1 #define PETSCKSP_DLL 2 3 /* 4 The PC (preconditioner) interface routines, callable by users. 5 */ 6 #include "private/pcimpl.h" /*I "petscksp.h" I*/ 7 8 /* Logging support */ 9 PetscCookie PC_COOKIE = 0; 10 PetscEvent PC_SetUp = 0, PC_SetUpOnBlocks = 0, PC_Apply = 0, PC_ApplyCoarse = 0, PC_ApplyMultiple = 0, PC_ApplySymmetricLeft = 0; 11 PetscEvent PC_ApplySymmetricRight = 0, PC_ModifySubMatrices = 0; 12 13 #undef __FUNCT__ 14 #define __FUNCT__ "PCGetDefaultType_Private" 15 PetscErrorCode PCGetDefaultType_Private(PC pc,const char* type[]) 16 { 17 PetscErrorCode ierr; 18 PetscMPIInt size; 19 PetscTruth flg1,flg2,set,flg3; 20 21 PetscFunctionBegin; 22 ierr = MPI_Comm_size(pc->comm,&size);CHKERRQ(ierr); 23 if (pc->pmat) { 24 PetscErrorCode (*f)(Mat,PetscTruth*,MatReuse,Mat*); 25 ierr = PetscObjectQueryFunction((PetscObject)pc->pmat,"MatGetDiagonalBlock_C",(void (**)(void))&f);CHKERRQ(ierr); 26 if (size == 1) { 27 ierr = MatHasOperation(pc->pmat,MATOP_ICCFACTOR_SYMBOLIC,&flg1);CHKERRQ(ierr); 28 ierr = MatHasOperation(pc->pmat,MATOP_ILUFACTOR_SYMBOLIC,&flg2);CHKERRQ(ierr); 29 ierr = MatIsSymmetricKnown(pc->pmat,&set,&flg3);CHKERRQ(ierr); 30 if (flg1 && (!flg2 || (set && flg3))) { 31 *type = PCICC; 32 } else if (flg2) { 33 *type = PCILU; 34 } else if (f) { /* likely is a parallel matrix run on one processor */ 35 *type = PCBJACOBI; 36 } else { 37 *type = PCNONE; 38 } 39 } else { 40 if (f) { 41 *type = PCBJACOBI; 42 } else { 43 *type = PCNONE; 44 } 45 } 46 } else { 47 if (size == 1) { 48 *type = PCILU; 49 } else { 50 *type = PCBJACOBI; 51 } 52 } 53 PetscFunctionReturn(0); 54 } 55 56 #undef __FUNCT__ 57 #define __FUNCT__ "PCDestroy" 58 /*@ 59 PCDestroy - Destroys PC context that was created with PCCreate(). 60 61 Collective on PC 62 63 Input Parameter: 64 . pc - the preconditioner context 65 66 Level: developer 67 68 .keywords: PC, destroy 69 70 .seealso: PCCreate(), PCSetUp() 71 @*/ 72 PetscErrorCode PETSCKSP_DLLEXPORT PCDestroy(PC pc) 73 { 74 PetscErrorCode ierr; 75 76 PetscFunctionBegin; 77 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 78 if (--pc->refct > 0) PetscFunctionReturn(0); 79 80 /* if memory was published with AMS then destroy it */ 81 ierr = PetscObjectDepublish(pc);CHKERRQ(ierr); 82 83 if (pc->ops->destroy) {ierr = (*pc->ops->destroy)(pc);CHKERRQ(ierr);} 84 if (pc->diagonalscaleright) {ierr = VecDestroy(pc->diagonalscaleright);CHKERRQ(ierr);} 85 if (pc->diagonalscaleleft) {ierr = VecDestroy(pc->diagonalscaleleft);CHKERRQ(ierr);} 86 87 if (pc->pmat) {ierr = MatDestroy(pc->pmat);CHKERRQ(ierr);} 88 if (pc->mat) {ierr = MatDestroy(pc->mat);CHKERRQ(ierr);} 89 90 ierr = PetscHeaderDestroy(pc);CHKERRQ(ierr); 91 PetscFunctionReturn(0); 92 } 93 94 #undef __FUNCT__ 95 #define __FUNCT__ "PCDiagonalScale" 96 /*@C 97 PCDiagonalScale - Indicates if the preconditioner applies an additional left and right 98 scaling as needed by certain time-stepping codes. 99 100 Collective on PC 101 102 Input Parameter: 103 . pc - the preconditioner context 104 105 Output Parameter: 106 . flag - PETSC_TRUE if it applies the scaling 107 108 Level: developer 109 110 Notes: If this returns PETSC_TRUE then the system solved via the Krylov method is 111 $ D M A D^{-1} y = D M b for left preconditioning or 112 $ D A M D^{-1} z = D b for right preconditioning 113 114 .keywords: PC 115 116 .seealso: PCCreate(), PCSetUp(), PCDiagonalScaleLeft(), PCDiagonalScaleRight(), PCDiagonalScaleSet() 117 @*/ 118 PetscErrorCode PETSCKSP_DLLEXPORT PCDiagonalScale(PC pc,PetscTruth *flag) 119 { 120 PetscFunctionBegin; 121 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 122 PetscValidPointer(flag,2); 123 *flag = pc->diagonalscale; 124 PetscFunctionReturn(0); 125 } 126 127 #undef __FUNCT__ 128 #define __FUNCT__ "PCDiagonalScaleSet" 129 /*@ 130 PCDiagonalScaleSet - Indicates the left scaling to use to apply an additional left and right 131 scaling as needed by certain time-stepping codes. 132 133 Collective on PC 134 135 Input Parameters: 136 + pc - the preconditioner context 137 - s - scaling vector 138 139 Level: intermediate 140 141 Notes: The system solved via the Krylov method is 142 $ D M A D^{-1} y = D M b for left preconditioning or 143 $ D A M D^{-1} z = D b for right preconditioning 144 145 PCDiagonalScaleLeft() scales a vector by D. PCDiagonalScaleRight() scales a vector by D^{-1}. 146 147 .keywords: PC 148 149 .seealso: PCCreate(), PCSetUp(), PCDiagonalScaleLeft(), PCDiagonalScaleRight(), PCDiagonalScale() 150 @*/ 151 PetscErrorCode PETSCKSP_DLLEXPORT PCDiagonalScaleSet(PC pc,Vec s) 152 { 153 PetscErrorCode ierr; 154 155 PetscFunctionBegin; 156 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 157 PetscValidHeaderSpecific(s,VEC_COOKIE,2); 158 pc->diagonalscale = PETSC_TRUE; 159 if (pc->diagonalscaleleft) { 160 ierr = VecDestroy(pc->diagonalscaleleft);CHKERRQ(ierr); 161 } 162 pc->diagonalscaleleft = s; 163 ierr = PetscObjectReference((PetscObject)s);CHKERRQ(ierr); 164 if (!pc->diagonalscaleright) { 165 ierr = VecDuplicate(s,&pc->diagonalscaleright);CHKERRQ(ierr); 166 } 167 ierr = VecCopy(s,pc->diagonalscaleright);CHKERRQ(ierr); 168 ierr = VecReciprocal(pc->diagonalscaleright);CHKERRQ(ierr); 169 PetscFunctionReturn(0); 170 } 171 172 #undef __FUNCT__ 173 #define __FUNCT__ "PCDiagonalScaleLeft" 174 /*@C 175 PCDiagonalScaleLeft - Indicates the left scaling to use to apply an additional left and right 176 scaling as needed by certain time-stepping codes. 177 178 Collective on PC 179 180 Input Parameters: 181 + pc - the preconditioner context 182 . in - input vector 183 + out - scaled vector (maybe the same as in) 184 185 Level: intermediate 186 187 Notes: The system solved via the Krylov method is 188 $ D M A D^{-1} y = D M b for left preconditioning or 189 $ D A M D^{-1} z = D b for right preconditioning 190 191 PCDiagonalScaleLeft() scales a vector by D. PCDiagonalScaleRight() scales a vector by D^{-1}. 192 193 If diagonal scaling is turned off and in is not out then in is copied to out 194 195 .keywords: PC 196 197 .seealso: PCCreate(), PCSetUp(), PCDiagonalScaleSet(), PCDiagonalScaleRight(), PCDiagonalScale() 198 @*/ 199 PetscErrorCode PETSCKSP_DLLEXPORT PCDiagonalScaleLeft(PC pc,Vec in,Vec out) 200 { 201 PetscErrorCode ierr; 202 203 PetscFunctionBegin; 204 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 205 PetscValidHeaderSpecific(in,VEC_COOKIE,2); 206 PetscValidHeaderSpecific(out,VEC_COOKIE,3); 207 if (pc->diagonalscale) { 208 ierr = VecPointwiseMult(out,pc->diagonalscaleleft,in);CHKERRQ(ierr); 209 } else if (in != out) { 210 ierr = VecCopy(in,out);CHKERRQ(ierr); 211 } 212 PetscFunctionReturn(0); 213 } 214 215 #undef __FUNCT__ 216 #define __FUNCT__ "PCDiagonalScaleRight" 217 /*@C 218 PCDiagonalScaleRight - Scales a vector by the right scaling as needed by certain time-stepping codes. 219 220 Collective on PC 221 222 Input Parameters: 223 + pc - the preconditioner context 224 . in - input vector 225 + out - scaled vector (maybe the same as in) 226 227 Level: intermediate 228 229 Notes: The system solved via the Krylov method is 230 $ D M A D^{-1} y = D M b for left preconditioning or 231 $ D A M D^{-1} z = D b for right preconditioning 232 233 PCDiagonalScaleLeft() scales a vector by D. PCDiagonalScaleRight() scales a vector by D^{-1}. 234 235 If diagonal scaling is turned off and in is not out then in is copied to out 236 237 .keywords: PC 238 239 .seealso: PCCreate(), PCSetUp(), PCDiagonalScaleLeft(), PCDiagonalScaleSet(), PCDiagonalScale() 240 @*/ 241 PetscErrorCode PETSCKSP_DLLEXPORT PCDiagonalScaleRight(PC pc,Vec in,Vec out) 242 { 243 PetscErrorCode ierr; 244 245 PetscFunctionBegin; 246 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 247 PetscValidHeaderSpecific(in,VEC_COOKIE,2); 248 PetscValidHeaderSpecific(out,VEC_COOKIE,3); 249 if (pc->diagonalscale) { 250 ierr = VecPointwiseMult(out,pc->diagonalscaleright,in);CHKERRQ(ierr); 251 } else if (in != out) { 252 ierr = VecCopy(in,out);CHKERRQ(ierr); 253 } 254 PetscFunctionReturn(0); 255 } 256 257 #undef __FUNCT__ 258 #define __FUNCT__ "PCPublish_Petsc" 259 static PetscErrorCode PCPublish_Petsc(PetscObject obj) 260 { 261 PetscFunctionBegin; 262 PetscFunctionReturn(0); 263 } 264 265 #undef __FUNCT__ 266 #define __FUNCT__ "PCCreate" 267 /*@ 268 PCCreate - Creates a preconditioner context. 269 270 Collective on MPI_Comm 271 272 Input Parameter: 273 . comm - MPI communicator 274 275 Output Parameter: 276 . pc - location to put the preconditioner context 277 278 Notes: 279 The default preconditioner on one processor is PCILU with 0 fill on more 280 then one it is PCBJACOBI with ILU() on each processor. 281 282 Level: developer 283 284 .keywords: PC, create, context 285 286 .seealso: PCSetUp(), PCApply(), PCDestroy() 287 @*/ 288 PetscErrorCode PETSCKSP_DLLEXPORT PCCreate(MPI_Comm comm,PC *newpc) 289 { 290 PC pc; 291 PetscErrorCode ierr; 292 293 PetscFunctionBegin; 294 PetscValidPointer(newpc,1) 295 *newpc = 0; 296 #ifndef PETSC_USE_DYNAMIC_LIBRARIES 297 ierr = PCInitializePackage(PETSC_NULL);CHKERRQ(ierr); 298 #endif 299 300 ierr = PetscHeaderCreate(pc,_p_PC,struct _PCOps,PC_COOKIE,-1,"PC",comm,PCDestroy,PCView);CHKERRQ(ierr); 301 pc->bops->publish = PCPublish_Petsc; 302 pc->mat = 0; 303 pc->pmat = 0; 304 pc->setupcalled = 0; 305 pc->data = 0; 306 pc->diagonalscale = PETSC_FALSE; 307 pc->diagonalscaleleft = 0; 308 pc->diagonalscaleright = 0; 309 310 pc->ops->destroy = 0; 311 pc->ops->apply = 0; 312 pc->ops->applytranspose = 0; 313 pc->ops->applyBA = 0; 314 pc->ops->applyBAtranspose = 0; 315 pc->ops->applyrichardson = 0; 316 pc->ops->view = 0; 317 pc->ops->getfactoredmatrix = 0; 318 pc->ops->applysymmetricright = 0; 319 pc->ops->applysymmetricleft = 0; 320 pc->ops->setuponblocks = 0; 321 322 pc->modifysubmatrices = 0; 323 pc->modifysubmatricesP = 0; 324 *newpc = pc; 325 ierr = PetscPublishAll(pc);CHKERRQ(ierr); 326 PetscFunctionReturn(0); 327 328 } 329 330 /* -------------------------------------------------------------------------------*/ 331 332 #undef __FUNCT__ 333 #define __FUNCT__ "PCApply" 334 /*@ 335 PCApply - Applies the preconditioner to a vector. 336 337 Collective on PC and Vec 338 339 Input Parameters: 340 + pc - the preconditioner context 341 - x - input vector 342 343 Output Parameter: 344 . y - output vector 345 346 Level: developer 347 348 .keywords: PC, apply 349 350 .seealso: PCApplyTranspose(), PCApplyBAorAB() 351 @*/ 352 PetscErrorCode PETSCKSP_DLLEXPORT PCApply(PC pc,Vec x,Vec y) 353 { 354 PetscErrorCode ierr; 355 356 PetscFunctionBegin; 357 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 358 PetscValidHeaderSpecific(x,VEC_COOKIE,2); 359 PetscValidHeaderSpecific(y,VEC_COOKIE,3); 360 if (x == y) SETERRQ(PETSC_ERR_ARG_IDN,"x and y must be different vectors"); 361 362 if (pc->setupcalled < 2) { 363 ierr = PCSetUp(pc);CHKERRQ(ierr); 364 } 365 ierr = PetscLogEventBegin(PC_Apply,pc,x,y,0);CHKERRQ(ierr); 366 ierr = (*pc->ops->apply)(pc,x,y);CHKERRQ(ierr); 367 ierr = PetscLogEventEnd(PC_Apply,pc,x,y,0);CHKERRQ(ierr); 368 PetscFunctionReturn(0); 369 } 370 371 #undef __FUNCT__ 372 #define __FUNCT__ "PCApplySymmetricLeft" 373 /*@ 374 PCApplySymmetricLeft - Applies the left part of a symmetric preconditioner to a vector. 375 376 Collective on PC and Vec 377 378 Input Parameters: 379 + pc - the preconditioner context 380 - x - input vector 381 382 Output Parameter: 383 . y - output vector 384 385 Notes: 386 Currently, this routine is implemented only for PCICC and PCJACOBI preconditioners. 387 388 Level: developer 389 390 .keywords: PC, apply, symmetric, left 391 392 .seealso: PCApply(), PCApplySymmetricRight() 393 @*/ 394 PetscErrorCode PETSCKSP_DLLEXPORT PCApplySymmetricLeft(PC pc,Vec x,Vec y) 395 { 396 PetscErrorCode ierr; 397 398 PetscFunctionBegin; 399 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 400 PetscValidHeaderSpecific(x,VEC_COOKIE,2); 401 PetscValidHeaderSpecific(y,VEC_COOKIE,3); 402 if (!pc->ops->applysymmetricleft) SETERRQ(PETSC_ERR_SUP,"PC does not have left symmetric apply"); 403 404 if (pc->setupcalled < 2) { 405 ierr = PCSetUp(pc);CHKERRQ(ierr); 406 } 407 408 ierr = PetscLogEventBegin(PC_ApplySymmetricLeft,pc,x,y,0);CHKERRQ(ierr); 409 ierr = (*pc->ops->applysymmetricleft)(pc,x,y);CHKERRQ(ierr); 410 ierr = PetscLogEventEnd(PC_ApplySymmetricLeft,pc,x,y,0);CHKERRQ(ierr); 411 PetscFunctionReturn(0); 412 } 413 414 #undef __FUNCT__ 415 #define __FUNCT__ "PCApplySymmetricRight" 416 /*@ 417 PCApplySymmetricRight - Applies the right part of a symmetric preconditioner to a vector. 418 419 Collective on PC and Vec 420 421 Input Parameters: 422 + pc - the preconditioner context 423 - x - input vector 424 425 Output Parameter: 426 . y - output vector 427 428 Level: developer 429 430 Notes: 431 Currently, this routine is implemented only for PCICC and PCJACOBI preconditioners. 432 433 .keywords: PC, apply, symmetric, right 434 435 .seealso: PCApply(), PCApplySymmetricLeft() 436 @*/ 437 PetscErrorCode PETSCKSP_DLLEXPORT PCApplySymmetricRight(PC pc,Vec x,Vec y) 438 { 439 PetscErrorCode ierr; 440 441 PetscFunctionBegin; 442 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 443 PetscValidHeaderSpecific(x,VEC_COOKIE,2); 444 PetscValidHeaderSpecific(y,VEC_COOKIE,3); 445 if (!pc->ops->applysymmetricright) SETERRQ(PETSC_ERR_SUP,"PC does not have left symmetric apply"); 446 447 if (pc->setupcalled < 2) { 448 ierr = PCSetUp(pc);CHKERRQ(ierr); 449 } 450 451 ierr = PetscLogEventBegin(PC_ApplySymmetricRight,pc,x,y,0);CHKERRQ(ierr); 452 ierr = (*pc->ops->applysymmetricright)(pc,x,y);CHKERRQ(ierr); 453 ierr = PetscLogEventEnd(PC_ApplySymmetricRight,pc,x,y,0);CHKERRQ(ierr); 454 PetscFunctionReturn(0); 455 } 456 457 #undef __FUNCT__ 458 #define __FUNCT__ "PCApplyTranspose" 459 /*@ 460 PCApplyTranspose - Applies the transpose of preconditioner to a vector. 461 462 Collective on PC and Vec 463 464 Input Parameters: 465 + pc - the preconditioner context 466 - x - input vector 467 468 Output Parameter: 469 . y - output vector 470 471 Level: developer 472 473 .keywords: PC, apply, transpose 474 475 .seealso: PCApply(), PCApplyBAorAB(), PCApplyBAorABTranspose(), PCHasApplyTranspose() 476 @*/ 477 PetscErrorCode PETSCKSP_DLLEXPORT PCApplyTranspose(PC pc,Vec x,Vec y) 478 { 479 PetscErrorCode ierr; 480 481 PetscFunctionBegin; 482 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 483 PetscValidHeaderSpecific(x,VEC_COOKIE,2); 484 PetscValidHeaderSpecific(y,VEC_COOKIE,3); 485 if (x == y) SETERRQ(PETSC_ERR_ARG_IDN,"x and y must be different vectors"); 486 if (!pc->ops->applytranspose) SETERRQ(PETSC_ERR_SUP," "); 487 488 if (pc->setupcalled < 2) { 489 ierr = PCSetUp(pc);CHKERRQ(ierr); 490 } 491 492 ierr = PetscLogEventBegin(PC_Apply,pc,x,y,0);CHKERRQ(ierr); 493 ierr = (*pc->ops->applytranspose)(pc,x,y);CHKERRQ(ierr); 494 ierr = PetscLogEventEnd(PC_Apply,pc,x,y,0);CHKERRQ(ierr); 495 PetscFunctionReturn(0); 496 } 497 498 #undef __FUNCT__ 499 #define __FUNCT__ "PCHasApplyTranspose" 500 /*@ 501 PCHasApplyTranspose - Test whether the preconditioner has a transpose apply operation 502 503 Collective on PC and Vec 504 505 Input Parameters: 506 . pc - the preconditioner context 507 508 Output Parameter: 509 . flg - PETSC_TRUE if a transpose operation is defined 510 511 Level: developer 512 513 .keywords: PC, apply, transpose 514 515 .seealso: PCApplyTranspose() 516 @*/ 517 PetscErrorCode PETSCKSP_DLLEXPORT PCHasApplyTranspose(PC pc,PetscTruth *flg) 518 { 519 PetscFunctionBegin; 520 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 521 PetscValidPointer(flg,2); 522 *flg = (PetscTruth) (pc->ops->applytranspose == 0); 523 PetscFunctionReturn(0); 524 } 525 526 #undef __FUNCT__ 527 #define __FUNCT__ "PCApplyBAorAB" 528 /*@ 529 PCApplyBAorAB - Applies the preconditioner and operator to a vector. 530 531 Collective on PC and Vec 532 533 Input Parameters: 534 + pc - the preconditioner context 535 . side - indicates the preconditioner side, one of PC_LEFT, PC_RIGHT, or PC_SYMMETRIC 536 . x - input vector 537 - work - work vector 538 539 Output Parameter: 540 . y - output vector 541 542 Level: developer 543 544 .keywords: PC, apply, operator 545 546 .seealso: PCApply(), PCApplyTranspose(), PCApplyBAorABTranspose() 547 @*/ 548 PetscErrorCode PETSCKSP_DLLEXPORT PCApplyBAorAB(PC pc,PCSide side,Vec x,Vec y,Vec work) 549 { 550 PetscErrorCode ierr; 551 552 PetscFunctionBegin; 553 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 554 PetscValidHeaderSpecific(x,VEC_COOKIE,3); 555 PetscValidHeaderSpecific(y,VEC_COOKIE,4); 556 PetscValidHeaderSpecific(work,VEC_COOKIE,5); 557 if (x == y) SETERRQ(PETSC_ERR_ARG_IDN,"x and y must be different vectors"); 558 if (side != PC_LEFT && side != PC_SYMMETRIC && side != PC_RIGHT) { 559 SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Side must be right, left, or symmetric"); 560 } 561 if (pc->diagonalscale && side == PC_SYMMETRIC) { 562 SETERRQ(PETSC_ERR_SUP,"Cannot include diagonal scaling with symmetric preconditioner application"); 563 } 564 565 if (pc->setupcalled < 2) { 566 ierr = PCSetUp(pc);CHKERRQ(ierr); 567 } 568 569 if (pc->diagonalscale) { 570 if (pc->ops->applyBA) { 571 Vec work2; /* this is expensive, but to fix requires a second work vector argument to PCApplyBAorAB() */ 572 ierr = VecDuplicate(x,&work2);CHKERRQ(ierr); 573 ierr = PCDiagonalScaleRight(pc,x,work2);CHKERRQ(ierr); 574 ierr = (*pc->ops->applyBA)(pc,side,work2,y,work);CHKERRQ(ierr); 575 ierr = PCDiagonalScaleLeft(pc,y,y);CHKERRQ(ierr); 576 ierr = VecDestroy(work2);CHKERRQ(ierr); 577 } else if (side == PC_RIGHT) { 578 ierr = PCDiagonalScaleRight(pc,x,y);CHKERRQ(ierr); 579 ierr = PCApply(pc,y,work);CHKERRQ(ierr); 580 ierr = MatMult(pc->mat,work,y);CHKERRQ(ierr); 581 ierr = PCDiagonalScaleLeft(pc,y,y);CHKERRQ(ierr); 582 } else if (side == PC_LEFT) { 583 ierr = PCDiagonalScaleRight(pc,x,y);CHKERRQ(ierr); 584 ierr = MatMult(pc->mat,y,work);CHKERRQ(ierr); 585 ierr = PCApply(pc,work,y);CHKERRQ(ierr); 586 ierr = PCDiagonalScaleLeft(pc,y,y);CHKERRQ(ierr); 587 } else if (side == PC_SYMMETRIC) { 588 SETERRQ(PETSC_ERR_SUP,"Cannot provide diagonal scaling with symmetric application of preconditioner"); 589 } 590 } else { 591 if (pc->ops->applyBA) { 592 ierr = (*pc->ops->applyBA)(pc,side,x,y,work);CHKERRQ(ierr); 593 } else if (side == PC_RIGHT) { 594 ierr = PCApply(pc,x,work);CHKERRQ(ierr); 595 ierr = MatMult(pc->mat,work,y);CHKERRQ(ierr); 596 } else if (side == PC_LEFT) { 597 ierr = MatMult(pc->mat,x,work);CHKERRQ(ierr); 598 ierr = PCApply(pc,work,y);CHKERRQ(ierr); 599 } else if (side == PC_SYMMETRIC) { 600 /* There's an extra copy here; maybe should provide 2 work vectors instead? */ 601 ierr = PCApplySymmetricRight(pc,x,work);CHKERRQ(ierr); 602 ierr = MatMult(pc->mat,work,y);CHKERRQ(ierr); 603 ierr = VecCopy(y,work);CHKERRQ(ierr); 604 ierr = PCApplySymmetricLeft(pc,work,y);CHKERRQ(ierr); 605 } 606 } 607 PetscFunctionReturn(0); 608 } 609 610 #undef __FUNCT__ 611 #define __FUNCT__ "PCApplyBAorABTranspose" 612 /*@ 613 PCApplyBAorABTranspose - Applies the transpose of the preconditioner 614 and operator to a vector. That is, applies tr(B) * tr(A) with left preconditioning, 615 not tr(B*A) = tr(A)*tr(B). 616 617 Collective on PC and Vec 618 619 Input Parameters: 620 + pc - the preconditioner context 621 . side - indicates the preconditioner side, one of PC_LEFT, PC_RIGHT, or PC_SYMMETRIC 622 . x - input vector 623 - work - work vector 624 625 Output Parameter: 626 . y - output vector 627 628 Level: developer 629 630 .keywords: PC, apply, operator, transpose 631 632 .seealso: PCApply(), PCApplyTranspose(), PCApplyBAorAB() 633 @*/ 634 PetscErrorCode PETSCKSP_DLLEXPORT PCApplyBAorABTranspose(PC pc,PCSide side,Vec x,Vec y,Vec work) 635 { 636 PetscErrorCode ierr; 637 638 PetscFunctionBegin; 639 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 640 PetscValidHeaderSpecific(x,VEC_COOKIE,3); 641 PetscValidHeaderSpecific(y,VEC_COOKIE,4); 642 PetscValidHeaderSpecific(work,VEC_COOKIE,5); 643 if (x == y) SETERRQ(PETSC_ERR_ARG_IDN,"x and y must be different vectors"); 644 if (pc->ops->applyBAtranspose) { 645 ierr = (*pc->ops->applyBAtranspose)(pc,side,x,y,work);CHKERRQ(ierr); 646 PetscFunctionReturn(0); 647 } 648 if (side != PC_LEFT && side != PC_RIGHT) { 649 SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Side must be right or left"); 650 } 651 652 if (pc->setupcalled < 2) { 653 ierr = PCSetUp(pc);CHKERRQ(ierr); 654 } 655 656 if (side == PC_RIGHT) { 657 ierr = PCApplyTranspose(pc,x,work);CHKERRQ(ierr); 658 ierr = MatMultTranspose(pc->mat,work,y);CHKERRQ(ierr); 659 } else if (side == PC_LEFT) { 660 ierr = MatMultTranspose(pc->mat,x,work);CHKERRQ(ierr); 661 ierr = PCApplyTranspose(pc,work,y);CHKERRQ(ierr); 662 } 663 /* add support for PC_SYMMETRIC */ 664 PetscFunctionReturn(0); /* actually will never get here */ 665 } 666 667 /* -------------------------------------------------------------------------------*/ 668 669 #undef __FUNCT__ 670 #define __FUNCT__ "PCApplyRichardsonExists" 671 /*@ 672 PCApplyRichardsonExists - Determines whether a particular preconditioner has a 673 built-in fast application of Richardson's method. 674 675 Not Collective 676 677 Input Parameter: 678 . pc - the preconditioner 679 680 Output Parameter: 681 . exists - PETSC_TRUE or PETSC_FALSE 682 683 Level: developer 684 685 .keywords: PC, apply, Richardson, exists 686 687 .seealso: PCApplyRichardson() 688 @*/ 689 PetscErrorCode PETSCKSP_DLLEXPORT PCApplyRichardsonExists(PC pc,PetscTruth *exists) 690 { 691 PetscFunctionBegin; 692 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 693 PetscValidIntPointer(exists,2); 694 if (pc->ops->applyrichardson) *exists = PETSC_TRUE; 695 else *exists = PETSC_FALSE; 696 PetscFunctionReturn(0); 697 } 698 699 #undef __FUNCT__ 700 #define __FUNCT__ "PCApplyRichardson" 701 /*@ 702 PCApplyRichardson - Applies several steps of Richardson iteration with 703 the particular preconditioner. This routine is usually used by the 704 Krylov solvers and not the application code directly. 705 706 Collective on PC 707 708 Input Parameters: 709 + pc - the preconditioner context 710 . x - the initial guess 711 . w - one work vector 712 . rtol - relative decrease in residual norm convergence criteria 713 . abstol - absolute residual norm convergence criteria 714 . dtol - divergence residual norm increase criteria 715 - its - the number of iterations to apply. 716 717 Output Parameter: 718 . y - the solution 719 720 Notes: 721 Most preconditioners do not support this function. Use the command 722 PCApplyRichardsonExists() to determine if one does. 723 724 Except for the multigrid PC this routine ignores the convergence tolerances 725 and always runs for the number of iterations 726 727 Level: developer 728 729 .keywords: PC, apply, Richardson 730 731 .seealso: PCApplyRichardsonExists() 732 @*/ 733 PetscErrorCode PETSCKSP_DLLEXPORT PCApplyRichardson(PC pc,Vec x,Vec y,Vec w,PetscReal rtol,PetscReal abstol, PetscReal dtol,PetscInt its) 734 { 735 PetscErrorCode ierr; 736 737 PetscFunctionBegin; 738 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 739 PetscValidHeaderSpecific(x,VEC_COOKIE,2); 740 PetscValidHeaderSpecific(y,VEC_COOKIE,3); 741 PetscValidHeaderSpecific(w,VEC_COOKIE,4); 742 if (!pc->ops->applyrichardson) SETERRQ(PETSC_ERR_SUP," "); 743 744 if (pc->setupcalled < 2) { 745 ierr = PCSetUp(pc);CHKERRQ(ierr); 746 } 747 748 ierr = (*pc->ops->applyrichardson)(pc,x,y,w,rtol,abstol,dtol,its);CHKERRQ(ierr); 749 PetscFunctionReturn(0); 750 } 751 752 /* 753 a setupcall of 0 indicates never setup, 754 1 needs to be resetup, 755 2 does not need any changes. 756 */ 757 #undef __FUNCT__ 758 #define __FUNCT__ "PCSetUp" 759 /*@ 760 PCSetUp - Prepares for the use of a preconditioner. 761 762 Collective on PC 763 764 Input Parameter: 765 . pc - the preconditioner context 766 767 Level: developer 768 769 .keywords: PC, setup 770 771 .seealso: PCCreate(), PCApply(), PCDestroy() 772 @*/ 773 PetscErrorCode PETSCKSP_DLLEXPORT PCSetUp(PC pc) 774 { 775 PetscErrorCode ierr; 776 const char *def; 777 778 PetscFunctionBegin; 779 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 780 781 if (pc->setupcalled > 1) { 782 ierr = PetscInfo(pc,"Setting PC with identical preconditioner\n");CHKERRQ(ierr); 783 PetscFunctionReturn(0); 784 } else if (!pc->setupcalled) { 785 ierr = PetscInfo(pc,"Setting up new PC\n");CHKERRQ(ierr); 786 } else if (pc->flag == SAME_NONZERO_PATTERN) { 787 ierr = PetscInfo(pc,"Setting up PC with same nonzero pattern\n");CHKERRQ(ierr); 788 } else { 789 ierr = PetscInfo(pc,"Setting up PC with different nonzero pattern\n");CHKERRQ(ierr); 790 } 791 792 ierr = PetscLogEventBegin(PC_SetUp,pc,0,0,0);CHKERRQ(ierr); 793 if (!pc->mat) {SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be set first");} 794 795 if (!pc->type_name) { 796 ierr = PCGetDefaultType_Private(pc,&def);CHKERRQ(ierr); 797 ierr = PCSetType(pc,def);CHKERRQ(ierr); 798 } 799 800 if (pc->ops->setup) { 801 ierr = (*pc->ops->setup)(pc);CHKERRQ(ierr); 802 } 803 pc->setupcalled = 2; 804 ierr = PetscLogEventEnd(PC_SetUp,pc,0,0,0);CHKERRQ(ierr); 805 PetscFunctionReturn(0); 806 } 807 808 #undef __FUNCT__ 809 #define __FUNCT__ "PCSetUpOnBlocks" 810 /*@ 811 PCSetUpOnBlocks - Sets up the preconditioner for each block in 812 the block Jacobi, block Gauss-Seidel, and overlapping Schwarz 813 methods. 814 815 Collective on PC 816 817 Input Parameters: 818 . pc - the preconditioner context 819 820 Level: developer 821 822 .keywords: PC, setup, blocks 823 824 .seealso: PCCreate(), PCApply(), PCDestroy(), PCSetUp() 825 @*/ 826 PetscErrorCode PETSCKSP_DLLEXPORT PCSetUpOnBlocks(PC pc) 827 { 828 PetscErrorCode ierr; 829 830 PetscFunctionBegin; 831 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 832 if (!pc->ops->setuponblocks) PetscFunctionReturn(0); 833 ierr = PetscLogEventBegin(PC_SetUpOnBlocks,pc,0,0,0);CHKERRQ(ierr); 834 ierr = (*pc->ops->setuponblocks)(pc);CHKERRQ(ierr); 835 ierr = PetscLogEventEnd(PC_SetUpOnBlocks,pc,0,0,0);CHKERRQ(ierr); 836 PetscFunctionReturn(0); 837 } 838 839 #undef __FUNCT__ 840 #define __FUNCT__ "PCSetModifySubMatrices" 841 /*@C 842 PCSetModifySubMatrices - Sets a user-defined routine for modifying the 843 submatrices that arise within certain subdomain-based preconditioners. 844 The basic submatrices are extracted from the preconditioner matrix as 845 usual; the user can then alter these (for example, to set different boundary 846 conditions for each submatrix) before they are used for the local solves. 847 848 Collective on PC 849 850 Input Parameters: 851 + pc - the preconditioner context 852 . func - routine for modifying the submatrices 853 - ctx - optional user-defined context (may be null) 854 855 Calling sequence of func: 856 $ func (PC pc,PetscInt nsub,IS *row,IS *col,Mat *submat,void *ctx); 857 858 . row - an array of index sets that contain the global row numbers 859 that comprise each local submatrix 860 . col - an array of index sets that contain the global column numbers 861 that comprise each local submatrix 862 . submat - array of local submatrices 863 - ctx - optional user-defined context for private data for the 864 user-defined func routine (may be null) 865 866 Notes: 867 PCSetModifySubMatrices() MUST be called before KSPSetUp() and 868 KSPSolve(). 869 870 A routine set by PCSetModifySubMatrices() is currently called within 871 the block Jacobi (PCBJACOBI) and additive Schwarz (PCASM) 872 preconditioners. All other preconditioners ignore this routine. 873 874 Level: advanced 875 876 .keywords: PC, set, modify, submatrices 877 878 .seealso: PCModifySubMatrices() 879 @*/ 880 PetscErrorCode PETSCKSP_DLLEXPORT PCSetModifySubMatrices(PC pc,PetscErrorCode (*func)(PC,PetscInt,const IS[],const IS[],Mat[],void*),void *ctx) 881 { 882 PetscFunctionBegin; 883 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 884 pc->modifysubmatrices = func; 885 pc->modifysubmatricesP = ctx; 886 PetscFunctionReturn(0); 887 } 888 889 #undef __FUNCT__ 890 #define __FUNCT__ "PCModifySubMatrices" 891 /*@C 892 PCModifySubMatrices - Calls an optional user-defined routine within 893 certain preconditioners if one has been set with PCSetModifySubMarices(). 894 895 Collective on PC 896 897 Input Parameters: 898 + pc - the preconditioner context 899 . nsub - the number of local submatrices 900 . row - an array of index sets that contain the global row numbers 901 that comprise each local submatrix 902 . col - an array of index sets that contain the global column numbers 903 that comprise each local submatrix 904 . submat - array of local submatrices 905 - ctx - optional user-defined context for private data for the 906 user-defined routine (may be null) 907 908 Output Parameter: 909 . submat - array of local submatrices (the entries of which may 910 have been modified) 911 912 Notes: 913 The user should NOT generally call this routine, as it will 914 automatically be called within certain preconditioners (currently 915 block Jacobi, additive Schwarz) if set. 916 917 The basic submatrices are extracted from the preconditioner matrix 918 as usual; the user can then alter these (for example, to set different 919 boundary conditions for each submatrix) before they are used for the 920 local solves. 921 922 Level: developer 923 924 .keywords: PC, modify, submatrices 925 926 .seealso: PCSetModifySubMatrices() 927 @*/ 928 PetscErrorCode PETSCKSP_DLLEXPORT PCModifySubMatrices(PC pc,PetscInt nsub,const IS row[],const IS col[],Mat submat[],void *ctx) 929 { 930 PetscErrorCode ierr; 931 932 PetscFunctionBegin; 933 if (!pc->modifysubmatrices) PetscFunctionReturn(0); 934 ierr = PetscLogEventBegin(PC_ModifySubMatrices,pc,0,0,0);CHKERRQ(ierr); 935 ierr = (*pc->modifysubmatrices)(pc,nsub,row,col,submat,ctx);CHKERRQ(ierr); 936 ierr = PetscLogEventEnd(PC_ModifySubMatrices,pc,0,0,0);CHKERRQ(ierr); 937 PetscFunctionReturn(0); 938 } 939 940 #undef __FUNCT__ 941 #define __FUNCT__ "PCSetOperators" 942 /*@ 943 PCSetOperators - Sets the matrix associated with the linear system and 944 a (possibly) different one associated with the preconditioner. 945 946 Collective on PC and Mat 947 948 Input Parameters: 949 + pc - the preconditioner context 950 . Amat - the matrix associated with the linear system 951 . Pmat - the matrix to be used in constructing the preconditioner, usually 952 the same as Amat. 953 - flag - flag indicating information about the preconditioner matrix structure 954 during successive linear solves. This flag is ignored the first time a 955 linear system is solved, and thus is irrelevant when solving just one linear 956 system. 957 958 Notes: 959 The flag can be used to eliminate unnecessary work in the preconditioner 960 during the repeated solution of linear systems of the same size. The 961 available options are 962 + SAME_PRECONDITIONER - 963 Pmat is identical during successive linear solves. 964 This option is intended for folks who are using 965 different Amat and Pmat matrices and wish to reuse the 966 same preconditioner matrix. For example, this option 967 saves work by not recomputing incomplete factorization 968 for ILU/ICC preconditioners. 969 . SAME_NONZERO_PATTERN - 970 Pmat has the same nonzero structure during 971 successive linear solves. 972 - DIFFERENT_NONZERO_PATTERN - 973 Pmat does not have the same nonzero structure. 974 975 Caution: 976 If you specify SAME_NONZERO_PATTERN, PETSc believes your assertion 977 and does not check the structure of the matrix. If you erroneously 978 claim that the structure is the same when it actually is not, the new 979 preconditioner will not function correctly. Thus, use this optimization 980 feature carefully! 981 982 If in doubt about whether your preconditioner matrix has changed 983 structure or not, use the flag DIFFERENT_NONZERO_PATTERN. 984 985 More Notes about Repeated Solution of Linear Systems: 986 PETSc does NOT reset the matrix entries of either Amat or Pmat 987 to zero after a linear solve; the user is completely responsible for 988 matrix assembly. See the routine MatZeroEntries() if desiring to 989 zero all elements of a matrix. 990 991 Level: intermediate 992 993 .keywords: PC, set, operators, matrix, linear system 994 995 .seealso: PCGetOperators(), MatZeroEntries() 996 @*/ 997 PetscErrorCode PETSCKSP_DLLEXPORT PCSetOperators(PC pc,Mat Amat,Mat Pmat,MatStructure flag) 998 { 999 PetscErrorCode ierr; 1000 PetscTruth isbjacobi,isrowbs; 1001 1002 PetscFunctionBegin; 1003 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 1004 if (Amat) PetscValidHeaderSpecific(Amat,MAT_COOKIE,2); 1005 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_COOKIE,3); 1006 if (Amat) PetscCheckSameComm(pc,1,Amat,2); 1007 if (Pmat) PetscCheckSameComm(pc,1,Pmat,3); 1008 1009 /* 1010 BlockSolve95 cannot use default BJacobi preconditioning 1011 */ 1012 if (Amat) { 1013 ierr = PetscTypeCompare((PetscObject)Amat,MATMPIROWBS,&isrowbs);CHKERRQ(ierr); 1014 if (isrowbs) { 1015 ierr = PetscTypeCompare((PetscObject)pc,PCBJACOBI,&isbjacobi);CHKERRQ(ierr); 1016 if (isbjacobi) { 1017 ierr = PCSetType(pc,PCILU);CHKERRQ(ierr); 1018 ierr = PetscInfo(pc,"Switching default PC to PCILU since BS95 doesn't support PCBJACOBI\n");CHKERRQ(ierr); 1019 } 1020 } 1021 } 1022 1023 /* reference first in case the matrices are the same */ 1024 if (Amat) {ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr);} 1025 if (pc->mat) {ierr = MatDestroy(pc->mat);CHKERRQ(ierr);} 1026 if (Pmat) {ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr);} 1027 if (pc->pmat) {ierr = MatDestroy(pc->pmat);CHKERRQ(ierr);} 1028 pc->mat = Amat; 1029 pc->pmat = Pmat; 1030 1031 if (pc->setupcalled == 2 && flag != SAME_PRECONDITIONER) { 1032 pc->setupcalled = 1; 1033 } 1034 pc->flag = flag; 1035 PetscFunctionReturn(0); 1036 } 1037 1038 #undef __FUNCT__ 1039 #define __FUNCT__ "PCGetOperators" 1040 /*@C 1041 PCGetOperators - Gets the matrix associated with the linear system and 1042 possibly a different one associated with the preconditioner. 1043 1044 Not collective, though parallel Mats are returned if the PC is parallel 1045 1046 Input Parameter: 1047 . pc - the preconditioner context 1048 1049 Output Parameters: 1050 + mat - the matrix associated with the linear system 1051 . pmat - matrix associated with the preconditioner, usually the same 1052 as mat. 1053 - flag - flag indicating information about the preconditioner 1054 matrix structure. See PCSetOperators() for details. 1055 1056 Level: intermediate 1057 1058 .keywords: PC, get, operators, matrix, linear system 1059 1060 .seealso: PCSetOperators(), KSPGetOperators(), KSPSetOperators(), PCGetOperatorsSet() 1061 @*/ 1062 PetscErrorCode PETSCKSP_DLLEXPORT PCGetOperators(PC pc,Mat *mat,Mat *pmat,MatStructure *flag) 1063 { 1064 PetscFunctionBegin; 1065 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 1066 if (mat) *mat = pc->mat; 1067 if (pmat) *pmat = pc->pmat; 1068 if (flag) *flag = pc->flag; 1069 PetscFunctionReturn(0); 1070 } 1071 1072 #undef __FUNCT__ 1073 #define __FUNCT__ "PCGetOperatorsSet" 1074 /*@C 1075 PCGetOperatorsSet - Determines if the matrix associated with the linear system and 1076 possibly a different one associated with the preconditioner have been set in the PC. 1077 1078 Not collective, though the results on all processes should be the same 1079 1080 Input Parameter: 1081 . pc - the preconditioner context 1082 1083 Output Parameters: 1084 + mat - the matrix associated with the linear system was set 1085 - pmat - matrix associated with the preconditioner was set, usually the same 1086 1087 Level: intermediate 1088 1089 .keywords: PC, get, operators, matrix, linear system 1090 1091 .seealso: PCSetOperators(), KSPGetOperators(), KSPSetOperators(), PCGetOperators() 1092 @*/ 1093 PetscErrorCode PETSCKSP_DLLEXPORT PCGetOperatorsSet(PC pc,PetscTruth *mat,PetscTruth *pmat) 1094 { 1095 PetscFunctionBegin; 1096 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 1097 if (mat) *mat = (pc->mat) ? PETSC_TRUE : PETSC_FALSE; 1098 if (pmat) *pmat = (pc->pmat) ? PETSC_TRUE : PETSC_FALSE; 1099 PetscFunctionReturn(0); 1100 } 1101 1102 #undef __FUNCT__ 1103 #define __FUNCT__ "PCGetFactoredMatrix" 1104 /*@ 1105 PCGetFactoredMatrix - Gets the factored matrix from the 1106 preconditioner context. This routine is valid only for the LU, 1107 incomplete LU, Cholesky, and incomplete Cholesky methods. 1108 1109 Not Collective on PC though Mat is parallel if PC is parallel 1110 1111 Input Parameters: 1112 . pc - the preconditioner context 1113 1114 Output parameters: 1115 . mat - the factored matrix 1116 1117 Level: advanced 1118 1119 Notes: Does not increase the reference count for the matrix so DO NOT destroy it 1120 1121 .keywords: PC, get, factored, matrix 1122 @*/ 1123 PetscErrorCode PETSCKSP_DLLEXPORT PCGetFactoredMatrix(PC pc,Mat *mat) 1124 { 1125 PetscErrorCode ierr; 1126 1127 PetscFunctionBegin; 1128 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 1129 PetscValidPointer(mat,2); 1130 if (pc->ops->getfactoredmatrix) { 1131 ierr = (*pc->ops->getfactoredmatrix)(pc,mat);CHKERRQ(ierr); 1132 } 1133 PetscFunctionReturn(0); 1134 } 1135 1136 #undef __FUNCT__ 1137 #define __FUNCT__ "PCSetOptionsPrefix" 1138 /*@C 1139 PCSetOptionsPrefix - Sets the prefix used for searching for all 1140 PC options in the database. 1141 1142 Collective on PC 1143 1144 Input Parameters: 1145 + pc - the preconditioner context 1146 - prefix - the prefix string to prepend to all PC option requests 1147 1148 Notes: 1149 A hyphen (-) must NOT be given at the beginning of the prefix name. 1150 The first character of all runtime options is AUTOMATICALLY the 1151 hyphen. 1152 1153 Level: advanced 1154 1155 .keywords: PC, set, options, prefix, database 1156 1157 .seealso: PCAppendOptionsPrefix(), PCGetOptionsPrefix() 1158 @*/ 1159 PetscErrorCode PETSCKSP_DLLEXPORT PCSetOptionsPrefix(PC pc,const char prefix[]) 1160 { 1161 PetscErrorCode ierr; 1162 1163 PetscFunctionBegin; 1164 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 1165 ierr = PetscObjectSetOptionsPrefix((PetscObject)pc,prefix);CHKERRQ(ierr); 1166 PetscFunctionReturn(0); 1167 } 1168 1169 #undef __FUNCT__ 1170 #define __FUNCT__ "PCAppendOptionsPrefix" 1171 /*@C 1172 PCAppendOptionsPrefix - Appends to the prefix used for searching for all 1173 PC options in the database. 1174 1175 Collective on PC 1176 1177 Input Parameters: 1178 + pc - the preconditioner context 1179 - prefix - the prefix string to prepend to all PC option requests 1180 1181 Notes: 1182 A hyphen (-) must NOT be given at the beginning of the prefix name. 1183 The first character of all runtime options is AUTOMATICALLY the 1184 hyphen. 1185 1186 Level: advanced 1187 1188 .keywords: PC, append, options, prefix, database 1189 1190 .seealso: PCSetOptionsPrefix(), PCGetOptionsPrefix() 1191 @*/ 1192 PetscErrorCode PETSCKSP_DLLEXPORT PCAppendOptionsPrefix(PC pc,const char prefix[]) 1193 { 1194 PetscErrorCode ierr; 1195 1196 PetscFunctionBegin; 1197 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 1198 ierr = PetscObjectAppendOptionsPrefix((PetscObject)pc,prefix);CHKERRQ(ierr); 1199 PetscFunctionReturn(0); 1200 } 1201 1202 #undef __FUNCT__ 1203 #define __FUNCT__ "PCGetOptionsPrefix" 1204 /*@C 1205 PCGetOptionsPrefix - Gets the prefix used for searching for all 1206 PC options in the database. 1207 1208 Not Collective 1209 1210 Input Parameters: 1211 . pc - the preconditioner context 1212 1213 Output Parameters: 1214 . prefix - pointer to the prefix string used, is returned 1215 1216 Notes: On the fortran side, the user should pass in a string 'prifix' of 1217 sufficient length to hold the prefix. 1218 1219 Level: advanced 1220 1221 .keywords: PC, get, options, prefix, database 1222 1223 .seealso: PCSetOptionsPrefix(), PCAppendOptionsPrefix() 1224 @*/ 1225 PetscErrorCode PETSCKSP_DLLEXPORT PCGetOptionsPrefix(PC pc,const char *prefix[]) 1226 { 1227 PetscErrorCode ierr; 1228 1229 PetscFunctionBegin; 1230 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 1231 PetscValidPointer(prefix,2); 1232 ierr = PetscObjectGetOptionsPrefix((PetscObject)pc,prefix);CHKERRQ(ierr); 1233 PetscFunctionReturn(0); 1234 } 1235 1236 #undef __FUNCT__ 1237 #define __FUNCT__ "PCPreSolve" 1238 /*@ 1239 PCPreSolve - Optional pre-solve phase, intended for any 1240 preconditioner-specific actions that must be performed before 1241 the iterative solve itself. 1242 1243 Collective on PC 1244 1245 Input Parameters: 1246 + pc - the preconditioner context 1247 - ksp - the Krylov subspace context 1248 1249 Level: developer 1250 1251 Sample of Usage: 1252 .vb 1253 PCPreSolve(pc,ksp); 1254 KSPSolve(ksp,b,x); 1255 PCPostSolve(pc,ksp); 1256 .ve 1257 1258 Notes: 1259 The pre-solve phase is distinct from the PCSetUp() phase. 1260 1261 KSPSolve() calls this directly, so is rarely called by the user. 1262 1263 .keywords: PC, pre-solve 1264 1265 .seealso: PCPostSolve() 1266 @*/ 1267 PetscErrorCode PETSCKSP_DLLEXPORT PCPreSolve(PC pc,KSP ksp) 1268 { 1269 PetscErrorCode ierr; 1270 Vec x,rhs; 1271 Mat A,B; 1272 1273 PetscFunctionBegin; 1274 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 1275 PetscValidHeaderSpecific(ksp,KSP_COOKIE,2); 1276 ierr = KSPGetSolution(ksp,&x);CHKERRQ(ierr); 1277 ierr = KSPGetRhs(ksp,&rhs);CHKERRQ(ierr); 1278 /* 1279 Scale the system and have the matrices use the scaled form 1280 only if the two matrices are actually the same (and hence 1281 have the same scaling 1282 */ 1283 ierr = PCGetOperators(pc,&A,&B,PETSC_NULL);CHKERRQ(ierr); 1284 if (A == B) { 1285 ierr = MatScaleSystem(pc->mat,rhs,x);CHKERRQ(ierr); 1286 ierr = MatUseScaledForm(pc->mat,PETSC_TRUE);CHKERRQ(ierr); 1287 } 1288 1289 if (pc->ops->presolve) { 1290 ierr = (*pc->ops->presolve)(pc,ksp,rhs,x);CHKERRQ(ierr); 1291 } 1292 PetscFunctionReturn(0); 1293 } 1294 1295 #undef __FUNCT__ 1296 #define __FUNCT__ "PCPostSolve" 1297 /*@ 1298 PCPostSolve - Optional post-solve phase, intended for any 1299 preconditioner-specific actions that must be performed after 1300 the iterative solve itself. 1301 1302 Collective on PC 1303 1304 Input Parameters: 1305 + pc - the preconditioner context 1306 - ksp - the Krylov subspace context 1307 1308 Sample of Usage: 1309 .vb 1310 PCPreSolve(pc,ksp); 1311 KSPSolve(ksp,b,x); 1312 PCPostSolve(pc,ksp); 1313 .ve 1314 1315 Note: 1316 KSPSolve() calls this routine directly, so it is rarely called by the user. 1317 1318 Level: developer 1319 1320 .keywords: PC, post-solve 1321 1322 .seealso: PCPreSolve(), KSPSolve() 1323 @*/ 1324 PetscErrorCode PETSCKSP_DLLEXPORT PCPostSolve(PC pc,KSP ksp) 1325 { 1326 PetscErrorCode ierr; 1327 Vec x,rhs; 1328 Mat A,B; 1329 1330 PetscFunctionBegin; 1331 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 1332 PetscValidHeaderSpecific(ksp,KSP_COOKIE,2); 1333 ierr = KSPGetSolution(ksp,&x);CHKERRQ(ierr); 1334 ierr = KSPGetRhs(ksp,&rhs);CHKERRQ(ierr); 1335 if (pc->ops->postsolve) { 1336 ierr = (*pc->ops->postsolve)(pc,ksp,rhs,x);CHKERRQ(ierr); 1337 } 1338 1339 /* 1340 Scale the system and have the matrices use the scaled form 1341 only if the two matrices are actually the same (and hence 1342 have the same scaling 1343 */ 1344 ierr = PCGetOperators(pc,&A,&B,PETSC_NULL);CHKERRQ(ierr); 1345 if (A == B) { 1346 ierr = MatUnScaleSystem(pc->mat,rhs,x);CHKERRQ(ierr); 1347 ierr = MatUseScaledForm(pc->mat,PETSC_FALSE);CHKERRQ(ierr); 1348 } 1349 PetscFunctionReturn(0); 1350 } 1351 1352 #undef __FUNCT__ 1353 #define __FUNCT__ "PCView" 1354 /*@C 1355 PCView - Prints the PC data structure. 1356 1357 Collective on PC 1358 1359 Input Parameters: 1360 + PC - the PC context 1361 - viewer - optional visualization context 1362 1363 Note: 1364 The available visualization contexts include 1365 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 1366 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 1367 output where only the first processor opens 1368 the file. All other processors send their 1369 data to the first processor to print. 1370 1371 The user can open an alternative visualization contexts with 1372 PetscViewerASCIIOpen() (output to a specified file). 1373 1374 Level: developer 1375 1376 .keywords: PC, view 1377 1378 .seealso: KSPView(), PetscViewerASCIIOpen() 1379 @*/ 1380 PetscErrorCode PETSCKSP_DLLEXPORT PCView(PC pc,PetscViewer viewer) 1381 { 1382 PCType cstr; 1383 PetscErrorCode ierr; 1384 PetscTruth mat_exists,iascii,isstring; 1385 PetscViewerFormat format; 1386 1387 PetscFunctionBegin; 1388 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 1389 if (!viewer) viewer = PETSC_VIEWER_STDOUT_(pc->comm); 1390 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2); 1391 PetscCheckSameComm(pc,1,viewer,2); 1392 1393 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 1394 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);CHKERRQ(ierr); 1395 if (iascii) { 1396 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1397 if (pc->prefix) { 1398 ierr = PetscViewerASCIIPrintf(viewer,"PC Object:(%s)\n",pc->prefix);CHKERRQ(ierr); 1399 } else { 1400 ierr = PetscViewerASCIIPrintf(viewer,"PC Object:\n");CHKERRQ(ierr); 1401 } 1402 ierr = PCGetType(pc,&cstr);CHKERRQ(ierr); 1403 if (cstr) { 1404 ierr = PetscViewerASCIIPrintf(viewer," type: %s\n",cstr);CHKERRQ(ierr); 1405 } else { 1406 ierr = PetscViewerASCIIPrintf(viewer," type: not yet set\n");CHKERRQ(ierr); 1407 } 1408 if (pc->ops->view) { 1409 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1410 ierr = (*pc->ops->view)(pc,viewer);CHKERRQ(ierr); 1411 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1412 } 1413 ierr = PetscObjectExists((PetscObject)pc->mat,&mat_exists);CHKERRQ(ierr); 1414 if (mat_exists) { 1415 ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr); 1416 if (pc->pmat == pc->mat) { 1417 ierr = PetscViewerASCIIPrintf(viewer," linear system matrix = precond matrix:\n");CHKERRQ(ierr); 1418 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1419 ierr = MatView(pc->mat,viewer);CHKERRQ(ierr); 1420 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1421 } else { 1422 ierr = PetscObjectExists((PetscObject)pc->pmat,&mat_exists);CHKERRQ(ierr); 1423 if (mat_exists) { 1424 ierr = PetscViewerASCIIPrintf(viewer," linear system matrix followed by preconditioner matrix:\n");CHKERRQ(ierr); 1425 } else { 1426 ierr = PetscViewerASCIIPrintf(viewer," linear system matrix:\n");CHKERRQ(ierr); 1427 } 1428 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1429 ierr = MatView(pc->mat,viewer);CHKERRQ(ierr); 1430 if (mat_exists) {ierr = MatView(pc->pmat,viewer);CHKERRQ(ierr);} 1431 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1432 } 1433 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 1434 } 1435 } else if (isstring) { 1436 ierr = PCGetType(pc,&cstr);CHKERRQ(ierr); 1437 ierr = PetscViewerStringSPrintf(viewer," %-7.7s",cstr);CHKERRQ(ierr); 1438 if (pc->ops->view) {ierr = (*pc->ops->view)(pc,viewer);CHKERRQ(ierr);} 1439 } else { 1440 SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by PC",((PetscObject)viewer)->type_name); 1441 } 1442 PetscFunctionReturn(0); 1443 } 1444 1445 #undef __FUNCT__ 1446 #define __FUNCT__ "PCRegister" 1447 /*@C 1448 PCRegister - See PCRegisterDynamic() 1449 1450 Level: advanced 1451 @*/ 1452 PetscErrorCode PETSCKSP_DLLEXPORT PCRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(PC)) 1453 { 1454 PetscErrorCode ierr; 1455 char fullname[PETSC_MAX_PATH_LEN]; 1456 1457 PetscFunctionBegin; 1458 1459 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 1460 ierr = PetscFListAdd(&PCList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 1461 PetscFunctionReturn(0); 1462 } 1463 1464 #undef __FUNCT__ 1465 #define __FUNCT__ "PCComputeExplicitOperator" 1466 /*@ 1467 PCComputeExplicitOperator - Computes the explicit preconditioned operator. 1468 1469 Collective on PC 1470 1471 Input Parameter: 1472 . pc - the preconditioner object 1473 1474 Output Parameter: 1475 . mat - the explict preconditioned operator 1476 1477 Notes: 1478 This computation is done by applying the operators to columns of the 1479 identity matrix. 1480 1481 Currently, this routine uses a dense matrix format when 1 processor 1482 is used and a sparse format otherwise. This routine is costly in general, 1483 and is recommended for use only with relatively small systems. 1484 1485 Level: advanced 1486 1487 .keywords: PC, compute, explicit, operator 1488 1489 @*/ 1490 PetscErrorCode PETSCKSP_DLLEXPORT PCComputeExplicitOperator(PC pc,Mat *mat) 1491 { 1492 Vec in,out; 1493 PetscErrorCode ierr; 1494 PetscInt i,M,m,*rows,start,end; 1495 PetscMPIInt size; 1496 MPI_Comm comm; 1497 PetscScalar *array,one = 1.0; 1498 1499 PetscFunctionBegin; 1500 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 1501 PetscValidPointer(mat,2); 1502 1503 comm = pc->comm; 1504 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 1505 1506 if (!pc->pmat) SETERRQ(PETSC_ERR_ORDER,"You must call KSPSetOperators() or PCSetOperators() before this call"); 1507 ierr = MatGetVecs(pc->pmat,&in,0);CHKERRQ(ierr); 1508 ierr = VecDuplicate(in,&out);CHKERRQ(ierr); 1509 ierr = VecGetOwnershipRange(in,&start,&end);CHKERRQ(ierr); 1510 ierr = VecGetSize(in,&M);CHKERRQ(ierr); 1511 ierr = VecGetLocalSize(in,&m);CHKERRQ(ierr); 1512 ierr = PetscMalloc((m+1)*sizeof(PetscInt),&rows);CHKERRQ(ierr); 1513 for (i=0; i<m; i++) {rows[i] = start + i;} 1514 1515 ierr = MatCreate(comm,mat);CHKERRQ(ierr); 1516 ierr = MatSetSizes(*mat,m,m,M,M);CHKERRQ(ierr); 1517 if (size == 1) { 1518 ierr = MatSetType(*mat,MATSEQDENSE);CHKERRQ(ierr); 1519 ierr = MatSeqDenseSetPreallocation(*mat,PETSC_NULL);CHKERRQ(ierr); 1520 } else { 1521 ierr = MatSetType(*mat,MATMPIAIJ);CHKERRQ(ierr); 1522 ierr = MatMPIAIJSetPreallocation(*mat,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr); 1523 } 1524 1525 for (i=0; i<M; i++) { 1526 1527 ierr = VecSet(in,0.0);CHKERRQ(ierr); 1528 ierr = VecSetValues(in,1,&i,&one,INSERT_VALUES);CHKERRQ(ierr); 1529 ierr = VecAssemblyBegin(in);CHKERRQ(ierr); 1530 ierr = VecAssemblyEnd(in);CHKERRQ(ierr); 1531 1532 /* should fix, allowing user to choose side */ 1533 ierr = PCApply(pc,in,out);CHKERRQ(ierr); 1534 1535 ierr = VecGetArray(out,&array);CHKERRQ(ierr); 1536 ierr = MatSetValues(*mat,m,rows,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 1537 ierr = VecRestoreArray(out,&array);CHKERRQ(ierr); 1538 1539 } 1540 ierr = PetscFree(rows);CHKERRQ(ierr); 1541 ierr = VecDestroy(out);CHKERRQ(ierr); 1542 ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1543 ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1544 PetscFunctionReturn(0); 1545 } 1546 1547