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