1 2 /* -------------------------------------------------------------------- 3 4 This file implements a Deflation preconditioner in PETSc as part of PC. 5 You can use this as a starting point for implementing your own 6 preconditioner that is not provided with PETSc. (You might also consider 7 just using PCSHELL) 8 9 The following basic routines are required for each preconditioner. 10 PCCreate_XXX() - Creates a preconditioner context 11 PCSetFromOptions_XXX() - Sets runtime options 12 PCApply_XXX() - Applies the preconditioner 13 PCDestroy_XXX() - Destroys the preconditioner context 14 where the suffix "_XXX" denotes a particular implementation, in 15 this case we use _Deflation (e.g., PCCreate_Deflation, PCApply_Deflation). 16 These routines are actually called via the common user interface 17 routines PCCreate(), PCSetFromOptions(), PCApply(), and PCDestroy(), 18 so the application code interface remains identical for all 19 preconditioners. 20 21 Another key routine is: 22 PCSetUp_XXX() - Prepares for the use of a preconditioner 23 by setting data structures and options. The interface routine PCSetUp() 24 is not usually called directly by the user, but instead is called by 25 PCApply() if necessary. 26 27 Additional basic routines are: 28 PCView_XXX() - Prints details of runtime options that 29 have actually been used. 30 These are called by application codes via the interface routines 31 PCView(). 32 33 The various types of solvers (preconditioners, Krylov subspace methods, 34 nonlinear solvers, timesteppers) are all organized similarly, so the 35 above description applies to these categories also. One exception is 36 that the analogues of PCApply() for these components are KSPSolve(), 37 SNESSolve(), and TSSolve(). 38 39 Additional optional functionality unique to preconditioners is left and 40 right symmetric preconditioner application via PCApplySymmetricLeft() 41 and PCApplySymmetricRight(). The Deflation implementation is 42 PCApplySymmetricLeftOrRight_Deflation(). 43 44 -------------------------------------------------------------------- */ 45 46 /* 47 Include files needed for the Deflation preconditioner: 48 pcimpl.h - private include file intended for use by all preconditioners 49 */ 50 51 #include <../src/ksp/pc/impls/deflation/deflation.h> /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 52 53 const char *const PCDeflationTypes[] = {"INIT","PRE","POST","PCDeflationType","PC_DEFLATION_",0}; 54 55 static PetscErrorCode PCDeflationSetSpace_Deflation(PC pc,Mat W,PetscBool transpose) 56 { 57 PC_Deflation *def = (PC_Deflation*)pc->data; 58 PetscErrorCode ierr; 59 60 PetscFunctionBegin; 61 if (transpose) { 62 def->Wt = W; 63 def->W = NULL; 64 } else { 65 def->W = W; 66 } 67 ierr = PetscObjectReference((PetscObject)W);CHKERRQ(ierr); 68 PetscFunctionReturn(0); 69 } 70 71 /* TODO create PCDeflationSetSpaceTranspose? */ 72 /*@ 73 PCDeflationSetSpace - Set deflation space matrix (or its transpose). 74 75 Logically Collective on PC 76 77 Input Parameters: 78 + pc - the preconditioner context 79 . W - deflation matrix 80 - tranpose - indicates that W is an explicit transpose of the deflation matrix 81 82 Level: intermediate 83 84 .seealso: PCDEFLATION 85 @*/ 86 PetscErrorCode PCDeflationSetSpace(PC pc,Mat W,PetscBool transpose) 87 { 88 PetscErrorCode ierr; 89 90 PetscFunctionBegin; 91 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 92 PetscValidHeaderSpecific(W,MAT_CLASSID,2); 93 PetscValidLogicalCollectiveBool(pc,transpose,3); 94 ierr = PetscTryMethod(pc,"PCDeflationSetSpace_C",(PC,Mat,PetscBool),(pc,W,transpose));CHKERRQ(ierr); 95 PetscFunctionReturn(0); 96 } 97 98 static PetscErrorCode PCDeflationSetLvl_Deflation(PC pc,PetscInt current,PetscInt max) 99 { 100 PC_Deflation *def = (PC_Deflation*)pc->data; 101 102 PetscFunctionBegin; 103 def->nestedlvl = current; 104 def->maxnestedlvl = max; 105 PetscFunctionReturn(0); 106 } 107 108 /*@ 109 PCDeflationSetMaxLvl - Set maximum level of deflation. 110 111 Logically Collective on PC 112 113 Input Parameters: 114 + pc - the preconditioner context 115 . max - maximum deflation level 116 117 Level: intermediate 118 119 .seealso: PCDEFLATION 120 @*/ 121 PetscErrorCode PCDeflationSetMaxLvl(PC pc,PetscInt max) 122 { 123 PetscErrorCode ierr; 124 125 PetscFunctionBegin; 126 PetscValidLogicalCollectiveInt(pc,max,2); 127 ierr = PetscTryMethod(pc,"PCDeflationSetLvl_C",(PC,PetscInt,PetscInt),(pc,0,max));CHKERRQ(ierr); 128 PetscFunctionReturn(0); 129 } 130 131 /* 132 TODO CP corection? 133 x <- x + W*(W'*A*W)^{-1}*W'*r = x + Q*r 134 */ 135 static PetscErrorCode PCPreSolve_Deflation(PC pc,KSP ksp,Vec b, Vec x) 136 { 137 PC_Deflation *def = (PC_Deflation*)pc->data; 138 Mat A; 139 Vec r,w1,w2; 140 PetscBool nonzero; 141 PetscErrorCode ierr; 142 143 PetscFunctionBegin; 144 w1 = def->workcoarse[0]; 145 w2 = def->workcoarse[1]; 146 r = def->work; 147 ierr = PCGetOperators(pc,NULL,&A);CHKERRQ(ierr); 148 149 ierr = KSPGetInitialGuessNonzero(ksp,&nonzero);CHKERRQ(ierr); 150 ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 151 if (nonzero) { 152 ierr = MatMult(A,x,r);CHKERRQ(ierr); /* r <- b - Ax */ 153 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 154 } else { 155 ierr = VecCopy(b,r);CHKERRQ(ierr); /* r <- b (x is 0) */ 156 } 157 158 ierr = MatMultTranspose(def->W,r,w1);CHKERRQ(ierr); /* w1 <- W'*r */ 159 ierr = KSPSolve(def->WtAWinv,w1,w2);CHKERRQ(ierr); /* w2 <- (W'*A*W)^{-1}*w1 */ 160 ierr = MatMult(def->W,w2,r);CHKERRQ(ierr); /* r <- W*w2 */ 161 ierr = VecAYPX(x,1.0,r);CHKERRQ(ierr); 162 PetscFunctionReturn(0); 163 } 164 165 /* 166 if (def->correct) { 167 z <- r - W*(W'*A*W)^{-1}*W'*(A*r -r) = (P-Q)*r 168 } else { 169 z <- r - W*(W'*A*W)^{-1}*W'*A*r = P*r 170 } 171 */ 172 static PetscErrorCode PCApply_Deflation(PC pc,Vec r, Vec z) 173 { 174 PC_Deflation *def = (PC_Deflation*)pc->data; 175 Mat A; 176 Vec u,w1,w2; 177 PetscErrorCode ierr; 178 179 PetscFunctionBegin; 180 w1 = def->workcoarse[0]; 181 w2 = def->workcoarse[1]; 182 u = def->work; 183 ierr = PCGetOperators(pc,NULL,&A);CHKERRQ(ierr); 184 185 if (!def->AW) { 186 ierr = MatMult(A,r,u);CHKERRQ(ierr); /* u <- A*r */ 187 if (def->correct) ierr = VecAXPY(u,-1.0,r);CHKERRQ(ierr); /* u <- A*r -r */ 188 ierr = MatMultTranspose(def->W,u,w1);CHKERRQ(ierr); /* w1 <- W'*u */ 189 } else { 190 ierr = MatMultTranspose(def->AW,u,w1);CHKERRQ(ierr); /* u <- A*r */ 191 if (def->correct) { 192 ierr = MatMultTranspose(def->W,r,w2);CHKERRQ(ierr); /* w2 <- W'*u */ 193 ierr = VecAXPY(w1,-1.0,w2);CHKERRQ(ierr); /* w1 <- w1 - w2 */ 194 } 195 } 196 ierr = KSPSolve(def->WtAWinv,w1,w2);CHKERRQ(ierr); /* w2 <- (W'*A*W)^{-1}*w1 */ 197 ierr = MatMult(def->W,w2,u);CHKERRQ(ierr); /* u <- W*w2 */ 198 ierr = VecWAXPY(z,-1.0,u,r);CHKERRQ(ierr); /* z <- r - u */ 199 PetscFunctionReturn(0); 200 } 201 202 static PetscErrorCode PCDeflationSetType_Deflation(PC pc,PCDeflationType type) 203 { 204 PC_Deflation *def = (PC_Deflation*)pc->data; 205 206 PetscFunctionBegin; 207 def->init = PETSC_FALSE; 208 def->pre = PETSC_FALSE; 209 if (type == PC_DEFLATION_POST) { 210 //pc->ops->postsolve = PCPostSolve_Deflation; 211 pc->ops->presolve = 0; 212 } else { 213 pc->ops->presolve = PCPreSolve_Deflation; 214 pc->ops->postsolve = 0; 215 if (type == PC_DEFLATION_INIT) { 216 def->init = PETSC_TRUE; 217 pc->ops->apply = 0; 218 } else { 219 def->pre = PETSC_TRUE; 220 } 221 } 222 PetscFunctionReturn(0); 223 } 224 225 /*@ 226 PCDeflationSetType - Causes the deflation preconditioner to use only a special 227 initial gues or pre/post solve solution update 228 229 Logically Collective on PC 230 231 Input Parameters: 232 + pc - the preconditioner context 233 - type - PC_DEFLATION_PRE, PC_DEFLATION_INIT, PC_DEFLATION_POST 234 235 Options Database Key: 236 . -pc_deflation_type <pre,init,post> 237 238 Level: intermediate 239 240 Concepts: Deflation preconditioner 241 242 .seealso: PCDeflationGetType() 243 @*/ 244 PetscErrorCode PCDeflationSetType(PC pc,PCDeflationType type) 245 { 246 PetscErrorCode ierr; 247 248 PetscFunctionBegin; 249 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 250 ierr = PetscTryMethod(pc,"PCDeflationSetType_C",(PC,PCDeflationType),(pc,type));CHKERRQ(ierr); 251 PetscFunctionReturn(0); 252 } 253 254 static PetscErrorCode PCDeflationGetType_Deflation(PC pc,PCDeflationType *type) 255 { 256 PC_Deflation *def = (PC_Deflation*)pc->data; 257 258 PetscFunctionBegin; 259 if (def->init) { 260 *type = PC_DEFLATION_INIT; 261 } else if (def->pre) { 262 *type = PC_DEFLATION_PRE; 263 } else { 264 *type = PC_DEFLATION_POST; 265 } 266 PetscFunctionReturn(0); 267 } 268 269 /*@ 270 PCDeflationGetType - Gets how the diagonal matrix is produced for the preconditioner 271 272 Not Collective on PC 273 274 Input Parameter: 275 . pc - the preconditioner context 276 277 Output Parameter: 278 - type - PC_DEFLATION_PRE, PC_DEFLATION_INIT, PC_DEFLATION_POST 279 280 Level: intermediate 281 282 Concepts: Deflation preconditioner 283 284 .seealso: PCDeflationSetType() 285 @*/ 286 PetscErrorCode PCDeflationGetType(PC pc,PCDeflationType *type) 287 { 288 PetscErrorCode ierr; 289 290 PetscFunctionBegin; 291 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 292 ierr = PetscUseMethod(pc,"PCDeflationGetType_C",(PC,PCDeflationType*),(pc,type));CHKERRQ(ierr); 293 PetscFunctionReturn(0); 294 } 295 296 static PetscErrorCode PCSetUp_Deflation(PC pc) 297 { 298 PC_Deflation *def = (PC_Deflation*)pc->data; 299 KSP innerksp; 300 PC pcinner; 301 Mat Amat,nextDef=NULL,*mats; 302 PetscInt i,m,red,size,commsize; 303 PetscBool match,flgspd,transp=PETSC_FALSE; 304 MatCompositeType ctype; 305 MPI_Comm comm; 306 const char *prefix; 307 PetscErrorCode ierr; 308 309 PetscFunctionBegin; 310 if (pc->setupcalled) PetscFunctionReturn(0); 311 ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 312 ierr = PCGetOperators(pc,NULL,&Amat);CHKERRQ(ierr); 313 314 /* compute a deflation space */ 315 if (def->W || def->Wt) { 316 def->spacetype = PC_DEFLATION_SPACE_USER; 317 } else { 318 //ierr = KSPDCGComputeDeflationSpace(ksp);CHKERRQ(ierr); 319 } 320 321 /* nested deflation */ 322 if (def->W) { 323 ierr = PetscObjectTypeCompare((PetscObject)def->W,MATCOMPOSITE,&match);CHKERRQ(ierr); 324 if (match) { 325 ierr = MatCompositeGetType(def->W,&ctype);CHKERRQ(ierr); 326 ierr = MatCompositeGetNumberMat(def->W,&size);CHKERRQ(ierr); 327 } 328 } else { 329 ierr = MatCreateTranspose(def->Wt,&def->W);CHKERRQ(ierr); 330 ierr = PetscObjectTypeCompare((PetscObject)def->Wt,MATCOMPOSITE,&match);CHKERRQ(ierr); 331 if (match) { 332 ierr = MatCompositeGetType(def->Wt,&ctype);CHKERRQ(ierr); 333 ierr = MatCompositeGetNumberMat(def->Wt,&size);CHKERRQ(ierr); 334 } 335 transp = PETSC_TRUE; 336 } 337 if (match && ctype == MAT_COMPOSITE_MULTIPLICATIVE) { 338 ierr = PetscMalloc1(size,&mats);CHKERRQ(ierr); 339 if (!transp) { 340 for (i=0; i<size; i++) { 341 ierr = MatCompositeGetMat(def->W,i,&mats[i]);CHKERRQ(ierr); 342 //ierr = PetscObjectReference((PetscObject)mats[i]);CHKERRQ(ierr); 343 } 344 if (def->nestedlvl < def->maxnestedlvl) { 345 size -= 1; 346 ierr = MatDestroy(&def->W);CHKERRQ(ierr); 347 def->W = mats[size]; 348 ierr = PetscObjectReference((PetscObject)mats[size]);CHKERRQ(ierr); 349 if (size > 1) { 350 ierr = MatCreateComposite(comm,size,mats,&nextDef);CHKERRQ(ierr); 351 ierr = MatCompositeSetType(nextDef,MAT_COMPOSITE_MULTIPLICATIVE);CHKERRQ(ierr); 352 } else { 353 nextDef = mats[0]; 354 ierr = PetscObjectReference((PetscObject)mats[0]);CHKERRQ(ierr); 355 } 356 } else { 357 /* ierr = MatCompositeSetMergeType(def->W,MAT_COMPOSITE_MERGE_LEFT);CHKERRQ(ierr); */ 358 ierr = MatCompositeMerge(def->W);CHKERRQ(ierr); 359 } 360 } 361 ierr = PetscFree(mats);CHKERRQ(ierr); 362 } 363 364 /* setup coarse problem */ 365 if (!def->WtAWinv) { 366 ierr = MatGetSize(def->W,NULL,&m);CHKERRQ(ierr); /* TODO works for W MatTranspose? */ 367 if (!def->WtAW) { 368 /* TODO add implicit product version ? */ 369 if (!def->AW) { 370 ierr = MatPtAP(Amat,def->W,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&def->WtAW);CHKERRQ(ierr); 371 } else { 372 ierr = MatTransposeMatMult(def->W,def->AW,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&def->WtAW);CHKERRQ(ierr); 373 } 374 /* TODO create MatInheritOption(Mat,MatOption) */ 375 ierr = MatGetOption(Amat,MAT_SPD,&flgspd);CHKERRQ(ierr); 376 ierr = MatSetOption(def->WtAW,MAT_SPD,flgspd);CHKERRQ(ierr); 377 #if defined(PETSC_USE_DEBUG) 378 /* Check WtAW is not sigular */ 379 PetscReal *norms; 380 ierr = PetscMalloc1(m,&norms);CHKERRQ(ierr); 381 ierr = MatGetColumnNorms(def->WtAW,NORM_INFINITY,norms);CHKERRQ(ierr); 382 for (i=0; i<m; i++) { 383 if (norms[i] < 100*PETSC_MACHINE_EPSILON) { 384 SETERRQ1(comm,PETSC_ERR_SUP,"Column %D of W is in kernel of A.",i); 385 } 386 } 387 ierr = PetscFree(norms);CHKERRQ(ierr); 388 #endif 389 } else { 390 ierr = MatGetOption(def->WtAW,MAT_SPD,&flgspd);CHKERRQ(ierr); 391 } 392 /* TODO use MATINV */ 393 ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr); 394 ierr = KSPCreate(comm,&def->WtAWinv);CHKERRQ(ierr); 395 ierr = KSPSetOperators(def->WtAWinv,def->WtAW,def->WtAW);CHKERRQ(ierr); 396 ierr = KSPSetType(def->WtAWinv,KSPPREONLY);CHKERRQ(ierr); 397 ierr = KSPGetPC(def->WtAWinv,&pcinner);CHKERRQ(ierr); 398 ierr = PCSetType(pcinner,PCTELESCOPE);CHKERRQ(ierr); 399 /* ugly hack to not have overwritten PCTELESCOPE */ 400 if (prefix) { 401 ierr = KSPSetOptionsPrefix(def->WtAWinv,prefix);CHKERRQ(ierr); 402 ierr = KSPAppendOptionsPrefix(def->WtAWinv,"tel_");CHKERRQ(ierr); 403 } else { 404 ierr = KSPSetOptionsPrefix(def->WtAWinv,"tel_");CHKERRQ(ierr); 405 } 406 ierr = PCSetFromOptions(pcinner);CHKERRQ(ierr); 407 /* Reduction factor choice */ 408 red = def->reductionfact; 409 if (red < 0) { 410 ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 411 red = ceil((float)commsize/ceil((float)m/commsize)); 412 ierr = PetscObjectTypeCompareAny((PetscObject)(def->WtAW),&match,MATSEQDENSE,MATMPIDENSE,MATDENSE,"");CHKERRQ(ierr); 413 if (match) red = commsize; 414 ierr = PetscInfo1(pc,"Auto choosing reduction factor %D\n",red);CHKERRQ(ierr); /* TODO add level? */ 415 } 416 ierr = PCTelescopeSetReductionFactor(pcinner,red);CHKERRQ(ierr); 417 ierr = PCSetUp(pcinner);CHKERRQ(ierr); 418 ierr = PCTelescopeGetKSP(pcinner,&innerksp);CHKERRQ(ierr); 419 if (innerksp) { 420 ierr = KSPGetPC(innerksp,&pcinner);CHKERRQ(ierr); 421 /* Setup KSP and PC */ 422 if (nextDef) { /* next level for multilevel deflation */ 423 /* set default KSPtype */ 424 if (!def->ksptype) { 425 def->ksptype = KSPFGMRES; 426 if (flgspd) { /* SPD system */ 427 def->ksptype = KSPFCG; 428 } 429 } 430 ierr = KSPSetType(innerksp,def->ksptype);CHKERRQ(ierr); /* TODO iherit from KSP */ 431 ierr = PCSetType(pcinner,PCDEFLATION);CHKERRQ(ierr); /* TODO create coarse preconditinoner M_c = WtMW ? */ 432 ierr = PCDeflationSetSpace(pcinner,nextDef,transp);CHKERRQ(ierr); 433 ierr = PCDeflationSetLvl_Deflation(pcinner,def->nestedlvl+1,def->maxnestedlvl);CHKERRQ(ierr); 434 /* inherit options TODO if not set */ 435 ((PC_Deflation*)(pcinner))->ksptype = def->ksptype; 436 ((PC_Deflation*)(pcinner))->correct = def->correct; 437 ((PC_Deflation*)(pcinner))->adaptiveconv = def->adaptiveconv; 438 ((PC_Deflation*)(pcinner))->adaptiveconst = def->adaptiveconst; 439 ierr = MatDestroy(&nextDef);CHKERRQ(ierr); 440 } else { /* the last level */ 441 ierr = KSPSetType(innerksp,KSPGMRES);CHKERRQ(ierr); 442 /* TODO Cholesky if flgspd? */ 443 ierr = PCSetType(pcinner,PCLU);CHKERRQ(ierr); 444 //TODO remove explicit matSolverPackage 445 if (commsize == red) { 446 ierr = PCFactorSetMatSolverType(pcinner,MATSOLVERSUPERLU);CHKERRQ(ierr); 447 } else { 448 ierr = PCFactorSetMatSolverType(pcinner,MATSOLVERSUPERLU_DIST);CHKERRQ(ierr); 449 } 450 } 451 /* TODO use def_[lvl]_ if lvl > 0? */ 452 if (prefix) { 453 ierr = KSPSetOptionsPrefix(innerksp,prefix);CHKERRQ(ierr); 454 ierr = KSPAppendOptionsPrefix(innerksp,"def_");CHKERRQ(ierr); 455 } else { 456 ierr = KSPSetOptionsPrefix(innerksp,"def_");CHKERRQ(ierr); 457 } 458 } 459 /* TODO: check if WtAWinv is KSP and move following from this if */ 460 ierr = KSPSetFromOptions(def->WtAWinv);CHKERRQ(ierr); 461 //if (def->adaptiveconv) { 462 // PetscReal *rnorm; 463 // PetscNew(&rnorm); 464 // ierr = KSPSetConvergenceTest(def->WtAWinv,KSPDCGConvergedAdaptive_DCG,rnorm,NULL);CHKERRQ(ierr); 465 //} 466 ierr = KSPSetUp(def->WtAWinv);CHKERRQ(ierr); 467 } 468 469 /* create work vecs */ 470 ierr = MatCreateVecs(Amat,NULL,&def->work);CHKERRQ(ierr); 471 ierr = KSPCreateVecs(def->WtAWinv,2,&def->workcoarse,0,NULL);CHKERRQ(ierr); 472 PetscFunctionReturn(0); 473 } 474 /* -------------------------------------------------------------------------- */ 475 static PetscErrorCode PCReset_Deflation(PC pc) 476 { 477 PC_Deflation *jac = (PC_Deflation*)pc->data; 478 PetscErrorCode ierr; 479 480 PetscFunctionBegin; 481 PetscFunctionReturn(0); 482 } 483 484 /* 485 PCDestroy_Deflation - Destroys the private context for the Deflation preconditioner 486 that was created with PCCreate_Deflation(). 487 488 Input Parameter: 489 . pc - the preconditioner context 490 491 Application Interface Routine: PCDestroy() 492 */ 493 static PetscErrorCode PCDestroy_Deflation(PC pc) 494 { 495 PetscErrorCode ierr; 496 497 PetscFunctionBegin; 498 ierr = PCReset_Deflation(pc);CHKERRQ(ierr); 499 500 /* 501 Free the private data structure that was hanging off the PC 502 */ 503 ierr = PetscFree(pc->data);CHKERRQ(ierr); 504 PetscFunctionReturn(0); 505 } 506 507 static PetscErrorCode PCSetFromOptions_Deflation(PetscOptionItems *PetscOptionsObject,PC pc) 508 { 509 PC_Deflation *jac = (PC_Deflation*)pc->data; 510 PetscErrorCode ierr; 511 PetscBool flg; 512 PCDeflationType deflt,type; 513 514 PetscFunctionBegin; 515 ierr = PCDeflationGetType(pc,&deflt);CHKERRQ(ierr); 516 ierr = PetscOptionsHead(PetscOptionsObject,"Deflation options");CHKERRQ(ierr); 517 ierr = PetscOptionsEnum("-pc_jacobi_type","How to construct diagonal matrix","PCDeflationSetType",PCDeflationTypes,(PetscEnum)deflt,(PetscEnum*)&type,&flg);CHKERRQ(ierr); 518 if (flg) { 519 ierr = PCDeflationSetType(pc,type);CHKERRQ(ierr); 520 } 521 ierr = PetscOptionsTail();CHKERRQ(ierr); 522 PetscFunctionReturn(0); 523 } 524 525 /*MC 526 PCDEFLATION - Deflation preconditioner shifts part of the spectrum to zero (deflates) 527 or to a predefined value 528 529 Options Database Key: 530 + -pc_deflation_type <init,pre,post> - selects approach to deflation (default: pre) 531 - -pc_jacobi_abs - use the absolute value of the diagonal entry 532 533 Level: beginner 534 535 Notes: 536 todo 537 538 .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 539 PCDeflationSetType(), PCDeflationSetSpace() 540 M*/ 541 542 PETSC_EXTERN PetscErrorCode PCCreate_Deflation(PC pc) 543 { 544 PC_Deflation *def; 545 PetscErrorCode ierr; 546 547 PetscFunctionBegin; 548 ierr = PetscNewLog(pc,&def);CHKERRQ(ierr); 549 pc->data = (void*)def; 550 551 def->init = PETSC_FALSE; 552 def->pre = PETSC_TRUE; 553 def->correct = PETSC_FALSE; 554 def->truenorm = PETSC_TRUE; 555 def->reductionfact = -1; 556 def->spacetype = PC_DEFLATION_SPACE_HAAR; 557 def->spacesize = 1; 558 def->extendsp = PETSC_FALSE; 559 def->nestedlvl = 0; 560 def->maxnestedlvl = 0; 561 def->adaptiveconv = PETSC_FALSE; 562 def->adaptiveconst = 1.0; 563 564 /* 565 Set the pointers for the functions that are provided above. 566 Now when the user-level routines (such as PCApply(), PCDestroy(), etc.) 567 are called, they will automatically call these functions. Note we 568 choose not to provide a couple of these functions since they are 569 not needed. 570 */ 571 pc->ops->apply = PCApply_Deflation; 572 pc->ops->applytranspose = PCApply_Deflation; 573 pc->ops->presolve = PCPreSolve_Deflation; 574 pc->ops->postsolve = 0; 575 pc->ops->setup = PCSetUp_Deflation; 576 pc->ops->reset = PCReset_Deflation; 577 pc->ops->destroy = PCDestroy_Deflation; 578 pc->ops->setfromoptions = PCSetFromOptions_Deflation; 579 pc->ops->view = 0; 580 pc->ops->applyrichardson = 0; 581 pc->ops->applysymmetricleft = 0; 582 pc->ops->applysymmetricright = 0; 583 584 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetType_C",PCDeflationSetType_Deflation);CHKERRQ(ierr); 585 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationGetType_C",PCDeflationGetType_Deflation);CHKERRQ(ierr); 586 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetSpace_C",PCDeflationSetSpace_Deflation);CHKERRQ(ierr); 587 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetLvl_C",PCDeflationSetLvl_Deflation);CHKERRQ(ierr); 588 PetscFunctionReturn(0); 589 } 590 591