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