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