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