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