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