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