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