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