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