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