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