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