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