1 #define PETSCKSP_DLL 2 3 /* 4 This provides a simple shell for Fortran (and C programmers) to 5 create their own preconditioner without writing much interface code. 6 */ 7 8 #include "private/pcimpl.h" /*I "petscpc.h" I*/ 9 #include "private/vecimpl.h" 10 11 EXTERN_C_BEGIN 12 typedef struct { 13 void *ctx; /* user provided contexts for preconditioner */ 14 PetscErrorCode (*destroy)(void*); 15 PetscErrorCode (*setup)(void*); 16 PetscErrorCode (*apply)(void*,Vec,Vec); 17 PetscErrorCode (*applyBA)(void*,PCSide,Vec,Vec,Vec); 18 PetscErrorCode (*presolve)(void*,KSP,Vec,Vec); 19 PetscErrorCode (*postsolve)(void*,KSP,Vec,Vec); 20 PetscErrorCode (*view)(void*,PetscViewer); 21 PetscErrorCode (*applytranspose)(void*,Vec,Vec); 22 PetscErrorCode (*applyrich)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt); 23 char *name; 24 } PC_Shell; 25 EXTERN_C_END 26 27 #undef __FUNCT__ 28 #define __FUNCT__ "PCShellGetContext" 29 /*@ 30 PCShellGetContext - Returns the user-provided context associated with a shell PC 31 32 Not Collective 33 34 Input Parameter: 35 . pc - should have been created with PCCreateShell() 36 37 Output Parameter: 38 . ctx - the user provided context 39 40 Level: advanced 41 42 Notes: 43 This routine is intended for use within various shell routines 44 45 .keywords: PC, shell, get, context 46 47 .seealso: PCCreateShell(), PCShellSetContext() 48 @*/ 49 PetscErrorCode PETSCKSP_DLLEXPORT PCShellGetContext(PC pc,void **ctx) 50 { 51 PetscErrorCode ierr; 52 PetscTruth flg; 53 54 PetscFunctionBegin; 55 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 56 PetscValidPointer(ctx,2); 57 ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);CHKERRQ(ierr); 58 if (!flg) *ctx = 0; 59 else *ctx = ((PC_Shell*)(pc->data))->ctx; 60 PetscFunctionReturn(0); 61 } 62 63 #undef __FUNCT__ 64 #define __FUNCT__ "PCShellSetContext" 65 /*@C 66 PCShellSetContext - sets the context for a shell PC 67 68 Collective on PC 69 70 Input Parameters: 71 + pc - the shell PC 72 - ctx - the context 73 74 Level: advanced 75 76 Fortran Notes: The context can only be an integer or a PetscObject 77 unfortunately it cannot be a Fortran array or derived type. 78 79 .seealso: PCCreateShell(), PCShellGetContext() 80 @*/ 81 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetContext(PC pc,void *ctx) 82 { 83 PC_Shell *shell = (PC_Shell*)pc->data; 84 PetscErrorCode ierr; 85 PetscTruth flg; 86 87 PetscFunctionBegin; 88 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 89 ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);CHKERRQ(ierr); 90 if (flg) { 91 shell->ctx = ctx; 92 } 93 PetscFunctionReturn(0); 94 } 95 96 #undef __FUNCT__ 97 #define __FUNCT__ "PCSetUp_Shell" 98 static PetscErrorCode PCSetUp_Shell(PC pc) 99 { 100 PC_Shell *shell; 101 PetscErrorCode ierr; 102 103 PetscFunctionBegin; 104 shell = (PC_Shell*)pc->data; 105 if (shell->setup) { 106 CHKMEMQ; 107 ierr = (*shell->setup)(shell->ctx);CHKERRQ(ierr); 108 CHKMEMQ; 109 } 110 PetscFunctionReturn(0); 111 } 112 113 #undef __FUNCT__ 114 #define __FUNCT__ "PCApply_Shell" 115 static PetscErrorCode PCApply_Shell(PC pc,Vec x,Vec y) 116 { 117 PC_Shell *shell; 118 PetscErrorCode ierr; 119 120 PetscFunctionBegin; 121 shell = (PC_Shell*)pc->data; 122 if (!shell->apply) SETERRQ(PETSC_ERR_USER,"No apply() routine provided to Shell PC"); 123 PetscStackPush("PCSHELL user function"); 124 CHKMEMQ; 125 ierr = (*shell->apply)(shell->ctx,x,y);CHKERRQ(ierr); 126 CHKMEMQ; 127 PetscStackPop; 128 PetscFunctionReturn(0); 129 } 130 131 #undef __FUNCT__ 132 #define __FUNCT__ "PCApplyBA_Shell" 133 static PetscErrorCode PCApplyBA_Shell(PC pc,PCSide side,Vec x,Vec y,Vec w) 134 { 135 PC_Shell *shell; 136 PetscErrorCode ierr; 137 138 PetscFunctionBegin; 139 shell = (PC_Shell*)pc->data; 140 if (!shell->applyBA) SETERRQ(PETSC_ERR_USER,"No applyBA() routine provided to Shell PC"); 141 PetscStackPush("PCSHELL user function BA"); 142 CHKMEMQ; 143 ierr = (*shell->applyBA)(shell->ctx,side,x,y,w);CHKERRQ(ierr); 144 CHKMEMQ; 145 PetscStackPop; 146 PetscFunctionReturn(0); 147 } 148 149 #undef __FUNCT__ 150 #define __FUNCT__ "PCPreSolve_Shell" 151 static PetscErrorCode PCPreSolve_Shell(PC pc,KSP ksp,Vec b,Vec x) 152 { 153 PC_Shell *shell; 154 PetscErrorCode ierr; 155 156 PetscFunctionBegin; 157 shell = (PC_Shell*)pc->data; 158 if (!shell->presolve) SETERRQ(PETSC_ERR_USER,"No presolve() routine provided to Shell PC"); 159 ierr = (*shell->presolve)(shell->ctx,ksp,b,x);CHKERRQ(ierr); 160 PetscFunctionReturn(0); 161 } 162 163 #undef __FUNCT__ 164 #define __FUNCT__ "PCPostSolve_Shell" 165 static PetscErrorCode PCPostSolve_Shell(PC pc,KSP ksp,Vec b,Vec x) 166 { 167 PC_Shell *shell; 168 PetscErrorCode ierr; 169 170 PetscFunctionBegin; 171 shell = (PC_Shell*)pc->data; 172 if (!shell->postsolve) SETERRQ(PETSC_ERR_USER,"No postsolve() routine provided to Shell PC"); 173 ierr = (*shell->postsolve)(shell->ctx,ksp,b,x);CHKERRQ(ierr); 174 PetscFunctionReturn(0); 175 } 176 177 #undef __FUNCT__ 178 #define __FUNCT__ "PCApplyTranspose_Shell" 179 static PetscErrorCode PCApplyTranspose_Shell(PC pc,Vec x,Vec y) 180 { 181 PC_Shell *shell; 182 PetscErrorCode ierr; 183 184 PetscFunctionBegin; 185 shell = (PC_Shell*)pc->data; 186 if (!shell->applytranspose) SETERRQ(PETSC_ERR_USER,"No applytranspose() routine provided to Shell PC"); 187 ierr = (*shell->applytranspose)(shell->ctx,x,y);CHKERRQ(ierr); 188 PetscFunctionReturn(0); 189 } 190 191 #undef __FUNCT__ 192 #define __FUNCT__ "PCApplyRichardson_Shell" 193 static PetscErrorCode PCApplyRichardson_Shell(PC pc,Vec x,Vec y,Vec w,PetscReal rtol,PetscReal abstol, PetscReal dtol,PetscInt it) 194 { 195 PetscErrorCode ierr; 196 PC_Shell *shell; 197 198 PetscFunctionBegin; 199 shell = (PC_Shell*)pc->data; 200 ierr = (*shell->applyrich)(shell->ctx,x,y,w,rtol,abstol,dtol,it);CHKERRQ(ierr); 201 PetscFunctionReturn(0); 202 } 203 204 #undef __FUNCT__ 205 #define __FUNCT__ "PCDestroy_Shell" 206 static PetscErrorCode PCDestroy_Shell(PC pc) 207 { 208 PC_Shell *shell = (PC_Shell*)pc->data; 209 PetscErrorCode ierr; 210 211 PetscFunctionBegin; 212 ierr = PetscStrfree(shell->name);CHKERRQ(ierr); 213 if (shell->destroy) { 214 ierr = (*shell->destroy)(shell->ctx);CHKERRQ(ierr); 215 } 216 ierr = PetscFree(shell);CHKERRQ(ierr); 217 PetscFunctionReturn(0); 218 } 219 220 #undef __FUNCT__ 221 #define __FUNCT__ "PCView_Shell" 222 static PetscErrorCode PCView_Shell(PC pc,PetscViewer viewer) 223 { 224 PC_Shell *shell = (PC_Shell*)pc->data; 225 PetscErrorCode ierr; 226 PetscTruth iascii; 227 228 PetscFunctionBegin; 229 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 230 if (iascii) { 231 if (shell->name) {ierr = PetscViewerASCIIPrintf(viewer," Shell: %s\n",shell->name);CHKERRQ(ierr);} 232 else {ierr = PetscViewerASCIIPrintf(viewer," Shell: no name\n");CHKERRQ(ierr);} 233 } 234 if (shell->view) { 235 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 236 ierr = (*shell->view)(shell->ctx,viewer);CHKERRQ(ierr); 237 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 238 } 239 PetscFunctionReturn(0); 240 } 241 242 /* ------------------------------------------------------------------------------*/ 243 EXTERN_C_BEGIN 244 #undef __FUNCT__ 245 #define __FUNCT__ "PCShellSetDestroy_Shell" 246 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetDestroy_Shell(PC pc, PetscErrorCode (*destroy)(void*)) 247 { 248 PC_Shell *shell; 249 250 PetscFunctionBegin; 251 shell = (PC_Shell*)pc->data; 252 shell->destroy = destroy; 253 PetscFunctionReturn(0); 254 } 255 EXTERN_C_END 256 257 EXTERN_C_BEGIN 258 #undef __FUNCT__ 259 #define __FUNCT__ "PCShellSetSetUp_Shell" 260 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetSetUp_Shell(PC pc, PetscErrorCode (*setup)(void*)) 261 { 262 PC_Shell *shell; 263 264 PetscFunctionBegin; 265 shell = (PC_Shell*)pc->data; 266 shell->setup = setup; 267 PetscFunctionReturn(0); 268 } 269 EXTERN_C_END 270 271 EXTERN_C_BEGIN 272 #undef __FUNCT__ 273 #define __FUNCT__ "PCShellSetApply_Shell" 274 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApply_Shell(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec)) 275 { 276 PC_Shell *shell; 277 278 PetscFunctionBegin; 279 shell = (PC_Shell*)pc->data; 280 shell->apply = apply; 281 PetscFunctionReturn(0); 282 } 283 EXTERN_C_END 284 285 EXTERN_C_BEGIN 286 #undef __FUNCT__ 287 #define __FUNCT__ "PCShellSetApplyBA_Shell" 288 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyBA_Shell(PC pc,PetscErrorCode (*apply)(void*,PCSide,Vec,Vec,Vec)) 289 { 290 PC_Shell *shell; 291 292 PetscFunctionBegin; 293 shell = (PC_Shell*)pc->data; 294 if (apply) pc->ops->applyBA = PCApplyBA_Shell; 295 else pc->ops->applyBA = 0; 296 shell->applyBA = apply; 297 PetscFunctionReturn(0); 298 } 299 EXTERN_C_END 300 301 EXTERN_C_BEGIN 302 #undef __FUNCT__ 303 #define __FUNCT__ "PCShellSetPreSolve_Shell" 304 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPreSolve_Shell(PC pc,PetscErrorCode (*presolve)(void*,KSP,Vec,Vec)) 305 { 306 PC_Shell *shell; 307 308 PetscFunctionBegin; 309 shell = (PC_Shell*)pc->data; 310 shell->presolve = presolve; 311 if (presolve) { 312 pc->ops->presolve = PCPreSolve_Shell; 313 } else { 314 pc->ops->presolve = 0; 315 } 316 PetscFunctionReturn(0); 317 } 318 EXTERN_C_END 319 320 EXTERN_C_BEGIN 321 #undef __FUNCT__ 322 #define __FUNCT__ "PCShellSetPostSolve_Shell" 323 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPostSolve_Shell(PC pc,PetscErrorCode (*postsolve)(void*,KSP,Vec,Vec)) 324 { 325 PC_Shell *shell; 326 327 PetscFunctionBegin; 328 shell = (PC_Shell*)pc->data; 329 shell->postsolve = postsolve; 330 if (postsolve) { 331 pc->ops->postsolve = PCPostSolve_Shell; 332 } else { 333 pc->ops->postsolve = 0; 334 } 335 PetscFunctionReturn(0); 336 } 337 EXTERN_C_END 338 339 EXTERN_C_BEGIN 340 #undef __FUNCT__ 341 #define __FUNCT__ "PCShellSetView_Shell" 342 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetView_Shell(PC pc,PetscErrorCode (*view)(void*,PetscViewer)) 343 { 344 PC_Shell *shell; 345 346 PetscFunctionBegin; 347 shell = (PC_Shell*)pc->data; 348 shell->view = view; 349 PetscFunctionReturn(0); 350 } 351 EXTERN_C_END 352 353 EXTERN_C_BEGIN 354 #undef __FUNCT__ 355 #define __FUNCT__ "PCShellSetApplyTranspose_Shell" 356 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyTranspose_Shell(PC pc,PetscErrorCode (*applytranspose)(void*,Vec,Vec)) 357 { 358 PC_Shell *shell; 359 360 PetscFunctionBegin; 361 shell = (PC_Shell*)pc->data; 362 shell->applytranspose = applytranspose; 363 PetscFunctionReturn(0); 364 } 365 EXTERN_C_END 366 367 EXTERN_C_BEGIN 368 #undef __FUNCT__ 369 #define __FUNCT__ "PCShellSetName_Shell" 370 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetName_Shell(PC pc,const char name[]) 371 { 372 PC_Shell *shell; 373 PetscErrorCode ierr; 374 375 PetscFunctionBegin; 376 shell = (PC_Shell*)pc->data; 377 ierr = PetscStrfree(shell->name);CHKERRQ(ierr); 378 ierr = PetscStrallocpy(name,&shell->name);CHKERRQ(ierr); 379 PetscFunctionReturn(0); 380 } 381 EXTERN_C_END 382 383 EXTERN_C_BEGIN 384 #undef __FUNCT__ 385 #define __FUNCT__ "PCShellGetName_Shell" 386 PetscErrorCode PETSCKSP_DLLEXPORT PCShellGetName_Shell(PC pc,char *name[]) 387 { 388 PC_Shell *shell; 389 390 PetscFunctionBegin; 391 shell = (PC_Shell*)pc->data; 392 *name = shell->name; 393 PetscFunctionReturn(0); 394 } 395 EXTERN_C_END 396 397 EXTERN_C_BEGIN 398 #undef __FUNCT__ 399 #define __FUNCT__ "PCShellSetApplyRichardson_Shell" 400 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyRichardson_Shell(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt)) 401 { 402 PC_Shell *shell; 403 404 PetscFunctionBegin; 405 shell = (PC_Shell*)pc->data; 406 pc->ops->applyrichardson = PCApplyRichardson_Shell; 407 shell->applyrich = apply; 408 PetscFunctionReturn(0); 409 } 410 EXTERN_C_END 411 412 /* -------------------------------------------------------------------------------*/ 413 414 #undef __FUNCT__ 415 #define __FUNCT__ "PCShellSetDestroy" 416 /*@C 417 PCShellSetDestroy - Sets routine to use to destroy the user-provided 418 application context. 419 420 Collective on PC 421 422 Input Parameters: 423 + pc - the preconditioner context 424 . destroy - the application-provided destroy routine 425 426 Calling sequence of destroy: 427 .vb 428 PetscErrorCode destroy (void *ptr) 429 .ve 430 431 . ptr - the application context 432 433 Level: developer 434 435 .keywords: PC, shell, set, destroy, user-provided 436 437 .seealso: PCShellSetApply(), PCShellSetContext() 438 @*/ 439 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetDestroy(PC pc,PetscErrorCode (*destroy)(void*)) 440 { 441 PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*)); 442 443 PetscFunctionBegin; 444 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 445 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetDestroy_C",(void (**)(void))&f);CHKERRQ(ierr); 446 if (f) { 447 ierr = (*f)(pc,destroy);CHKERRQ(ierr); 448 } 449 PetscFunctionReturn(0); 450 } 451 452 453 #undef __FUNCT__ 454 #define __FUNCT__ "PCShellSetSetUp" 455 /*@C 456 PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the 457 matrix operator is changed. 458 459 Collective on PC 460 461 Input Parameters: 462 + pc - the preconditioner context 463 . setup - the application-provided setup routine 464 465 Calling sequence of setup: 466 .vb 467 PetscErrorCode setup (void *ptr) 468 .ve 469 470 . ptr - the application context 471 472 Level: developer 473 474 .keywords: PC, shell, set, setup, user-provided 475 476 .seealso: PCShellSetApplyRichardson(), PCShellSetApply(), PCShellSetContext() 477 @*/ 478 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetSetUp(PC pc,PetscErrorCode (*setup)(void*)) 479 { 480 PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*)); 481 482 PetscFunctionBegin; 483 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 484 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetSetUp_C",(void (**)(void))&f);CHKERRQ(ierr); 485 if (f) { 486 ierr = (*f)(pc,setup);CHKERRQ(ierr); 487 } 488 PetscFunctionReturn(0); 489 } 490 491 492 #undef __FUNCT__ 493 #define __FUNCT__ "PCShellSetView" 494 /*@C 495 PCShellSetView - Sets routine to use as viewer of shell preconditioner 496 497 Collective on PC 498 499 Input Parameters: 500 + pc - the preconditioner context 501 - view - the application-provided view routine 502 503 Calling sequence of apply: 504 .vb 505 PetscErrorCode view(void *ptr,PetscViewer v) 506 .ve 507 508 + ptr - the application context 509 - v - viewer 510 511 Level: developer 512 513 .keywords: PC, shell, set, apply, user-provided 514 515 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose() 516 @*/ 517 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetView(PC pc,PetscErrorCode (*view)(void*,PetscViewer)) 518 { 519 PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,PetscViewer)); 520 521 PetscFunctionBegin; 522 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 523 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetView_C",(void (**)(void))&f);CHKERRQ(ierr); 524 if (f) { 525 ierr = (*f)(pc,view);CHKERRQ(ierr); 526 } 527 PetscFunctionReturn(0); 528 } 529 530 #undef __FUNCT__ 531 #define __FUNCT__ "PCShellSetApply" 532 /*@C 533 PCShellSetApply - Sets routine to use as preconditioner. 534 535 Collective on PC 536 537 Input Parameters: 538 + pc - the preconditioner context 539 - apply - the application-provided preconditioning routine 540 541 Calling sequence of apply: 542 .vb 543 PetscErrorCode apply (void *ptr,Vec xin,Vec xout) 544 .ve 545 546 + ptr - the application context 547 . xin - input vector 548 - xout - output vector 549 550 Level: developer 551 552 .keywords: PC, shell, set, apply, user-provided 553 554 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApplyBA() 555 @*/ 556 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApply(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec)) 557 { 558 PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec)); 559 560 PetscFunctionBegin; 561 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 562 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApply_C",(void (**)(void))&f);CHKERRQ(ierr); 563 if (f) { 564 ierr = (*f)(pc,apply);CHKERRQ(ierr); 565 } 566 PetscFunctionReturn(0); 567 } 568 569 #undef __FUNCT__ 570 #define __FUNCT__ "PCShellSetApplyBA" 571 /*@C 572 PCShellSetApplyBA - Sets routine to use as preconditioner times operator. 573 574 Collective on PC 575 576 Input Parameters: 577 + pc - the preconditioner context 578 - applyBA - the application-provided BA routine 579 580 Calling sequence of apply: 581 .vb 582 PetscErrorCode applyBA (void *ptr,Vec xin,Vec xout) 583 .ve 584 585 + ptr - the application context 586 . xin - input vector 587 - xout - output vector 588 589 Level: developer 590 591 .keywords: PC, shell, set, apply, user-provided 592 593 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApply() 594 @*/ 595 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyBA(PC pc,PetscErrorCode (*applyBA)(void*,PCSide,Vec,Vec,Vec)) 596 { 597 PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,PCSide,Vec,Vec,Vec)); 598 599 PetscFunctionBegin; 600 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 601 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyBA_C",(void (**)(void))&f);CHKERRQ(ierr); 602 if (f) { 603 ierr = (*f)(pc,applyBA);CHKERRQ(ierr); 604 } 605 PetscFunctionReturn(0); 606 } 607 608 #undef __FUNCT__ 609 #define __FUNCT__ "PCShellSetApplyTranspose" 610 /*@C 611 PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose. 612 613 Collective on PC 614 615 Input Parameters: 616 + pc - the preconditioner context 617 - apply - the application-provided preconditioning transpose routine 618 619 Calling sequence of apply: 620 .vb 621 PetscErrorCode applytranspose (void *ptr,Vec xin,Vec xout) 622 .ve 623 624 + ptr - the application context 625 . xin - input vector 626 - xout - output vector 627 628 Level: developer 629 630 Notes: 631 Uses the same context variable as PCShellSetApply(). 632 633 .keywords: PC, shell, set, apply, user-provided 634 635 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApply(), PCSetContext(), PCShellSetApplyBA() 636 @*/ 637 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyTranspose(PC pc,PetscErrorCode (*applytranspose)(void*,Vec,Vec)) 638 { 639 PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec)); 640 641 PetscFunctionBegin; 642 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 643 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyTranspose_C",(void (**)(void))&f);CHKERRQ(ierr); 644 if (f) { 645 ierr = (*f)(pc,applytranspose);CHKERRQ(ierr); 646 } 647 PetscFunctionReturn(0); 648 } 649 650 #undef __FUNCT__ 651 #define __FUNCT__ "PCShellSetPreSolve" 652 /*@C 653 PCShellSetPreSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is 654 applied. This usually does something like scale the linear system in some application 655 specific way. 656 657 Collective on PC 658 659 Input Parameters: 660 + pc - the preconditioner context 661 - presolve - the application-provided presolve routine 662 663 Calling sequence of presolve: 664 .vb 665 PetscErrorCode presolve (void *ptr,KSP ksp,Vec b,Vec x) 666 .ve 667 668 + ptr - the application context 669 . xin - input vector 670 - xout - output vector 671 672 Level: developer 673 674 .keywords: PC, shell, set, apply, user-provided 675 676 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPostSolve(), PCShellSetContext() 677 @*/ 678 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPreSolve(PC pc,PetscErrorCode (*presolve)(void*,KSP,Vec,Vec)) 679 { 680 PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,KSP,Vec,Vec)); 681 682 PetscFunctionBegin; 683 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 684 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPreSolve_C",(void (**)(void))&f);CHKERRQ(ierr); 685 if (f) { 686 ierr = (*f)(pc,presolve);CHKERRQ(ierr); 687 } 688 PetscFunctionReturn(0); 689 } 690 691 #undef __FUNCT__ 692 #define __FUNCT__ "PCShellSetPostSolve" 693 /*@C 694 PCShellSetPostSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is 695 applied. This usually does something like scale the linear system in some application 696 specific way. 697 698 Collective on PC 699 700 Input Parameters: 701 + pc - the preconditioner context 702 - postsolve - the application-provided presolve routine 703 704 Calling sequence of postsolve: 705 .vb 706 PetscErrorCode postsolve(void *ptr,KSP ksp,Vec b,Vec x) 707 .ve 708 709 + ptr - the application context 710 . xin - input vector 711 - xout - output vector 712 713 Level: developer 714 715 .keywords: PC, shell, set, apply, user-provided 716 717 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPreSolve(), PCShellSetContext() 718 @*/ 719 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPostSolve(PC pc,PetscErrorCode (*postsolve)(void*,KSP,Vec,Vec)) 720 { 721 PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,KSP,Vec,Vec)); 722 723 PetscFunctionBegin; 724 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 725 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPostSolve_C",(void (**)(void))&f);CHKERRQ(ierr); 726 if (f) { 727 ierr = (*f)(pc,postsolve);CHKERRQ(ierr); 728 } 729 PetscFunctionReturn(0); 730 } 731 732 #undef __FUNCT__ 733 #define __FUNCT__ "PCShellSetName" 734 /*@C 735 PCShellSetName - Sets an optional name to associate with a shell 736 preconditioner. 737 738 Not Collective 739 740 Input Parameters: 741 + pc - the preconditioner context 742 - name - character string describing shell preconditioner 743 744 Level: developer 745 746 .keywords: PC, shell, set, name, user-provided 747 748 .seealso: PCShellGetName() 749 @*/ 750 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetName(PC pc,const char name[]) 751 { 752 PetscErrorCode ierr,(*f)(PC,const char []); 753 754 PetscFunctionBegin; 755 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 756 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetName_C",(void (**)(void))&f);CHKERRQ(ierr); 757 if (f) { 758 ierr = (*f)(pc,name);CHKERRQ(ierr); 759 } 760 PetscFunctionReturn(0); 761 } 762 763 #undef __FUNCT__ 764 #define __FUNCT__ "PCShellGetName" 765 /*@C 766 PCShellGetName - Gets an optional name that the user has set for a shell 767 preconditioner. 768 769 Not Collective 770 771 Input Parameter: 772 . pc - the preconditioner context 773 774 Output Parameter: 775 . name - character string describing shell preconditioner (you should not free this) 776 777 Level: developer 778 779 .keywords: PC, shell, get, name, user-provided 780 781 .seealso: PCShellSetName() 782 @*/ 783 PetscErrorCode PETSCKSP_DLLEXPORT PCShellGetName(PC pc,char *name[]) 784 { 785 PetscErrorCode ierr,(*f)(PC,char *[]); 786 787 PetscFunctionBegin; 788 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 789 PetscValidPointer(name,2); 790 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellGetName_C",(void (**)(void))&f);CHKERRQ(ierr); 791 if (f) { 792 ierr = (*f)(pc,name);CHKERRQ(ierr); 793 } else { 794 SETERRQ(PETSC_ERR_ARG_WRONG,"Not shell preconditioner, cannot get name"); 795 } 796 PetscFunctionReturn(0); 797 } 798 799 #undef __FUNCT__ 800 #define __FUNCT__ "PCShellSetApplyRichardson" 801 /*@C 802 PCShellSetApplyRichardson - Sets routine to use as preconditioner 803 in Richardson iteration. 804 805 Collective on PC 806 807 Input Parameters: 808 + pc - the preconditioner context 809 - apply - the application-provided preconditioning routine 810 811 Calling sequence of apply: 812 .vb 813 PetscErrorCode apply (void *ptr,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt maxits) 814 .ve 815 816 + ptr - the application context 817 . b - right-hand-side 818 . x - current iterate 819 . r - work space 820 . rtol - relative tolerance of residual norm to stop at 821 . abstol - absolute tolerance of residual norm to stop at 822 . dtol - if residual norm increases by this factor than return 823 - maxits - number of iterations to run 824 825 Level: developer 826 827 .keywords: PC, shell, set, apply, Richardson, user-provided 828 829 .seealso: PCShellSetApply(), PCShellSetContext() 830 @*/ 831 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyRichardson(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt)) 832 { 833 PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt)); 834 835 PetscFunctionBegin; 836 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 837 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyRichardson_C",(void (**)(void))&f);CHKERRQ(ierr); 838 if (f) { 839 ierr = (*f)(pc,apply);CHKERRQ(ierr); 840 } 841 PetscFunctionReturn(0); 842 } 843 844 /*MC 845 PCSHELL - Creates a new preconditioner class for use with your 846 own private data storage format. 847 848 Level: advanced 849 850 Concepts: providing your own preconditioner 851 852 Usage: 853 $ PetscErrorCode (*mult)(void*,Vec,Vec); 854 $ PetscErrorCode (*setup)(void*); 855 $ PCCreate(comm,&pc); 856 $ PCSetType(pc,PCSHELL); 857 $ PCShellSetApply(pc,mult); 858 $ PCShellSetApplyBA(pc,mult); (optional) 859 $ PCShellSetApplyTranspose(pc,mult); (optional) 860 $ PCShellSetContext(pc,ctx) 861 $ PCShellSetSetUp(pc,setup); (optional) 862 863 .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 864 MATSHELL, PCShellSetSetUp(), PCShellSetApply(), PCShellSetView(), 865 PCShellSetApplyTranspose(), PCShellSetName(), PCShellSetApplyRichardson(), 866 PCShellGetName(), PCShellSetContext(), PCShellGetContext(), PCShellSetApplyBA() 867 M*/ 868 869 EXTERN_C_BEGIN 870 #undef __FUNCT__ 871 #define __FUNCT__ "PCCreate_Shell" 872 PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_Shell(PC pc) 873 { 874 PetscErrorCode ierr; 875 PC_Shell *shell; 876 877 PetscFunctionBegin; 878 pc->ops->destroy = PCDestroy_Shell; 879 ierr = PetscNew(PC_Shell,&shell);CHKERRQ(ierr); 880 ierr = PetscLogObjectMemory(pc,sizeof(PC_Shell));CHKERRQ(ierr); 881 pc->data = (void*)shell; 882 pc->name = 0; 883 884 pc->ops->apply = PCApply_Shell; 885 pc->ops->view = PCView_Shell; 886 pc->ops->applytranspose = PCApplyTranspose_Shell; 887 pc->ops->applyrichardson = 0; 888 pc->ops->setup = PCSetUp_Shell; 889 pc->ops->presolve = 0; 890 pc->ops->postsolve = 0; 891 pc->ops->view = PCView_Shell; 892 893 shell->apply = 0; 894 shell->applytranspose = 0; 895 shell->name = 0; 896 shell->applyrich = 0; 897 shell->presolve = 0; 898 shell->postsolve = 0; 899 shell->ctx = 0; 900 shell->setup = 0; 901 shell->view = 0; 902 shell->destroy = 0; 903 904 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetDestroy_C","PCShellSetDestroy_Shell", 905 PCShellSetDestroy_Shell);CHKERRQ(ierr); 906 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetSetUp_C","PCShellSetSetUp_Shell", 907 PCShellSetSetUp_Shell);CHKERRQ(ierr); 908 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApply_C","PCShellSetApply_Shell", 909 PCShellSetApply_Shell);CHKERRQ(ierr); 910 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyBA_C","PCShellSetApplyBA_Shell", 911 PCShellSetApplyBA_Shell);CHKERRQ(ierr); 912 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPreSolve_C","PCShellSetPreSolve_Shell", 913 PCShellSetPreSolve_Shell);CHKERRQ(ierr); 914 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPostSolve_C","PCShellSetPostSolve_Shell", 915 PCShellSetPostSolve_Shell);CHKERRQ(ierr); 916 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetView_C","PCShellSetView_Shell", 917 PCShellSetView_Shell);CHKERRQ(ierr); 918 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyTranspose_C","PCShellSetApplyTranspose_Shell", 919 PCShellSetApplyTranspose_Shell);CHKERRQ(ierr); 920 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetName_C","PCShellSetName_Shell", 921 PCShellSetName_Shell);CHKERRQ(ierr); 922 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellGetName_C","PCShellGetName_Shell", 923 PCShellGetName_Shell);CHKERRQ(ierr); 924 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyRichardson_C","PCShellSetApplyRichardson_Shell", 925 PCShellSetApplyRichardson_Shell);CHKERRQ(ierr); 926 PetscFunctionReturn(0); 927 } 928 EXTERN_C_END 929 930 931 932 933 934 935