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