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