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