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