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