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