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