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,(*f)(PC,PetscErrorCode (*)(PC)); 436 437 PetscFunctionBegin; 438 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 439 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetDestroy_C",(void (**)(void))&f);CHKERRQ(ierr); 440 if (f) { 441 ierr = (*f)(pc,destroy);CHKERRQ(ierr); 442 } 443 PetscFunctionReturn(0); 444 } 445 446 447 #undef __FUNCT__ 448 #define __FUNCT__ "PCShellSetSetUp" 449 /*@C 450 PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the 451 matrix operator is changed. 452 453 Logically Collective on PC 454 455 Input Parameters: 456 + pc - the preconditioner context 457 . setup - the application-provided setup routine 458 459 Calling sequence of setup: 460 .vb 461 PetscErrorCode setup (PC pc) 462 .ve 463 464 . pc - the preconditioner, get the application context with PCShellGetContext() 465 466 Notes: the function MUST return an error code of 0 on success and nonzero on failure. 467 468 Level: developer 469 470 .keywords: PC, shell, set, setup, user-provided 471 472 .seealso: PCShellSetApplyRichardson(), PCShellSetApply(), PCShellSetContext() 473 @*/ 474 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetSetUp(PC pc,PetscErrorCode (*setup)(PC)) 475 { 476 PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(PC)); 477 478 PetscFunctionBegin; 479 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 480 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetSetUp_C",(void (**)(void))&f);CHKERRQ(ierr); 481 if (f) { 482 ierr = (*f)(pc,setup);CHKERRQ(ierr); 483 } 484 PetscFunctionReturn(0); 485 } 486 487 488 #undef __FUNCT__ 489 #define __FUNCT__ "PCShellSetView" 490 /*@C 491 PCShellSetView - Sets routine to use as viewer of shell preconditioner 492 493 Logically Collective on PC 494 495 Input Parameters: 496 + pc - the preconditioner context 497 - view - the application-provided view routine 498 499 Calling sequence of apply: 500 .vb 501 PetscErrorCode view(PC pc,PetscViewer v) 502 .ve 503 504 + pc - the preconditioner, get the application context with PCShellGetContext() 505 - v - viewer 506 507 Notes: the function MUST return an error code of 0 on success and nonzero on failure. 508 509 Level: developer 510 511 .keywords: PC, shell, set, apply, user-provided 512 513 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose() 514 @*/ 515 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetView(PC pc,PetscErrorCode (*view)(PC,PetscViewer)) 516 { 517 PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(PC,PetscViewer)); 518 519 PetscFunctionBegin; 520 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 521 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetView_C",(void (**)(void))&f);CHKERRQ(ierr); 522 if (f) { 523 ierr = (*f)(pc,view);CHKERRQ(ierr); 524 } 525 PetscFunctionReturn(0); 526 } 527 528 #undef __FUNCT__ 529 #define __FUNCT__ "PCShellSetApply" 530 /*@C 531 PCShellSetApply - Sets routine to use as preconditioner. 532 533 Logically Collective on PC 534 535 Input Parameters: 536 + pc - the preconditioner context 537 - apply - the application-provided preconditioning routine 538 539 Calling sequence of apply: 540 .vb 541 PetscErrorCode apply (PC pc,Vec xin,Vec xout) 542 .ve 543 544 + pc - the preconditioner, get the application context with PCShellGetContext() 545 . xin - input vector 546 - xout - output vector 547 548 Notes: the function MUST return an error code of 0 on success and nonzero on failure. 549 550 Level: developer 551 552 .keywords: PC, shell, set, apply, user-provided 553 554 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApplyBA() 555 @*/ 556 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApply(PC pc,PetscErrorCode (*apply)(PC,Vec,Vec)) 557 { 558 PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(PC,Vec,Vec)); 559 560 PetscFunctionBegin; 561 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 562 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApply_C",(void (**)(void))&f);CHKERRQ(ierr); 563 if (f) { 564 ierr = (*f)(pc,apply);CHKERRQ(ierr); 565 } 566 PetscFunctionReturn(0); 567 } 568 569 #undef __FUNCT__ 570 #define __FUNCT__ "PCShellSetApplyBA" 571 /*@C 572 PCShellSetApplyBA - Sets routine to use as preconditioner times operator. 573 574 Logically Collective on PC 575 576 Input Parameters: 577 + pc - the preconditioner context 578 - applyBA - the application-provided BA routine 579 580 Calling sequence of apply: 581 .vb 582 PetscErrorCode applyBA (PC pc,Vec xin,Vec xout) 583 .ve 584 585 + pc - the preconditioner, get the application context with PCShellGetContext() 586 . xin - input vector 587 - xout - output vector 588 589 Notes: the function MUST return an error code of 0 on success and nonzero on failure. 590 591 Level: developer 592 593 .keywords: PC, shell, set, apply, user-provided 594 595 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApply() 596 @*/ 597 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyBA(PC pc,PetscErrorCode (*applyBA)(PC,PCSide,Vec,Vec,Vec)) 598 { 599 PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(PC,PCSide,Vec,Vec,Vec)); 600 601 PetscFunctionBegin; 602 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 603 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyBA_C",(void (**)(void))&f);CHKERRQ(ierr); 604 if (f) { 605 ierr = (*f)(pc,applyBA);CHKERRQ(ierr); 606 } 607 PetscFunctionReturn(0); 608 } 609 610 #undef __FUNCT__ 611 #define __FUNCT__ "PCShellSetApplyTranspose" 612 /*@C 613 PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose. 614 615 Logically Collective on PC 616 617 Input Parameters: 618 + pc - the preconditioner context 619 - apply - the application-provided preconditioning transpose routine 620 621 Calling sequence of apply: 622 .vb 623 PetscErrorCode applytranspose (PC pc,Vec xin,Vec xout) 624 .ve 625 626 + pc - the preconditioner, get the application context with PCShellGetContext() 627 . xin - input vector 628 - xout - output vector 629 630 Notes: the function MUST return an error code of 0 on success and nonzero on failure. 631 632 Level: developer 633 634 Notes: 635 Uses the same context variable as PCShellSetApply(). 636 637 .keywords: PC, shell, set, apply, user-provided 638 639 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApply(), PCSetContext(), PCShellSetApplyBA() 640 @*/ 641 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyTranspose(PC pc,PetscErrorCode (*applytranspose)(PC,Vec,Vec)) 642 { 643 PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(PC,Vec,Vec)); 644 645 PetscFunctionBegin; 646 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 647 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyTranspose_C",(void (**)(void))&f);CHKERRQ(ierr); 648 if (f) { 649 ierr = (*f)(pc,applytranspose);CHKERRQ(ierr); 650 } 651 PetscFunctionReturn(0); 652 } 653 654 #undef __FUNCT__ 655 #define __FUNCT__ "PCShellSetPreSolve" 656 /*@C 657 PCShellSetPreSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is 658 applied. This usually does something like scale the linear system in some application 659 specific way. 660 661 Logically Collective on PC 662 663 Input Parameters: 664 + pc - the preconditioner context 665 - presolve - the application-provided presolve routine 666 667 Calling sequence of presolve: 668 .vb 669 PetscErrorCode presolve (PC,KSP ksp,Vec b,Vec x) 670 .ve 671 672 + pc - the preconditioner, get the application context with PCShellGetContext() 673 . xin - input vector 674 - xout - output vector 675 676 Notes: the function MUST return an error code of 0 on success and nonzero on failure. 677 678 Level: developer 679 680 .keywords: PC, shell, set, apply, user-provided 681 682 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPostSolve(), PCShellSetContext() 683 @*/ 684 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPreSolve(PC pc,PetscErrorCode (*presolve)(PC,KSP,Vec,Vec)) 685 { 686 PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(PC,KSP,Vec,Vec)); 687 688 PetscFunctionBegin; 689 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 690 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPreSolve_C",(void (**)(void))&f);CHKERRQ(ierr); 691 if (f) { 692 ierr = (*f)(pc,presolve);CHKERRQ(ierr); 693 } 694 PetscFunctionReturn(0); 695 } 696 697 #undef __FUNCT__ 698 #define __FUNCT__ "PCShellSetPostSolve" 699 /*@C 700 PCShellSetPostSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is 701 applied. This usually does something like scale the linear system in some application 702 specific way. 703 704 Logically Collective on PC 705 706 Input Parameters: 707 + pc - the preconditioner context 708 - postsolve - the application-provided presolve routine 709 710 Calling sequence of postsolve: 711 .vb 712 PetscErrorCode postsolve(PC,KSP ksp,Vec b,Vec x) 713 .ve 714 715 + pc - the preconditioner, get the application context with PCShellGetContext() 716 . xin - input vector 717 - xout - output vector 718 719 Notes: the function MUST return an error code of 0 on success and nonzero on failure. 720 721 Level: developer 722 723 .keywords: PC, shell, set, apply, user-provided 724 725 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPreSolve(), PCShellSetContext() 726 @*/ 727 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPostSolve(PC pc,PetscErrorCode (*postsolve)(PC,KSP,Vec,Vec)) 728 { 729 PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(PC,KSP,Vec,Vec)); 730 731 PetscFunctionBegin; 732 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 733 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPostSolve_C",(void (**)(void))&f);CHKERRQ(ierr); 734 if (f) { 735 ierr = (*f)(pc,postsolve);CHKERRQ(ierr); 736 } 737 PetscFunctionReturn(0); 738 } 739 740 #undef __FUNCT__ 741 #define __FUNCT__ "PCShellSetName" 742 /*@C 743 PCShellSetName - Sets an optional name to associate with a shell 744 preconditioner. 745 746 Not Collective 747 748 Input Parameters: 749 + pc - the preconditioner context 750 - name - character string describing shell preconditioner 751 752 Level: developer 753 754 .keywords: PC, shell, set, name, user-provided 755 756 .seealso: PCShellGetName() 757 @*/ 758 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetName(PC pc,const char name[]) 759 { 760 PetscErrorCode ierr,(*f)(PC,const char []); 761 762 PetscFunctionBegin; 763 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 764 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetName_C",(void (**)(void))&f);CHKERRQ(ierr); 765 if (f) { 766 ierr = (*f)(pc,name);CHKERRQ(ierr); 767 } 768 PetscFunctionReturn(0); 769 } 770 771 #undef __FUNCT__ 772 #define __FUNCT__ "PCShellGetName" 773 /*@C 774 PCShellGetName - Gets an optional name that the user has set for a shell 775 preconditioner. 776 777 Not Collective 778 779 Input Parameter: 780 . pc - the preconditioner context 781 782 Output Parameter: 783 . name - character string describing shell preconditioner (you should not free this) 784 785 Level: developer 786 787 .keywords: PC, shell, get, name, user-provided 788 789 .seealso: PCShellSetName() 790 @*/ 791 PetscErrorCode PETSCKSP_DLLEXPORT PCShellGetName(PC pc,char *name[]) 792 { 793 PetscErrorCode ierr,(*f)(PC,char *[]); 794 795 PetscFunctionBegin; 796 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 797 PetscValidPointer(name,2); 798 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellGetName_C",(void (**)(void))&f);CHKERRQ(ierr); 799 if (f) { 800 ierr = (*f)(pc,name);CHKERRQ(ierr); 801 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not shell preconditioner, cannot get name"); 802 PetscFunctionReturn(0); 803 } 804 805 #undef __FUNCT__ 806 #define __FUNCT__ "PCShellSetApplyRichardson" 807 /*@C 808 PCShellSetApplyRichardson - Sets routine to use as preconditioner 809 in Richardson iteration. 810 811 Logically Collective on PC 812 813 Input Parameters: 814 + pc - the preconditioner context 815 - apply - the application-provided preconditioning routine 816 817 Calling sequence of apply: 818 .vb 819 PetscErrorCode apply (PC pc,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt maxits) 820 .ve 821 822 + pc - the preconditioner, get the application context with PCShellGetContext() 823 . b - right-hand-side 824 . x - current iterate 825 . r - work space 826 . rtol - relative tolerance of residual norm to stop at 827 . abstol - absolute tolerance of residual norm to stop at 828 . dtol - if residual norm increases by this factor than return 829 - maxits - number of iterations to run 830 831 Notes: the function MUST return an error code of 0 on success and nonzero on failure. 832 833 Level: developer 834 835 .keywords: PC, shell, set, apply, Richardson, user-provided 836 837 .seealso: PCShellSetApply(), PCShellSetContext() 838 @*/ 839 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyRichardson(PC pc,PetscErrorCode (*apply)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt,PetscBool ,PetscInt*,PCRichardsonConvergedReason*)) 840 { 841 PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt,PetscBool ,PetscInt*,PCRichardsonConvergedReason*)); 842 843 PetscFunctionBegin; 844 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 845 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyRichardson_C",(void (**)(void))&f);CHKERRQ(ierr); 846 if (f) { 847 ierr = (*f)(pc,apply);CHKERRQ(ierr); 848 } 849 PetscFunctionReturn(0); 850 } 851 852 /*MC 853 PCSHELL - Creates a new preconditioner class for use with your 854 own private data storage format. 855 856 Level: advanced 857 > 858 Concepts: providing your own preconditioner 859 860 Usage: 861 $ extern PetscErrorCode apply(PC,Vec,Vec); 862 $ extern PetscErrorCode applyba(PC,PCSide,Vec,Vec,Vec); 863 $ extern PetscErrorCode applytranspose(PC,Vec,Vec); 864 $ extern PetscErrorCode setup(PC); 865 $ extern PetscErrorCode destroy(PC); 866 $ 867 $ PCCreate(comm,&pc); 868 $ PCSetType(pc,PCSHELL); 869 $ PCShellSetContext(pc,ctx) 870 $ PCShellSetApply(pc,apply); 871 $ PCShellSetApplyBA(pc,applyba); (optional) 872 $ PCShellSetApplyTranspose(pc,applytranspose); (optional) 873 $ PCShellSetSetUp(pc,setup); (optional) 874 $ PCShellSetDestroy(pc,destroy); (optional) 875 876 .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 877 MATSHELL, PCShellSetSetUp(), PCShellSetApply(), PCShellSetView(), 878 PCShellSetApplyTranspose(), PCShellSetName(), PCShellSetApplyRichardson(), 879 PCShellGetName(), PCShellSetContext(), PCShellGetContext(), PCShellSetApplyBA() 880 M*/ 881 882 EXTERN_C_BEGIN 883 #undef __FUNCT__ 884 #define __FUNCT__ "PCCreate_Shell" 885 PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_Shell(PC pc) 886 { 887 PetscErrorCode ierr; 888 PC_Shell *shell; 889 890 PetscFunctionBegin; 891 ierr = PetscNewLog(pc,PC_Shell,&shell);CHKERRQ(ierr); 892 pc->data = (void*)shell; 893 894 pc->ops->destroy = PCDestroy_Shell; 895 pc->ops->view = PCView_Shell; 896 pc->ops->apply = PCApply_Shell; 897 pc->ops->applytranspose = 0; 898 pc->ops->applyrichardson = 0; 899 pc->ops->setup = 0; 900 pc->ops->presolve = 0; 901 pc->ops->postsolve = 0; 902 903 shell->apply = 0; 904 shell->applytranspose = 0; 905 shell->name = 0; 906 shell->applyrich = 0; 907 shell->presolve = 0; 908 shell->postsolve = 0; 909 shell->ctx = 0; 910 shell->setup = 0; 911 shell->view = 0; 912 shell->destroy = 0; 913 914 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetDestroy_C","PCShellSetDestroy_Shell", 915 PCShellSetDestroy_Shell);CHKERRQ(ierr); 916 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetSetUp_C","PCShellSetSetUp_Shell", 917 PCShellSetSetUp_Shell);CHKERRQ(ierr); 918 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApply_C","PCShellSetApply_Shell", 919 PCShellSetApply_Shell);CHKERRQ(ierr); 920 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyBA_C","PCShellSetApplyBA_Shell", 921 PCShellSetApplyBA_Shell);CHKERRQ(ierr); 922 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPreSolve_C","PCShellSetPreSolve_Shell", 923 PCShellSetPreSolve_Shell);CHKERRQ(ierr); 924 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPostSolve_C","PCShellSetPostSolve_Shell", 925 PCShellSetPostSolve_Shell);CHKERRQ(ierr); 926 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetView_C","PCShellSetView_Shell", 927 PCShellSetView_Shell);CHKERRQ(ierr); 928 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyTranspose_C","PCShellSetApplyTranspose_Shell", 929 PCShellSetApplyTranspose_Shell);CHKERRQ(ierr); 930 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetName_C","PCShellSetName_Shell", 931 PCShellSetName_Shell);CHKERRQ(ierr); 932 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellGetName_C","PCShellGetName_Shell", 933 PCShellGetName_Shell);CHKERRQ(ierr); 934 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyRichardson_C","PCShellSetApplyRichardson_Shell", 935 PCShellSetApplyRichardson_Shell);CHKERRQ(ierr); 936 PetscFunctionReturn(0); 937 } 938 EXTERN_C_END 939 940 941 942 943 944 945