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