1292e2e67SJakub Kruzik #include <../src/ksp/pc/impls/deflation/deflation.h> /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 237eeb815SJakub Kruzik 38513960bSJakub Kruzik const char *const PCDeflationSpaceTypes[] = { 48513960bSJakub Kruzik "haar", 58513960bSJakub Kruzik "jacket-haar", 68513960bSJakub Kruzik "db2", 78513960bSJakub Kruzik "db4", 88513960bSJakub Kruzik "db8", 98513960bSJakub Kruzik "db16", 108513960bSJakub Kruzik "biorth22", 118513960bSJakub Kruzik "meyer", 128513960bSJakub Kruzik "aggregation", 138513960bSJakub Kruzik "slepc", 148513960bSJakub Kruzik "slepc-cheap", 158513960bSJakub Kruzik "user", 160a78af22SJakub Kruzik "PCDeflationSpaceType", 170a78af22SJakub Kruzik "PC_DEFLATION_SPACE_", 188513960bSJakub Kruzik 0 198513960bSJakub Kruzik }; 208513960bSJakub Kruzik 21a122ebaeSJakub Kruzik static PetscErrorCode PCDeflationSetInitOnly_Deflation(PC pc,PetscBool flg) 22a122ebaeSJakub Kruzik { 23a122ebaeSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 24a122ebaeSJakub Kruzik 25a122ebaeSJakub Kruzik PetscFunctionBegin; 26a122ebaeSJakub Kruzik def->init = flg; 27a122ebaeSJakub Kruzik PetscFunctionReturn(0); 28a122ebaeSJakub Kruzik } 29a122ebaeSJakub Kruzik 30a122ebaeSJakub Kruzik /*@ 31a122ebaeSJakub Kruzik PCDeflationSetInitOnly - Do only initialization step. 32*e26ad46dSJakub Kruzik Sets initial guess to the solution on the deflation space but does not apply 33*e26ad46dSJakub Kruzik the deflation preconditioner. The additional preconditioner is still applied. 34a122ebaeSJakub Kruzik 35*e26ad46dSJakub Kruzik Logically Collective 36a122ebaeSJakub Kruzik 37a122ebaeSJakub Kruzik Input Parameters: 38a122ebaeSJakub Kruzik + pc - the preconditioner context 39a122ebaeSJakub Kruzik - flg - default PETSC_FALSE 40a122ebaeSJakub Kruzik 41*e26ad46dSJakub Kruzik Options Database Keys: 42*e26ad46dSJakub Kruzik . -pc_deflation_init_only <false> - if true computes only the special guess 43*e26ad46dSJakub Kruzik 44a122ebaeSJakub Kruzik Level: intermediate 45a122ebaeSJakub Kruzik 46a122ebaeSJakub Kruzik .seealso: PCDEFLATION 47a122ebaeSJakub Kruzik @*/ 48a122ebaeSJakub Kruzik PetscErrorCode PCDeflationSetInitOnly(PC pc,PetscBool flg) 49a122ebaeSJakub Kruzik { 50a122ebaeSJakub Kruzik PetscErrorCode ierr; 51a122ebaeSJakub Kruzik 52a122ebaeSJakub Kruzik PetscFunctionBegin; 53a122ebaeSJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 54a122ebaeSJakub Kruzik PetscValidLogicalCollectiveBool(pc,flg,2); 55a122ebaeSJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetInitOnly_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr); 56a122ebaeSJakub Kruzik PetscFunctionReturn(0); 57a122ebaeSJakub Kruzik } 58a122ebaeSJakub Kruzik 59a122ebaeSJakub Kruzik 6098d6e3deSJakub Kruzik static PetscErrorCode PCDeflationSetLvl_Deflation(PC pc,PetscInt current,PetscInt max) 6198d6e3deSJakub Kruzik { 6298d6e3deSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 6398d6e3deSJakub Kruzik 6498d6e3deSJakub Kruzik PetscFunctionBegin; 6598d6e3deSJakub Kruzik if (current) def->nestedlvl = current; 6698d6e3deSJakub Kruzik def->maxnestedlvl = max; 6798d6e3deSJakub Kruzik PetscFunctionReturn(0); 6898d6e3deSJakub Kruzik } 6998d6e3deSJakub Kruzik 7098d6e3deSJakub Kruzik /*@ 71*e26ad46dSJakub Kruzik PCDeflationSetMaxLvl - Set the maximum level of deflation nesting. 7298d6e3deSJakub Kruzik 73*e26ad46dSJakub Kruzik Logically Collective 7498d6e3deSJakub Kruzik 7598d6e3deSJakub Kruzik Input Parameters: 7698d6e3deSJakub Kruzik + pc - the preconditioner context 7798d6e3deSJakub Kruzik - max - maximum deflation level 7898d6e3deSJakub Kruzik 79*e26ad46dSJakub Kruzik Options Database Keys: 80*e26ad46dSJakub Kruzik . -pc_deflation_max_lvl <0> - maximum number of levels for multilevel deflation 81*e26ad46dSJakub Kruzik 8298d6e3deSJakub Kruzik Level: intermediate 8398d6e3deSJakub Kruzik 84*e26ad46dSJakub Kruzik .seealso: PCDeflationSetSpaceToCompute(), PCDeflationSetSpace(), PCDEFLATION 8598d6e3deSJakub Kruzik @*/ 8698d6e3deSJakub Kruzik PetscErrorCode PCDeflationSetMaxLvl(PC pc,PetscInt max) 8798d6e3deSJakub Kruzik { 8898d6e3deSJakub Kruzik PetscErrorCode ierr; 8998d6e3deSJakub Kruzik 9098d6e3deSJakub Kruzik PetscFunctionBegin; 9198d6e3deSJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 9298d6e3deSJakub Kruzik PetscValidLogicalCollectiveInt(pc,max,2); 9398d6e3deSJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetLvl_C",(PC,PetscInt,PetscInt),(pc,0,max));CHKERRQ(ierr); 9498d6e3deSJakub Kruzik PetscFunctionReturn(0); 9598d6e3deSJakub Kruzik } 9698d6e3deSJakub Kruzik 97859a873cSJakub Kruzik static PetscErrorCode PCDeflationSetReductionFactor_Deflation(PC pc,PetscInt red) 98859a873cSJakub Kruzik { 99859a873cSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 100859a873cSJakub Kruzik 101859a873cSJakub Kruzik PetscFunctionBegin; 102859a873cSJakub Kruzik def->reductionfact = red; 103859a873cSJakub Kruzik PetscFunctionReturn(0); 104859a873cSJakub Kruzik } 105859a873cSJakub Kruzik 106859a873cSJakub Kruzik /*@ 107*e26ad46dSJakub Kruzik PCDeflationSetReductionFactor - Set reduction factor for the bottom PCTELESCOPE coarse problem solver. 108859a873cSJakub Kruzik 109*e26ad46dSJakub Kruzik Logically Collective 110859a873cSJakub Kruzik 111859a873cSJakub Kruzik Input Parameters: 112859a873cSJakub Kruzik + pc - the preconditioner context 113859a873cSJakub Kruzik - red - reduction factor (or PETSC_DETERMINE) 114859a873cSJakub Kruzik 115*e26ad46dSJakub Kruzik Options Database Keys: 116*e26ad46dSJakub Kruzik . -pc_deflation_reduction_factor <-1> - reduction factor on bottom level coarse problem for PCTELESCOPE 117*e26ad46dSJakub Kruzik 118*e26ad46dSJakub Kruzik Notes: 119*e26ad46dSJakub Kruzik Default is computed based on the size of the coarse problem. 120*e26ad46dSJakub Kruzik 121859a873cSJakub Kruzik Level: intermediate 122859a873cSJakub Kruzik 123*e26ad46dSJakub Kruzik .seealso: PCTELESCOPE, PCDEFLATION 124859a873cSJakub Kruzik @*/ 125859a873cSJakub Kruzik PetscErrorCode PCDeflationSetReductionFactor(PC pc,PetscInt red) 126859a873cSJakub Kruzik { 127859a873cSJakub Kruzik PetscErrorCode ierr; 128859a873cSJakub Kruzik 129859a873cSJakub Kruzik PetscFunctionBegin; 130859a873cSJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 131859a873cSJakub Kruzik PetscValidLogicalCollectiveInt(pc,red,2); 132859a873cSJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetReductionFactor_C",(PC,PetscInt),(pc,red));CHKERRQ(ierr); 133859a873cSJakub Kruzik PetscFunctionReturn(0); 134859a873cSJakub Kruzik } 135859a873cSJakub Kruzik 1368a71cb68SJakub Kruzik static PetscErrorCode PCDeflationSetCorrectionFactor_Deflation(PC pc,PetscScalar fact) 1378a71cb68SJakub Kruzik { 1388a71cb68SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 1398a71cb68SJakub Kruzik 1408a71cb68SJakub Kruzik PetscFunctionBegin; 1418a71cb68SJakub Kruzik /* TODO PETSC_DETERMINE -> compute max eigenvalue with power method */ 1428a71cb68SJakub Kruzik def->correct = PETSC_TRUE; 1438a71cb68SJakub Kruzik def->correctfact = fact; 144*e26ad46dSJakub Kruzik if (def->correct == 0.0) { 1458a71cb68SJakub Kruzik def->correct = PETSC_FALSE; 1468a71cb68SJakub Kruzik } 1478a71cb68SJakub Kruzik PetscFunctionReturn(0); 1488a71cb68SJakub Kruzik } 1498a71cb68SJakub Kruzik 1508a71cb68SJakub Kruzik /*@ 1518a71cb68SJakub Kruzik PCDeflationSetCorrectionFactor - Set coarse problem correction factor. 152*e26ad46dSJakub Kruzik The Preconditioner becomes P*M^{-1} + fact*Q. 1538a71cb68SJakub Kruzik 154*e26ad46dSJakub Kruzik Logically Collective 1558a71cb68SJakub Kruzik 1568a71cb68SJakub Kruzik Input Parameters: 1578a71cb68SJakub Kruzik + pc - the preconditioner context 158*e26ad46dSJakub Kruzik - fact - correction factor 159*e26ad46dSJakub Kruzik 160*e26ad46dSJakub Kruzik Options Database Keys: 161*e26ad46dSJakub Kruzik + -pc_deflation_correction <false> - if true apply coarse problem correction 162*e26ad46dSJakub Kruzik - -pc_deflation_correction_factor <1.0> - sets coarse problem correction factor 163*e26ad46dSJakub Kruzik 164*e26ad46dSJakub Kruzik Notes: 165*e26ad46dSJakub Kruzik Any non-zero fact enables the coarse problem correction. 1668a71cb68SJakub Kruzik 1678a71cb68SJakub Kruzik Level: intermediate 1688a71cb68SJakub Kruzik 1698a71cb68SJakub Kruzik .seealso: PCDEFLATION 1708a71cb68SJakub Kruzik @*/ 1718a71cb68SJakub Kruzik PetscErrorCode PCDeflationSetCorrectionFactor(PC pc,PetscScalar fact) 1728a71cb68SJakub Kruzik { 1738a71cb68SJakub Kruzik PetscErrorCode ierr; 1748a71cb68SJakub Kruzik 1758a71cb68SJakub Kruzik PetscFunctionBegin; 1768a71cb68SJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1778a71cb68SJakub Kruzik PetscValidLogicalCollectiveScalar(pc,fact,2); 1788a71cb68SJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetCorrectionFactor_C",(PC,PetscScalar),(pc,fact));CHKERRQ(ierr); 1798a71cb68SJakub Kruzik PetscFunctionReturn(0); 1808a71cb68SJakub Kruzik } 1818a71cb68SJakub Kruzik 18239417d7eSJakub Kruzik static PetscErrorCode PCDeflationSetSpaceToCompute_Deflation(PC pc,PCDeflationSpaceType type,PetscInt size) 18339417d7eSJakub Kruzik { 18439417d7eSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 18539417d7eSJakub Kruzik 18639417d7eSJakub Kruzik PetscFunctionBegin; 18739417d7eSJakub Kruzik if (type) def->spacetype = type; 18839417d7eSJakub Kruzik if (size > 0) def->spacesize = size; 18939417d7eSJakub Kruzik PetscFunctionReturn(0); 19039417d7eSJakub Kruzik } 19139417d7eSJakub Kruzik 19239417d7eSJakub Kruzik /*@ 19339417d7eSJakub Kruzik PCDeflationSetSpaceToCompute - Set deflation space type and size to compute. 19439417d7eSJakub Kruzik 195*e26ad46dSJakub Kruzik Logically Collective 19639417d7eSJakub Kruzik 19739417d7eSJakub Kruzik Input Parameters: 19839417d7eSJakub Kruzik + pc - the preconditioner context 19939417d7eSJakub Kruzik . type - deflation space type to compute (or PETSC_IGNORE) 20039417d7eSJakub Kruzik - size - size of the space to compute (or PETSC_DEFAULT) 20139417d7eSJakub Kruzik 202*e26ad46dSJakub Kruzik Options Database Keys: 203*e26ad46dSJakub Kruzik + -pc_deflation_compute_space <haar> - compute PCDeflationSpaceType deflation space 204*e26ad46dSJakub Kruzik - -pc_deflation_compute_space_size <1> - size of the deflation space 205*e26ad46dSJakub Kruzik 20639417d7eSJakub Kruzik Notes: 20739417d7eSJakub Kruzik For wavelet-based deflation, size represents number of levels. 208*e26ad46dSJakub Kruzik 20939417d7eSJakub Kruzik The deflation space is computed in PCSetUP(). 21039417d7eSJakub Kruzik 21139417d7eSJakub Kruzik Level: intermediate 21239417d7eSJakub Kruzik 213*e26ad46dSJakub Kruzik .seealso: PCDeflationSetMaxLvl(), PCDEFLATION 21439417d7eSJakub Kruzik @*/ 21539417d7eSJakub Kruzik PetscErrorCode PCDeflationSetSpaceToCompute(PC pc,PCDeflationSpaceType type,PetscInt size) 21639417d7eSJakub Kruzik { 21739417d7eSJakub Kruzik PetscErrorCode ierr; 21839417d7eSJakub Kruzik 21939417d7eSJakub Kruzik PetscFunctionBegin; 22039417d7eSJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 22139417d7eSJakub Kruzik if (type) PetscValidLogicalCollectiveEnum(pc,type,2); 22239417d7eSJakub Kruzik if (size > 0) PetscValidLogicalCollectiveInt(pc,size,3); 22339417d7eSJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetSpaceToCompute_C",(PC,PCDeflationSpaceType,PetscInt),(pc,type,size));CHKERRQ(ierr); 22439417d7eSJakub Kruzik PetscFunctionReturn(0); 22539417d7eSJakub Kruzik } 2268513960bSJakub Kruzik 227e662bc50SJakub Kruzik static PetscErrorCode PCDeflationSetSpace_Deflation(PC pc,Mat W,PetscBool transpose) 228e662bc50SJakub Kruzik { 229e662bc50SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 230e662bc50SJakub Kruzik PetscErrorCode ierr; 231e662bc50SJakub Kruzik 232e662bc50SJakub Kruzik PetscFunctionBegin; 233e662bc50SJakub Kruzik if (transpose) { 234e662bc50SJakub Kruzik def->Wt = W; 235e662bc50SJakub Kruzik def->W = NULL; 236e662bc50SJakub Kruzik } else { 237e662bc50SJakub Kruzik def->W = W; 238e662bc50SJakub Kruzik } 239e662bc50SJakub Kruzik ierr = PetscObjectReference((PetscObject)W);CHKERRQ(ierr); 240e662bc50SJakub Kruzik PetscFunctionReturn(0); 241e662bc50SJakub Kruzik } 242e662bc50SJakub Kruzik 243e662bc50SJakub Kruzik /*@ 244*e26ad46dSJakub Kruzik PCDeflationSetSpace - Set the deflation space matrix (or its (hermitian) transpose). 245e662bc50SJakub Kruzik 246*e26ad46dSJakub Kruzik Logically Collective 247e662bc50SJakub Kruzik 248e662bc50SJakub Kruzik Input Parameters: 249e662bc50SJakub Kruzik + pc - the preconditioner context 250e662bc50SJakub Kruzik . W - deflation matrix 251*e26ad46dSJakub Kruzik - transpose - indicates that W is an explicit transpose of the deflation matrix 252*e26ad46dSJakub Kruzik 253*e26ad46dSJakub Kruzik Notes: 254*e26ad46dSJakub Kruzik Setting W as a multipliplicative MATCOMPOSITE enables use of the multilevel 255*e26ad46dSJakub Kruzik deflation. If W = W0*W1*W2*...*Wn, W0 is taken as the first deflation space and 256*e26ad46dSJakub Kruzik the coarse problem (W0'*A*W0)^{-1} is again preconditioned by deflation with 257*e26ad46dSJakub Kruzik W1 as the deflation matrix. This repeats until the maximum level set by 258*e26ad46dSJakub Kruzik PCDeflationSetMaxLvl is reached or there are no more matrices available. 259*e26ad46dSJakub Kruzik If there are matrices left after reaching the maximum level, 260*e26ad46dSJakub Kruzik they are merged into a deflation matrix ...*W{n-1}*Wn. 261e662bc50SJakub Kruzik 262e662bc50SJakub Kruzik Level: intermediate 263e662bc50SJakub Kruzik 264*e26ad46dSJakub Kruzik .seealso: PCDeflationSetMaxLvl(), PCDEFLATION 265e662bc50SJakub Kruzik @*/ 266e662bc50SJakub Kruzik PetscErrorCode PCDeflationSetSpace(PC pc,Mat W,PetscBool transpose) 267e662bc50SJakub Kruzik { 268e662bc50SJakub Kruzik PetscErrorCode ierr; 269e662bc50SJakub Kruzik 270e662bc50SJakub Kruzik PetscFunctionBegin; 271e662bc50SJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 272e662bc50SJakub Kruzik PetscValidHeaderSpecific(W,MAT_CLASSID,2); 273e662bc50SJakub Kruzik PetscValidLogicalCollectiveBool(pc,transpose,3); 274e662bc50SJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetSpace_C",(PC,Mat,PetscBool),(pc,W,transpose));CHKERRQ(ierr); 275e662bc50SJakub Kruzik PetscFunctionReturn(0); 276e662bc50SJakub Kruzik } 277e662bc50SJakub Kruzik 2783cf3a049SJakub Kruzik static PetscErrorCode PCDeflationSetProjectionNullSpaceMat_Deflation(PC pc,Mat mat) 2793cf3a049SJakub Kruzik { 2803cf3a049SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 2813cf3a049SJakub Kruzik PetscErrorCode ierr; 2823cf3a049SJakub Kruzik 2833cf3a049SJakub Kruzik PetscFunctionBegin; 2843cf3a049SJakub Kruzik ierr = MatDestroy(&def->WtA);CHKERRQ(ierr); 2853cf3a049SJakub Kruzik def->WtA = mat; 2863cf3a049SJakub Kruzik ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 2873cf3a049SJakub Kruzik ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)def->WtA);CHKERRQ(ierr); 2883cf3a049SJakub Kruzik PetscFunctionReturn(0); 2893cf3a049SJakub Kruzik } 2903cf3a049SJakub Kruzik 2913cf3a049SJakub Kruzik /*@ 292*e26ad46dSJakub Kruzik PCDeflationSetProjectionNullSpaceMat - Set the projection null space matrix (W'*A). 2933cf3a049SJakub Kruzik 294*e26ad46dSJakub Kruzik Collective 2953cf3a049SJakub Kruzik 2963cf3a049SJakub Kruzik Input Parameters: 2973cf3a049SJakub Kruzik + pc - preconditioner context 2983cf3a049SJakub Kruzik - mat - projection null space matrix 2993cf3a049SJakub Kruzik 3003cf3a049SJakub Kruzik Level: developer 3013cf3a049SJakub Kruzik 3023cf3a049SJakub Kruzik .seealso: PCDEFLATION 3033cf3a049SJakub Kruzik @*/ 3043cf3a049SJakub Kruzik PetscErrorCode PCDeflationSetProjectionNullSpaceMat(PC pc,Mat mat) 3053cf3a049SJakub Kruzik { 3063cf3a049SJakub Kruzik PetscErrorCode ierr; 3073cf3a049SJakub Kruzik 3083cf3a049SJakub Kruzik PetscFunctionBegin; 3093cf3a049SJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 3103cf3a049SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3113cf3a049SJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetProjectionNullSpaceMat_C",(PC,Mat),(pc,mat));CHKERRQ(ierr); 3123cf3a049SJakub Kruzik PetscFunctionReturn(0); 3133cf3a049SJakub Kruzik } 3143cf3a049SJakub Kruzik 315e924b002SJakub Kruzik static PetscErrorCode PCDeflationSetCoarseMat_Deflation(PC pc,Mat mat) 316e924b002SJakub Kruzik { 317e924b002SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 318e924b002SJakub Kruzik PetscErrorCode ierr; 319e924b002SJakub Kruzik 320e924b002SJakub Kruzik PetscFunctionBegin; 321e924b002SJakub Kruzik ierr = MatDestroy(&def->WtAW);CHKERRQ(ierr); 322e924b002SJakub Kruzik def->WtAW = mat; 323e924b002SJakub Kruzik ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 324e924b002SJakub Kruzik ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)def->WtAW);CHKERRQ(ierr); 325e924b002SJakub Kruzik PetscFunctionReturn(0); 326e924b002SJakub Kruzik } 327e924b002SJakub Kruzik 328e924b002SJakub Kruzik /*@ 329*e26ad46dSJakub Kruzik PCDeflationSetCoarseMat - Set the coarse problem Mat. 330e924b002SJakub Kruzik 331*e26ad46dSJakub Kruzik Collective 332e924b002SJakub Kruzik 333e924b002SJakub Kruzik Input Parameters: 334e924b002SJakub Kruzik + pc - preconditioner context 335e924b002SJakub Kruzik - mat - coarse problem mat 336e924b002SJakub Kruzik 337e924b002SJakub Kruzik Level: developer 338e924b002SJakub Kruzik 339e924b002SJakub Kruzik .seealso: PCDEFLATION 340e924b002SJakub Kruzik @*/ 341e924b002SJakub Kruzik PetscErrorCode PCDeflationSetCoarseMat(PC pc,Mat mat) 342e924b002SJakub Kruzik { 343e924b002SJakub Kruzik PetscErrorCode ierr; 344e924b002SJakub Kruzik 345e924b002SJakub Kruzik PetscFunctionBegin; 346e924b002SJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 347e924b002SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 348e924b002SJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetCoarseMat_C",(PC,Mat),(pc,mat));CHKERRQ(ierr); 349e924b002SJakub Kruzik PetscFunctionReturn(0); 350e924b002SJakub Kruzik } 351e924b002SJakub Kruzik 35298d6e3deSJakub Kruzik static PetscErrorCode PCDeflationGetCoarseKSP_Deflation(PC pc,KSP *ksp) 3535c0c31c5SJakub Kruzik { 3545c0c31c5SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 3555c0c31c5SJakub Kruzik 3565c0c31c5SJakub Kruzik PetscFunctionBegin; 35798d6e3deSJakub Kruzik *ksp = def->WtAWinv; 3585c0c31c5SJakub Kruzik PetscFunctionReturn(0); 3595c0c31c5SJakub Kruzik } 3605c0c31c5SJakub Kruzik 3615c0c31c5SJakub Kruzik /*@ 36298d6e3deSJakub Kruzik PCDeflationGetCoarseKSP - Returns a pointer to the coarse problem KSP. 3635c0c31c5SJakub Kruzik 36498d6e3deSJakub Kruzik Not Collective 3655c0c31c5SJakub Kruzik 3665c0c31c5SJakub Kruzik Input Parameters: 36798d6e3deSJakub Kruzik . pc - preconditioner context 3685c0c31c5SJakub Kruzik 369*e26ad46dSJakub Kruzik Output Parameters: 37098d6e3deSJakub Kruzik . ksp - coarse problem KSP context 3715c0c31c5SJakub Kruzik 372*e26ad46dSJakub Kruzik Level: advanced 37398d6e3deSJakub Kruzik 37498d6e3deSJakub Kruzik .seealso: PCDeflationSetCoarseKSP(), PCDEFLATION 3755c0c31c5SJakub Kruzik @*/ 37698d6e3deSJakub Kruzik PetscErrorCode PCDeflationGetCoarseKSP(PC pc,KSP *ksp) 3775c0c31c5SJakub Kruzik { 3785c0c31c5SJakub Kruzik PetscErrorCode ierr; 3795c0c31c5SJakub Kruzik 3805c0c31c5SJakub Kruzik PetscFunctionBegin; 38122b0793eSJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 38298d6e3deSJakub Kruzik PetscValidPointer(ksp,2); 38398d6e3deSJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationGetCoarseKSP_C",(PC,KSP*),(pc,ksp));CHKERRQ(ierr); 38498d6e3deSJakub Kruzik PetscFunctionReturn(0); 38598d6e3deSJakub Kruzik } 38698d6e3deSJakub Kruzik 38798d6e3deSJakub Kruzik static PetscErrorCode PCDeflationSetCoarseKSP_Deflation(PC pc,KSP ksp) 38898d6e3deSJakub Kruzik { 38998d6e3deSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 39098d6e3deSJakub Kruzik PetscErrorCode ierr; 39198d6e3deSJakub Kruzik 39298d6e3deSJakub Kruzik PetscFunctionBegin; 39398d6e3deSJakub Kruzik ierr = KSPDestroy(&def->WtAWinv);CHKERRQ(ierr); 39498d6e3deSJakub Kruzik def->WtAWinv = ksp; 39598d6e3deSJakub Kruzik ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 39698d6e3deSJakub Kruzik ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)def->WtAWinv);CHKERRQ(ierr); 39798d6e3deSJakub Kruzik PetscFunctionReturn(0); 39898d6e3deSJakub Kruzik } 39998d6e3deSJakub Kruzik 40098d6e3deSJakub Kruzik /*@ 401*e26ad46dSJakub Kruzik PCDeflationSetCoarseKSP - Set the coarse problem KSP. 40298d6e3deSJakub Kruzik 403*e26ad46dSJakub Kruzik Collective 40498d6e3deSJakub Kruzik 40598d6e3deSJakub Kruzik Input Parameters: 40698d6e3deSJakub Kruzik + pc - preconditioner context 40798d6e3deSJakub Kruzik - ksp - coarse problem KSP context 40898d6e3deSJakub Kruzik 40998d6e3deSJakub Kruzik Level: developer 41098d6e3deSJakub Kruzik 41198d6e3deSJakub Kruzik .seealso: PCDeflationGetCoarseKSP(), PCDEFLATION 41298d6e3deSJakub Kruzik @*/ 41398d6e3deSJakub Kruzik PetscErrorCode PCDeflationSetCoarseKSP(PC pc,KSP ksp) 41498d6e3deSJakub Kruzik { 41598d6e3deSJakub Kruzik PetscErrorCode ierr; 41698d6e3deSJakub Kruzik 41798d6e3deSJakub Kruzik PetscFunctionBegin; 41898d6e3deSJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 41998d6e3deSJakub Kruzik PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 42098d6e3deSJakub Kruzik PetscCheckSameComm(pc,1,ksp,2); 42198d6e3deSJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetCoarseKSP_C",(PC,KSP),(pc,ksp));CHKERRQ(ierr); 4225c0c31c5SJakub Kruzik PetscFunctionReturn(0); 4235c0c31c5SJakub Kruzik } 424e662bc50SJakub Kruzik 425268c6673SJakub Kruzik static PetscErrorCode PCDeflationGetPC_Deflation(PC pc,PC *apc) 426268c6673SJakub Kruzik { 427268c6673SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 428268c6673SJakub Kruzik 429268c6673SJakub Kruzik PetscFunctionBegin; 430268c6673SJakub Kruzik *apc = def->pc; 431268c6673SJakub Kruzik PetscFunctionReturn(0); 432268c6673SJakub Kruzik } 433268c6673SJakub Kruzik 434268c6673SJakub Kruzik /*@ 435*e26ad46dSJakub Kruzik PCDeflationGetPC - Returns a pointer to the additional preconditioner. 436268c6673SJakub Kruzik 437268c6673SJakub Kruzik Not Collective 438268c6673SJakub Kruzik 439268c6673SJakub Kruzik Input Parameters: 440268c6673SJakub Kruzik . pc - the preconditioner context 441268c6673SJakub Kruzik 442*e26ad46dSJakub Kruzik Output Parameters: 443268c6673SJakub Kruzik . apc - additional preconditioner 444268c6673SJakub Kruzik 445268c6673SJakub Kruzik Level: advanced 446268c6673SJakub Kruzik 447268c6673SJakub Kruzik .seealso: PCDeflationSetPC(), PCDEFLATION 448268c6673SJakub Kruzik @*/ 449268c6673SJakub Kruzik PetscErrorCode PCDeflationGetPC(PC pc,PC *apc) 450268c6673SJakub Kruzik { 451268c6673SJakub Kruzik PetscErrorCode ierr; 452268c6673SJakub Kruzik 453268c6673SJakub Kruzik PetscFunctionBegin; 454268c6673SJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 455268c6673SJakub Kruzik PetscValidPointer(pc,2); 456268c6673SJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationGetPC_C",(PC,PC*),(pc,apc));CHKERRQ(ierr); 457268c6673SJakub Kruzik PetscFunctionReturn(0); 458268c6673SJakub Kruzik } 459268c6673SJakub Kruzik 46022b0793eSJakub Kruzik static PetscErrorCode PCDeflationSetPC_Deflation(PC pc,PC apc) 46122b0793eSJakub Kruzik { 46222b0793eSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 46322b0793eSJakub Kruzik PetscErrorCode ierr; 46422b0793eSJakub Kruzik 46522b0793eSJakub Kruzik PetscFunctionBegin; 46622b0793eSJakub Kruzik ierr = PCDestroy(&def->pc);CHKERRQ(ierr); 46722b0793eSJakub Kruzik def->pc = apc; 46822b0793eSJakub Kruzik ierr = PetscObjectReference((PetscObject)apc);CHKERRQ(ierr); 46922b0793eSJakub Kruzik ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)def->pc);CHKERRQ(ierr); 47022b0793eSJakub Kruzik PetscFunctionReturn(0); 47122b0793eSJakub Kruzik } 47222b0793eSJakub Kruzik 47322b0793eSJakub Kruzik /*@ 474*e26ad46dSJakub Kruzik PCDeflationSetPC - Set the additional preconditioner. 47522b0793eSJakub Kruzik 476*e26ad46dSJakub Kruzik Collective 47722b0793eSJakub Kruzik 47822b0793eSJakub Kruzik Input Parameters: 47922b0793eSJakub Kruzik + pc - the preconditioner context 48022b0793eSJakub Kruzik - apc - additional preconditioner 48122b0793eSJakub Kruzik 482268c6673SJakub Kruzik Level: developer 48322b0793eSJakub Kruzik 484268c6673SJakub Kruzik .seealso: PCDeflationGetPC(), PCDEFLATION 48522b0793eSJakub Kruzik @*/ 48622b0793eSJakub Kruzik PetscErrorCode PCDeflationSetPC(PC pc,PC apc) 48722b0793eSJakub Kruzik { 48822b0793eSJakub Kruzik PetscErrorCode ierr; 48922b0793eSJakub Kruzik 49022b0793eSJakub Kruzik PetscFunctionBegin; 49122b0793eSJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 49222b0793eSJakub Kruzik PetscValidHeaderSpecific(apc,PC_CLASSID,2); 49322b0793eSJakub Kruzik PetscCheckSameComm(pc,1,apc,2); 49422b0793eSJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetPC_C",(PC,PC),(pc,apc));CHKERRQ(ierr); 49522b0793eSJakub Kruzik PetscFunctionReturn(0); 49622b0793eSJakub Kruzik } 49722b0793eSJakub Kruzik 49837eeb815SJakub Kruzik /* 499b27c8092SJakub Kruzik x <- x + W*(W'*A*W)^{-1}*W'*r = x + Q*r 500b27c8092SJakub Kruzik */ 501b27c8092SJakub Kruzik static PetscErrorCode PCPreSolve_Deflation(PC pc,KSP ksp,Vec b, Vec x) 502b27c8092SJakub Kruzik { 503b27c8092SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 504b27c8092SJakub Kruzik Mat A; 505b27c8092SJakub Kruzik Vec r,w1,w2; 506b27c8092SJakub Kruzik PetscBool nonzero; 507b27c8092SJakub Kruzik PetscErrorCode ierr; 50837eeb815SJakub Kruzik 509b27c8092SJakub Kruzik PetscFunctionBegin; 510b27c8092SJakub Kruzik w1 = def->workcoarse[0]; 511b27c8092SJakub Kruzik w2 = def->workcoarse[1]; 512b27c8092SJakub Kruzik r = def->work; 513b27c8092SJakub Kruzik ierr = PCGetOperators(pc,NULL,&A);CHKERRQ(ierr); 51437eeb815SJakub Kruzik 515b27c8092SJakub Kruzik ierr = KSPGetInitialGuessNonzero(ksp,&nonzero);CHKERRQ(ierr); 516b27c8092SJakub Kruzik ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 517b27c8092SJakub Kruzik if (nonzero) { 518b27c8092SJakub Kruzik ierr = MatMult(A,x,r);CHKERRQ(ierr); /* r <- b - Ax */ 519b27c8092SJakub Kruzik ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 520b27c8092SJakub Kruzik } else { 521b27c8092SJakub Kruzik ierr = VecCopy(b,r);CHKERRQ(ierr); /* r <- b (x is 0) */ 522b27c8092SJakub Kruzik } 523b27c8092SJakub Kruzik 524a3177931SJakub Kruzik if (def->Wt) { 525a3177931SJakub Kruzik ierr = MatMult(def->Wt,r,w1);CHKERRQ(ierr); /* w1 <- W'*r */ 526a3177931SJakub Kruzik } else { 527a3177931SJakub Kruzik ierr = MatMultHermitianTranspose(def->W,r,w1);CHKERRQ(ierr); /* w1 <- W'*r */ 528a3177931SJakub Kruzik } 529b27c8092SJakub Kruzik ierr = KSPSolve(def->WtAWinv,w1,w2);CHKERRQ(ierr); /* w2 <- (W'*A*W)^{-1}*w1 */ 530b27c8092SJakub Kruzik ierr = MatMult(def->W,w2,r);CHKERRQ(ierr); /* r <- W*w2 */ 531b27c8092SJakub Kruzik ierr = VecAYPX(x,1.0,r);CHKERRQ(ierr); 532b27c8092SJakub Kruzik PetscFunctionReturn(0); 533b27c8092SJakub Kruzik } 53437eeb815SJakub Kruzik 535f8bf229cSJakub Kruzik /* 536f8bf229cSJakub Kruzik if (def->correct) { 537ae029463SJakub Kruzik z <- M^{-1}r - W*(W'*A*W)^{-1}*(W'*A*M^{-1}r - l*W'*r) = (P*M^{-1} + l*Q)*r 538f8bf229cSJakub Kruzik } else { 539ae029463SJakub Kruzik z <- M^{-1}*r - W*(W'*A*W)^{-1}*W'*A*M{-1}*r = P*M^{-1}*r 540f8bf229cSJakub Kruzik } 54137eeb815SJakub Kruzik */ 542f8bf229cSJakub Kruzik static PetscErrorCode PCApply_Deflation(PC pc,Vec r,Vec z) 543f8bf229cSJakub Kruzik { 544f8bf229cSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 545f8bf229cSJakub Kruzik Mat A; 546f8bf229cSJakub Kruzik Vec u,w1,w2; 547f8bf229cSJakub Kruzik PetscErrorCode ierr; 548f8bf229cSJakub Kruzik 549f8bf229cSJakub Kruzik PetscFunctionBegin; 550f8bf229cSJakub Kruzik w1 = def->workcoarse[0]; 551f8bf229cSJakub Kruzik w2 = def->workcoarse[1]; 552f8bf229cSJakub Kruzik u = def->work; 553f8bf229cSJakub Kruzik ierr = PCGetOperators(pc,NULL,&A);CHKERRQ(ierr); 554f8bf229cSJakub Kruzik 555ae029463SJakub Kruzik ierr = PCApply(def->pc,r,z);CHKERRQ(ierr); /* z <- M^{-1}*r */ 55622b0793eSJakub Kruzik if (!def->init) { 557ae029463SJakub Kruzik ierr = MatMult(def->WtA,z,w1);CHKERRQ(ierr); /* w1 <- W'*A*z */ 558f8bf229cSJakub Kruzik if (def->correct) { 559ae029463SJakub Kruzik if (def->Wt) { 560ae029463SJakub Kruzik ierr = MatMult(def->Wt,r,w2);CHKERRQ(ierr); /* w2 <- W'*r */ 561ae029463SJakub Kruzik } else { 562a3177931SJakub Kruzik ierr = MatMultHermitianTranspose(def->W,r,w2);CHKERRQ(ierr); /* w2 <- W'*r */ 563f8bf229cSJakub Kruzik } 564ae029463SJakub Kruzik ierr = VecAXPY(w1,-1.0*def->correctfact,w2);CHKERRQ(ierr); /* w1 <- w1 - l*w2 */ 565f8bf229cSJakub Kruzik } 566f8bf229cSJakub Kruzik ierr = KSPSolve(def->WtAWinv,w1,w2);CHKERRQ(ierr); /* w2 <- (W'*A*W)^{-1}*w1 */ 567f8bf229cSJakub Kruzik ierr = MatMult(def->W,w2,u);CHKERRQ(ierr); /* u <- W*w2 */ 56822b0793eSJakub Kruzik ierr = VecAXPY(z,-1.0,u);CHKERRQ(ierr); /* z <- z - u */ 56922b0793eSJakub Kruzik } 570f8bf229cSJakub Kruzik PetscFunctionReturn(0); 571f8bf229cSJakub Kruzik } 572f8bf229cSJakub Kruzik 57337eeb815SJakub Kruzik static PetscErrorCode PCSetUp_Deflation(PC pc) 57437eeb815SJakub Kruzik { 575409a357bSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 576409a357bSJakub Kruzik KSP innerksp; 577409a357bSJakub Kruzik PC pcinner; 578409a357bSJakub Kruzik Mat Amat,nextDef=NULL,*mats; 579409a357bSJakub Kruzik PetscInt i,m,red,size,commsize; 580409a357bSJakub Kruzik PetscBool match,flgspd,transp=PETSC_FALSE; 581409a357bSJakub Kruzik MatCompositeType ctype; 582409a357bSJakub Kruzik MPI_Comm comm; 583409a357bSJakub Kruzik const char *prefix; 58437eeb815SJakub Kruzik PetscErrorCode ierr; 58537eeb815SJakub Kruzik 58637eeb815SJakub Kruzik PetscFunctionBegin; 587409a357bSJakub Kruzik if (pc->setupcalled) PetscFunctionReturn(0); 588409a357bSJakub Kruzik ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 589f8bf229cSJakub Kruzik ierr = PCGetOperators(pc,NULL,&Amat);CHKERRQ(ierr); 5900a78af22SJakub Kruzik ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr); 591f8bf229cSJakub Kruzik 592f8bf229cSJakub Kruzik /* compute a deflation space */ 593409a357bSJakub Kruzik if (def->W || def->Wt) { 594409a357bSJakub Kruzik def->spacetype = PC_DEFLATION_SPACE_USER; 595409a357bSJakub Kruzik } else { 596e53e0a0dSJakub Kruzik ierr = PCDeflationComputeSpace(pc);CHKERRQ(ierr); 59737eeb815SJakub Kruzik } 59837eeb815SJakub Kruzik 599409a357bSJakub Kruzik /* nested deflation */ 600409a357bSJakub Kruzik if (def->W) { 601409a357bSJakub Kruzik ierr = PetscObjectTypeCompare((PetscObject)def->W,MATCOMPOSITE,&match);CHKERRQ(ierr); 602409a357bSJakub Kruzik if (match) { 603409a357bSJakub Kruzik ierr = MatCompositeGetType(def->W,&ctype);CHKERRQ(ierr); 604409a357bSJakub Kruzik ierr = MatCompositeGetNumberMat(def->W,&size);CHKERRQ(ierr); 60537eeb815SJakub Kruzik } 606409a357bSJakub Kruzik } else { 607a3177931SJakub Kruzik ierr = MatCreateHermitianTranspose(def->Wt,&def->W);CHKERRQ(ierr); 608409a357bSJakub Kruzik ierr = PetscObjectTypeCompare((PetscObject)def->Wt,MATCOMPOSITE,&match);CHKERRQ(ierr); 609409a357bSJakub Kruzik if (match) { 610409a357bSJakub Kruzik ierr = MatCompositeGetType(def->Wt,&ctype);CHKERRQ(ierr); 611409a357bSJakub Kruzik ierr = MatCompositeGetNumberMat(def->Wt,&size);CHKERRQ(ierr); 612409a357bSJakub Kruzik } 613409a357bSJakub Kruzik transp = PETSC_TRUE; 614409a357bSJakub Kruzik } 615409a357bSJakub Kruzik if (match && ctype == MAT_COMPOSITE_MULTIPLICATIVE) { 616409a357bSJakub Kruzik if (!transp) { 61728da0170SJakub Kruzik if (def->nestedlvl < def->maxnestedlvl) { 61828da0170SJakub Kruzik ierr = PetscMalloc1(size,&mats);CHKERRQ(ierr); 619409a357bSJakub Kruzik for (i=0; i<size; i++) { 620409a357bSJakub Kruzik ierr = MatCompositeGetMat(def->W,i,&mats[i]);CHKERRQ(ierr); 621409a357bSJakub Kruzik } 622409a357bSJakub Kruzik size -= 1; 623409a357bSJakub Kruzik ierr = MatDestroy(&def->W);CHKERRQ(ierr); 624409a357bSJakub Kruzik def->W = mats[size]; 625409a357bSJakub Kruzik ierr = PetscObjectReference((PetscObject)mats[size]);CHKERRQ(ierr); 626409a357bSJakub Kruzik if (size > 1) { 627409a357bSJakub Kruzik ierr = MatCreateComposite(comm,size,mats,&nextDef);CHKERRQ(ierr); 628409a357bSJakub Kruzik ierr = MatCompositeSetType(nextDef,MAT_COMPOSITE_MULTIPLICATIVE);CHKERRQ(ierr); 629409a357bSJakub Kruzik } else { 630409a357bSJakub Kruzik nextDef = mats[0]; 631409a357bSJakub Kruzik ierr = PetscObjectReference((PetscObject)mats[0]);CHKERRQ(ierr); 632409a357bSJakub Kruzik } 63328da0170SJakub Kruzik ierr = PetscFree(mats);CHKERRQ(ierr); 634409a357bSJakub Kruzik } else { 635409a357bSJakub Kruzik /* ierr = MatCompositeSetMergeType(def->W,MAT_COMPOSITE_MERGE_LEFT);CHKERRQ(ierr); */ 636409a357bSJakub Kruzik ierr = MatCompositeMerge(def->W);CHKERRQ(ierr); 637409a357bSJakub Kruzik } 63828da0170SJakub Kruzik } else { 63928da0170SJakub Kruzik if (def->nestedlvl < def->maxnestedlvl) { 64028da0170SJakub Kruzik ierr = PetscMalloc1(size,&mats);CHKERRQ(ierr); 64128da0170SJakub Kruzik for (i=0; i<size; i++) { 64228da0170SJakub Kruzik ierr = MatCompositeGetMat(def->Wt,i,&mats[i]);CHKERRQ(ierr); 64328da0170SJakub Kruzik } 64428da0170SJakub Kruzik size -= 1; 64528da0170SJakub Kruzik ierr = MatDestroy(&def->Wt);CHKERRQ(ierr); 64628da0170SJakub Kruzik def->Wt = mats[0]; 64728da0170SJakub Kruzik ierr = PetscObjectReference((PetscObject)mats[0]);CHKERRQ(ierr); 64828da0170SJakub Kruzik if (size > 1) { 64928da0170SJakub Kruzik ierr = MatCreateComposite(comm,size,&mats[1],&nextDef);CHKERRQ(ierr); 65028da0170SJakub Kruzik ierr = MatCompositeSetType(nextDef,MAT_COMPOSITE_MULTIPLICATIVE);CHKERRQ(ierr); 65128da0170SJakub Kruzik } else { 65228da0170SJakub Kruzik nextDef = mats[1]; 65328da0170SJakub Kruzik ierr = PetscObjectReference((PetscObject)mats[1]);CHKERRQ(ierr); 654409a357bSJakub Kruzik } 655409a357bSJakub Kruzik ierr = PetscFree(mats);CHKERRQ(ierr); 65628da0170SJakub Kruzik } else { 65728da0170SJakub Kruzik /* ierr = MatCompositeSetMergeType(def->W,MAT_COMPOSITE_MERGE_LEFT);CHKERRQ(ierr); */ 65828da0170SJakub Kruzik ierr = MatCompositeMerge(def->Wt);CHKERRQ(ierr); 65928da0170SJakub Kruzik } 66028da0170SJakub Kruzik } 66128da0170SJakub Kruzik } 66228da0170SJakub Kruzik 66328da0170SJakub Kruzik if (transp) { 66428da0170SJakub Kruzik ierr = MatDestroy(&def->W);CHKERRQ(ierr); 665a3177931SJakub Kruzik ierr = MatHermitianTranspose(def->Wt,MAT_INITIAL_MATRIX,&def->W);CHKERRQ(ierr); 666409a357bSJakub Kruzik } 667409a357bSJakub Kruzik 668ae029463SJakub Kruzik /* assemble WtA */ 669ae029463SJakub Kruzik if (!def->WtA) { 670ae029463SJakub Kruzik if (def->Wt) { 671ae029463SJakub Kruzik ierr = MatMatMult(def->Wt,Amat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&def->WtA);CHKERRQ(ierr); 672ae029463SJakub Kruzik } else { 673a3177931SJakub Kruzik #if defined(PETSC_USE_COMPLEX) 674a3177931SJakub Kruzik ierr = MatHermitianTranspose(def->W,MAT_INITIAL_MATRIX,&def->Wt);CHKERRQ(ierr); 675a3177931SJakub Kruzik ierr = MatMatMult(def->W,Amat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&def->WtA);CHKERRQ(ierr); 676a3177931SJakub Kruzik #else 677ae029463SJakub Kruzik ierr = MatTransposeMatMult(def->W,Amat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&def->WtA);CHKERRQ(ierr); 678a3177931SJakub Kruzik #endif 679ae029463SJakub Kruzik } 680ae029463SJakub Kruzik } 681409a357bSJakub Kruzik /* setup coarse problem */ 682409a357bSJakub Kruzik if (!def->WtAWinv) { 68328da0170SJakub Kruzik ierr = MatGetSize(def->W,NULL,&m);CHKERRQ(ierr); 684409a357bSJakub Kruzik if (!def->WtAW) { 685ae029463SJakub Kruzik ierr = MatMatMult(def->WtA,def->W,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&def->WtAW);CHKERRQ(ierr); 686409a357bSJakub Kruzik /* TODO create MatInheritOption(Mat,MatOption) */ 687409a357bSJakub Kruzik ierr = MatGetOption(Amat,MAT_SPD,&flgspd);CHKERRQ(ierr); 688409a357bSJakub Kruzik ierr = MatSetOption(def->WtAW,MAT_SPD,flgspd);CHKERRQ(ierr); 689409a357bSJakub Kruzik #if defined(PETSC_USE_DEBUG) 690ae029463SJakub Kruzik /* Check columns of W are not in kernel of A */ 691409a357bSJakub Kruzik PetscReal *norms; 692409a357bSJakub Kruzik ierr = PetscMalloc1(m,&norms);CHKERRQ(ierr); 693409a357bSJakub Kruzik ierr = MatGetColumnNorms(def->WtAW,NORM_INFINITY,norms);CHKERRQ(ierr); 694409a357bSJakub Kruzik for (i=0; i<m; i++) { 695409a357bSJakub Kruzik if (norms[i] < 100*PETSC_MACHINE_EPSILON) { 696409a357bSJakub Kruzik SETERRQ1(comm,PETSC_ERR_SUP,"Column %D of W is in kernel of A.",i); 697409a357bSJakub Kruzik } 698409a357bSJakub Kruzik } 699409a357bSJakub Kruzik ierr = PetscFree(norms);CHKERRQ(ierr); 700409a357bSJakub Kruzik #endif 701409a357bSJakub Kruzik } else { 702409a357bSJakub Kruzik ierr = MatGetOption(def->WtAW,MAT_SPD,&flgspd);CHKERRQ(ierr); 703409a357bSJakub Kruzik } 704409a357bSJakub Kruzik /* TODO use MATINV */ 705409a357bSJakub Kruzik ierr = KSPCreate(comm,&def->WtAWinv);CHKERRQ(ierr); 706409a357bSJakub Kruzik ierr = KSPSetOperators(def->WtAWinv,def->WtAW,def->WtAW);CHKERRQ(ierr); 707409a357bSJakub Kruzik ierr = KSPGetPC(def->WtAWinv,&pcinner);CHKERRQ(ierr); 708557a2f7dSJakub Kruzik /* Setup KSP and PC */ 709557a2f7dSJakub Kruzik if (nextDef) { /* next level for multilevel deflation */ 710557a2f7dSJakub Kruzik innerksp = def->WtAWinv; 711557a2f7dSJakub Kruzik /* set default KSPtype */ 712557a2f7dSJakub Kruzik if (!def->ksptype) { 713557a2f7dSJakub Kruzik def->ksptype = KSPFGMRES; 714557a2f7dSJakub Kruzik if (flgspd) { /* SPD system */ 715557a2f7dSJakub Kruzik def->ksptype = KSPFCG; 716557a2f7dSJakub Kruzik } 717557a2f7dSJakub Kruzik } 718ae029463SJakub Kruzik ierr = KSPSetType(innerksp,def->ksptype);CHKERRQ(ierr); /* TODO iherit from KSP + tolerances */ 719557a2f7dSJakub Kruzik ierr = PCSetType(pcinner,PCDEFLATION);CHKERRQ(ierr); /* TODO create coarse preconditinoner M_c = WtMW ? */ 720557a2f7dSJakub Kruzik ierr = PCDeflationSetSpace(pcinner,nextDef,transp);CHKERRQ(ierr); 721557a2f7dSJakub Kruzik ierr = PCDeflationSetLvl_Deflation(pcinner,def->nestedlvl+1,def->maxnestedlvl);CHKERRQ(ierr); 722ae029463SJakub Kruzik /* inherit options */ 723557a2f7dSJakub Kruzik ((PC_Deflation*)(pcinner->data))->ksptype = def->ksptype; 724557a2f7dSJakub Kruzik ((PC_Deflation*)(pcinner->data))->correct = def->correct; 725557a2f7dSJakub Kruzik ierr = MatDestroy(&nextDef);CHKERRQ(ierr); 726557a2f7dSJakub Kruzik } else { /* the last level */ 727557a2f7dSJakub Kruzik ierr = KSPSetType(def->WtAWinv,KSPPREONLY);CHKERRQ(ierr); 728409a357bSJakub Kruzik ierr = PCSetType(pcinner,PCTELESCOPE);CHKERRQ(ierr); 729ac66f006SJakub Kruzik /* ugly hack to not have overwritten PCTELESCOPE */ 730ac66f006SJakub Kruzik if (prefix) { 731ac66f006SJakub Kruzik ierr = KSPSetOptionsPrefix(def->WtAWinv,prefix);CHKERRQ(ierr); 732ac66f006SJakub Kruzik } 73322b0793eSJakub Kruzik ierr = KSPAppendOptionsPrefix(def->WtAWinv,"tel_");CHKERRQ(ierr); 734ac66f006SJakub Kruzik ierr = PCSetFromOptions(pcinner);CHKERRQ(ierr); 735409a357bSJakub Kruzik /* Reduction factor choice */ 736409a357bSJakub Kruzik red = def->reductionfact; 737409a357bSJakub Kruzik if (red < 0) { 738409a357bSJakub Kruzik ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 739409a357bSJakub Kruzik red = ceil((float)commsize/ceil((float)m/commsize)); 740409a357bSJakub Kruzik ierr = PetscObjectTypeCompareAny((PetscObject)(def->WtAW),&match,MATSEQDENSE,MATMPIDENSE,MATDENSE,"");CHKERRQ(ierr); 741409a357bSJakub Kruzik if (match) red = commsize; 742409a357bSJakub Kruzik ierr = PetscInfo1(pc,"Auto choosing reduction factor %D\n",red);CHKERRQ(ierr); /* TODO add level? */ 743409a357bSJakub Kruzik } 744409a357bSJakub Kruzik ierr = PCTelescopeSetReductionFactor(pcinner,red);CHKERRQ(ierr); 745ac66f006SJakub Kruzik ierr = PCSetUp(pcinner);CHKERRQ(ierr); 746409a357bSJakub Kruzik ierr = PCTelescopeGetKSP(pcinner,&innerksp);CHKERRQ(ierr); 747ac66f006SJakub Kruzik if (innerksp) { 748409a357bSJakub Kruzik ierr = KSPGetPC(innerksp,&pcinner);CHKERRQ(ierr); 749409a357bSJakub Kruzik /* TODO Cholesky if flgspd? */ 750ac66f006SJakub Kruzik ierr = PCSetType(pcinner,PCLU);CHKERRQ(ierr); 751409a357bSJakub Kruzik //TODO remove explicit matSolverPackage 752409a357bSJakub Kruzik if (commsize == red) { 753ac66f006SJakub Kruzik ierr = PCFactorSetMatSolverType(pcinner,MATSOLVERSUPERLU);CHKERRQ(ierr); 754409a357bSJakub Kruzik } else { 755ac66f006SJakub Kruzik ierr = PCFactorSetMatSolverType(pcinner,MATSOLVERSUPERLU_DIST);CHKERRQ(ierr); 756409a357bSJakub Kruzik } 757409a357bSJakub Kruzik } 758557a2f7dSJakub Kruzik } 759557a2f7dSJakub Kruzik 760557a2f7dSJakub Kruzik if (innerksp) { 761409a357bSJakub Kruzik /* TODO use def_[lvl]_ if lvl > 0? */ 762409a357bSJakub Kruzik if (prefix) { 763409a357bSJakub Kruzik ierr = KSPSetOptionsPrefix(innerksp,prefix);CHKERRQ(ierr); 764409a357bSJakub Kruzik } 76522b0793eSJakub Kruzik ierr = KSPAppendOptionsPrefix(innerksp,"def_");CHKERRQ(ierr); 766557a2f7dSJakub Kruzik ierr = KSPSetFromOptions(innerksp);CHKERRQ(ierr); 767557a2f7dSJakub Kruzik ierr = KSPSetUp(innerksp);CHKERRQ(ierr); 768ac66f006SJakub Kruzik } 769409a357bSJakub Kruzik } 770557a2f7dSJakub Kruzik ierr = KSPSetFromOptions(def->WtAWinv);CHKERRQ(ierr); 771557a2f7dSJakub Kruzik ierr = KSPSetUp(def->WtAWinv);CHKERRQ(ierr); 772409a357bSJakub Kruzik 77322b0793eSJakub Kruzik if (!def->pc) { 77422b0793eSJakub Kruzik ierr = PCCreate(comm,&def->pc);CHKERRQ(ierr); 77522b0793eSJakub Kruzik ierr = PCSetOperators(def->pc,Amat,Amat);CHKERRQ(ierr); 77622b0793eSJakub Kruzik ierr = PCSetType(def->pc,PCNONE);CHKERRQ(ierr); 77722b0793eSJakub Kruzik if (prefix) { 77822b0793eSJakub Kruzik ierr = PCSetOptionsPrefix(def->pc,prefix);CHKERRQ(ierr); 77922b0793eSJakub Kruzik } 78022b0793eSJakub Kruzik ierr = PCAppendOptionsPrefix(def->pc,"def_pc_");CHKERRQ(ierr); 78122b0793eSJakub Kruzik ierr = PCSetFromOptions(def->pc);CHKERRQ(ierr); 78222b0793eSJakub Kruzik ierr = PCSetUp(def->pc);CHKERRQ(ierr); 78322b0793eSJakub Kruzik } 78422b0793eSJakub Kruzik 785f8bf229cSJakub Kruzik /* create work vecs */ 786f8bf229cSJakub Kruzik ierr = MatCreateVecs(Amat,NULL,&def->work);CHKERRQ(ierr); 787f8bf229cSJakub Kruzik ierr = KSPCreateVecs(def->WtAWinv,2,&def->workcoarse,0,NULL);CHKERRQ(ierr); 78837eeb815SJakub Kruzik PetscFunctionReturn(0); 78937eeb815SJakub Kruzik } 790b30d4775SJakub Kruzik 79137eeb815SJakub Kruzik static PetscErrorCode PCReset_Deflation(PC pc) 79237eeb815SJakub Kruzik { 793b30d4775SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 79437eeb815SJakub Kruzik PetscErrorCode ierr; 79537eeb815SJakub Kruzik 79637eeb815SJakub Kruzik PetscFunctionBegin; 797b30d4775SJakub Kruzik ierr = VecDestroy(&def->work);CHKERRQ(ierr); 798b30d4775SJakub Kruzik ierr = VecDestroyVecs(2,&def->workcoarse);CHKERRQ(ierr); 799b30d4775SJakub Kruzik ierr = MatDestroy(&def->W);CHKERRQ(ierr); 800b30d4775SJakub Kruzik ierr = MatDestroy(&def->Wt);CHKERRQ(ierr); 801ae029463SJakub Kruzik ierr = MatDestroy(&def->WtA);CHKERRQ(ierr); 802b30d4775SJakub Kruzik ierr = MatDestroy(&def->WtAW);CHKERRQ(ierr); 803b30d4775SJakub Kruzik ierr = KSPDestroy(&def->WtAWinv);CHKERRQ(ierr); 80422b0793eSJakub Kruzik ierr = PCDestroy(&def->pc);CHKERRQ(ierr); 80537eeb815SJakub Kruzik PetscFunctionReturn(0); 80637eeb815SJakub Kruzik } 80737eeb815SJakub Kruzik 80837eeb815SJakub Kruzik static PetscErrorCode PCDestroy_Deflation(PC pc) 80937eeb815SJakub Kruzik { 81037eeb815SJakub Kruzik PetscErrorCode ierr; 81137eeb815SJakub Kruzik 81237eeb815SJakub Kruzik PetscFunctionBegin; 81337eeb815SJakub Kruzik ierr = PCReset_Deflation(pc);CHKERRQ(ierr); 81437eeb815SJakub Kruzik ierr = PetscFree(pc->data);CHKERRQ(ierr); 81537eeb815SJakub Kruzik PetscFunctionReturn(0); 81637eeb815SJakub Kruzik } 81737eeb815SJakub Kruzik 8188513960bSJakub Kruzik static PetscErrorCode PCView_Deflation(PC pc,PetscViewer viewer) 8198513960bSJakub Kruzik { 8208513960bSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 8211ac6250aSJakub Kruzik PetscInt its; 8228513960bSJakub Kruzik PetscBool iascii; 8238513960bSJakub Kruzik PetscErrorCode ierr; 8248513960bSJakub Kruzik 8258513960bSJakub Kruzik PetscFunctionBegin; 8268513960bSJakub Kruzik ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 8278513960bSJakub Kruzik if (iascii) { 8288513960bSJakub Kruzik if (def->correct) { 8291ac6250aSJakub Kruzik ierr = PetscViewerASCIIPrintf(viewer,"using CP correction, factor = %g+%gi\n", 8301ac6250aSJakub Kruzik (double)PetscRealPart(def->correctfact), 8311ac6250aSJakub Kruzik (double)PetscImaginaryPart(def->correctfact));CHKERRQ(ierr); 8328513960bSJakub Kruzik } 8338513960bSJakub Kruzik if (!def->nestedlvl) { 8341ac6250aSJakub Kruzik ierr = PetscViewerASCIIPrintf(viewer,"deflation space type: %s\n",PCDeflationSpaceTypes[def->spacetype]);CHKERRQ(ierr); 8358513960bSJakub Kruzik } 8368513960bSJakub Kruzik 8371ac6250aSJakub Kruzik ierr = PetscViewerASCIIPrintf(viewer,"--- Additional PC:\n");CHKERRQ(ierr); 83822b0793eSJakub Kruzik ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 83922b0793eSJakub Kruzik ierr = PCView(def->pc,viewer);CHKERRQ(ierr); 84022b0793eSJakub Kruzik ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 84122b0793eSJakub Kruzik 8421ac6250aSJakub Kruzik ierr = PetscViewerASCIIPrintf(viewer,"--- Coarse problem solver:\n");CHKERRQ(ierr); 8438513960bSJakub Kruzik ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 8441ac6250aSJakub Kruzik ierr = KSPGetTotalIterations(def->WtAWinv,&its);CHKERRQ(ierr); 8451ac6250aSJakub Kruzik ierr = PetscViewerASCIIPrintf(viewer,"total number of iterations: %D\n",its);CHKERRQ(ierr); 8468513960bSJakub Kruzik ierr = KSPView(def->WtAWinv,viewer);CHKERRQ(ierr); 8478513960bSJakub Kruzik ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 8488513960bSJakub Kruzik } 8498513960bSJakub Kruzik PetscFunctionReturn(0); 8508513960bSJakub Kruzik } 8518513960bSJakub Kruzik 85237eeb815SJakub Kruzik static PetscErrorCode PCSetFromOptions_Deflation(PetscOptionItems *PetscOptionsObject,PC pc) 85337eeb815SJakub Kruzik { 854880d05ceSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 85537eeb815SJakub Kruzik PetscErrorCode ierr; 85637eeb815SJakub Kruzik 85737eeb815SJakub Kruzik PetscFunctionBegin; 85837eeb815SJakub Kruzik ierr = PetscOptionsHead(PetscOptionsObject,"Deflation options");CHKERRQ(ierr); 859a122ebaeSJakub Kruzik ierr = PetscOptionsBool("-pc_deflation_init_only","Use only initialization step - Initdef","PCDeflationSetInitOnly",def->init,&def->init,NULL);CHKERRQ(ierr); 860859a873cSJakub Kruzik ierr = PetscOptionsInt("-pc_deflation_max_lvl","Maximum of deflation levels","PCDeflationSetMaxLvl",def->maxnestedlvl,&def->maxnestedlvl,NULL);CHKERRQ(ierr); 861859a873cSJakub Kruzik ierr = PetscOptionsInt("-pc_deflation_reduction_factor","Reduction factor for coarse problem solution using PCTELESCOPE","PCDeflationSetReductionFactor",def->reductionfact,&def->reductionfact,NULL);CHKERRQ(ierr); 8628a71cb68SJakub Kruzik ierr = PetscOptionsBool("-pc_deflation_correction","Add coarse problem correction Q to P","PCDeflationSetCorrectionFactor",def->correct,&def->correct,NULL);CHKERRQ(ierr); 8638a71cb68SJakub Kruzik ierr = PetscOptionsScalar("-pc_deflation_correction_factor","Set multiple of Q to use as coarse problem correction","PCDeflationSetCorrectionFactor",def->correctfact,&def->correctfact,NULL);CHKERRQ(ierr); 864880d05ceSJakub Kruzik ierr = PetscOptionsEnum("-pc_deflation_compute_space","Compute deflation space","PCDeflationSetSpace",PCDeflationSpaceTypes,(PetscEnum)def->spacetype,(PetscEnum*)&def->spacetype,NULL);CHKERRQ(ierr); 865880d05ceSJakub Kruzik ierr = PetscOptionsInt("-pc_deflation_compute_space_size","Set size of the deflation space to compute","PCDeflationSetSpace",def->spacesize,&def->spacesize,NULL);CHKERRQ(ierr); 866880d05ceSJakub Kruzik ierr = PetscOptionsBool("-pc_deflation_space_extend","Extend deflation space instead of truncating (wavelets)","PCDeflation",def->extendsp,&def->extendsp,NULL);CHKERRQ(ierr); 867880d05ceSJakub Kruzik //TODO add set function and fix manpages 86837eeb815SJakub Kruzik ierr = PetscOptionsTail();CHKERRQ(ierr); 86937eeb815SJakub Kruzik PetscFunctionReturn(0); 87037eeb815SJakub Kruzik } 87137eeb815SJakub Kruzik 87237eeb815SJakub Kruzik /*MC 873*e26ad46dSJakub Kruzik PCDEFLATION - Deflation preconditioner shifts (deflates) part of the spectrum to zero or to a predefined value. 87437eeb815SJakub Kruzik 875*e26ad46dSJakub Kruzik Options Database Keys: 876*e26ad46dSJakub Kruzik + -pc_deflation_init_only <false> - if true computes only the special guess 877*e26ad46dSJakub Kruzik . -pc_deflation_max_lvl <0> - maximum number of levels for multilevel deflation 878*e26ad46dSJakub Kruzik . -pc_deflation_reduction_factor <-1> - reduction factor on bottom level coarse problem for PCTELESCOPE (default based on the size of the coarse problem) 879*e26ad46dSJakub Kruzik . -pc_deflation_correction <false> - if true apply coarse problem correction 880*e26ad46dSJakub Kruzik . -pc_deflation_correction_factor <1.0> - sets coarse problem correction factor 881*e26ad46dSJakub Kruzik . -pc_deflation_compute_space <haar> - compute PCDeflationSpaceType deflation space 882*e26ad46dSJakub Kruzik - -pc_deflation_compute_space_size <1> - size of the deflation space (corresponds to number of levels for wavelet-based deflation) 88337eeb815SJakub Kruzik 88437eeb815SJakub Kruzik Notes: 885*e26ad46dSJakub Kruzik Given a (complex - transpose is always hermitian) full rank deflation matrix W, the deflation (introduced in [1,2]) 886*e26ad46dSJakub Kruzik preconditioner uses projections Q = W*(W'*A*W)^{-1}*W' and P = I - Q*A, where A is pmat. 887*e26ad46dSJakub Kruzik 888*e26ad46dSJakub Kruzik The deflation computes initial guess x0 = x_{-1} - Q*r_{-1}, which is the solution on the deflation space. 889*e26ad46dSJakub Kruzik If PCDeflationSetInitOnly() or -pc_deflation_init_only is set to PETSC_TRUE (InitDef scheme), the application of the 890*e26ad46dSJakub Kruzik preconditioner consists only of application of the additional preconditioner M^{-1}. Otherwise, the preconditioner 891*e26ad46dSJakub Kruzik application consists of P*M{-1} + factor*Q. The first part of the preconditioner (PM^{-1}) shifts some eigenvalues 892*e26ad46dSJakub Kruzik to zero while the addition of the coarse problem correction (factor*Q) makes the preconditioner to shift some 893*e26ad46dSJakub Kruzik eigenvalues to the given factor. The InitDef scheme is recommended for deflation using high accuracy estimates 894*e26ad46dSJakub Kruzik of eigenvectors of A when it exhibits similar convergence to the full deflation but is cheaper. 895*e26ad46dSJakub Kruzik 896*e26ad46dSJakub Kruzik The deflation matrix is by default automatically computed. The type of deflation matrix and its size to compute can 897*e26ad46dSJakub Kruzik be controlled by PCDeflationSetSpaceToCompute() or -pc_deflation_compute_space and -pc_deflation_compute_space_size. 898*e26ad46dSJakub Kruzik User can set an arbitrary deflation space matrix with PCDeflationSetSpace(). If the deflation matrix 899*e26ad46dSJakub Kruzik is a multiplicative MATCOMPOSITE, a multilevel deflation [3] is used. The first matrix in the composite is used as the 900*e26ad46dSJakub Kruzik deflation matrix, and the coarse problem (W'*A*W)^{-1} is solved by FCG (if A is MAT_SPD) or FGMRES preconditioned 901*e26ad46dSJakub Kruzik by deflation with deflation matrix being the next matrix in the MATCOMPOSITE. This scheme repeats until the maximum 902*e26ad46dSJakub Kruzik level is reached or there are no more matrices. If the maximal level is reached, the remaining matrices are merged 903*e26ad46dSJakub Kruzik (multiplied) to create the last deflation matrix. The maximal level defaults to 0 and can be set by 904*e26ad46dSJakub Kruzik PCDeflationSetMaxLvl() or by -pc_deflation_max_lvl. 905*e26ad46dSJakub Kruzik 906*e26ad46dSJakub Kruzik The coarse problem KSP can be controlled from the command line with prefix -def_[lvl]. You can also use 907*e26ad46dSJakub Kruzik PCDeflationGetCoarseKSP() or PCDeflationSetCoarseKSP() to control it from code. The bottom level KSP defaults to 908*e26ad46dSJakub Kruzik KSPREONLY with PCLU direct solver wrapped into PCTELESCOPE. For convenience, the reduction factor can be set by 909*e26ad46dSJakub Kruzik PCDeflationSetReductionFactor() or -pc_deflation_recduction_factor. The default is chosen heuristically based on the 910*e26ad46dSJakub Kruzik coarse problem size. 911*e26ad46dSJakub Kruzik 912*e26ad46dSJakub Kruzik The additional preconditioner can be controlled from command line with prefix -def_[lvl]_pc, 913*e26ad46dSJakub Kruzik e.g., -def_0_pc_pc_type bjacobi. You can also use PCDeflationGetPC() or PCDeflationSetPC() to control 914*e26ad46dSJakub Kruzik the additional preconditioner from code. It defaults to PCNONE. 915*e26ad46dSJakub Kruzik 916*e26ad46dSJakub Kruzik The coarse problem correction term (factor*Q) can be turned on by -pc_deflation_correction and the factor value can 917*e26ad46dSJakub Kruzik be set by pc_deflation_correction_factor or by PCDeflationSetCorrectionFactor(). The coarse problem can 918*e26ad46dSJakub Kruzik significantly improve convergence when the deflation coarse problem is not solved with high enough accuracy. We 919*e26ad46dSJakub Kruzik recommend setting factor to some eigenvalue, e.g., the largest eigenvalue so that the preconditioner does not create 920*e26ad46dSJakub Kruzik an isolated eigenvalue. 921*e26ad46dSJakub Kruzik 922*e26ad46dSJakub Kruzik The preconditioner supports KSPMonitorDynamicTolerance(). This is useful for the multilevel scheme for which we also 923*e26ad46dSJakub Kruzik recommend limiting the number of iterations for the coarse problem. 924*e26ad46dSJakub Kruzik 925*e26ad46dSJakub Kruzik See section 3 of [4] for additional references and decription of the algorithm when used for conjugate gradients. 926*e26ad46dSJakub Kruzik Section 4 describes some possible choices for the deflation space. 927*e26ad46dSJakub Kruzik 928*e26ad46dSJakub Kruzik Developer Notes: 929*e26ad46dSJakub Kruzik Contributed by Jakub Kruzik (PERMON), Institute of Geonics of the Czech 930*e26ad46dSJakub Kruzik Academy of Sciences and VSB - TU Ostrava. 931*e26ad46dSJakub Kruzik 932*e26ad46dSJakub Kruzik Developed from PERMON code used in [4] while on a research stay with 933*e26ad46dSJakub Kruzik Prof. Reinhard Nabben at the Institute of Mathematics, TU Berlin. 934*e26ad46dSJakub Kruzik 935*e26ad46dSJakub Kruzik References: 936*e26ad46dSJakub Kruzik + [1] - A. Nicolaides. “Deflation of conjugate gradients with applications to boundary valueproblems”, SIAM J. Numer. Anal. 24.2, 1987. 937*e26ad46dSJakub Kruzik . [2] - Z. Dostal. "Conjugate gradient method with preconditioning by projector", Int J. Comput. Math. 23.3-4, 1988. 938*e26ad46dSJakub Kruzik . [3] - Y. A. Erlangga and R. Nabben. "Multilevel Projection-Based Nested Krylov Iteration for Boundary Value Problems", SIAM J. Sci. Comput. 30.3, 2008. 939*e26ad46dSJakub Kruzik . [4] - J. Kruzik "Implementation of the Deflated Variants of the Conjugate Gradient Method", Master's thesis, VSB-TUO, 2018 - http://dspace5.vsb.cz/bitstream/handle/10084/130303/KRU0097_USP_N2658_2612T078_2018.pdf 940*e26ad46dSJakub Kruzik 941*e26ad46dSJakub Kruzik Level: intermediate 94237eeb815SJakub Kruzik 94337eeb815SJakub Kruzik .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 944*e26ad46dSJakub Kruzik PCDeflationSetInitOnly(), PCDeflationSetMaxLvl(), PCDeflationSetReductionFactor(), 945*e26ad46dSJakub Kruzik PCDeflationSetCorrectionFactor(), PCDeflationSetSpaceToCompoute(), 946*e26ad46dSJakub Kruzik PCDeflationSetSpace(), PCDeflationSpaceType, PCDeflationSetProjectionNullSpaceMat(), 947*e26ad46dSJakub Kruzik PCDeflationSetCoarseMat(), PCDeflationSetCoarseKSP(), PCDeflationGetCoarseKSP(), 948*e26ad46dSJakub Kruzik PCDeflationGetPC(), PCDeflationSetPC() 94937eeb815SJakub Kruzik M*/ 95037eeb815SJakub Kruzik 95137eeb815SJakub Kruzik PETSC_EXTERN PetscErrorCode PCCreate_Deflation(PC pc) 95237eeb815SJakub Kruzik { 95337eeb815SJakub Kruzik PC_Deflation *def; 95437eeb815SJakub Kruzik PetscErrorCode ierr; 95537eeb815SJakub Kruzik 95637eeb815SJakub Kruzik PetscFunctionBegin; 95737eeb815SJakub Kruzik ierr = PetscNewLog(pc,&def);CHKERRQ(ierr); 95837eeb815SJakub Kruzik pc->data = (void*)def; 95937eeb815SJakub Kruzik 960e662bc50SJakub Kruzik def->init = PETSC_FALSE; 961e662bc50SJakub Kruzik def->correct = PETSC_FALSE; 962fcb31d99SJakub Kruzik def->correctfact = 1.0; 963e662bc50SJakub Kruzik def->reductionfact = -1; 964e662bc50SJakub Kruzik def->spacetype = PC_DEFLATION_SPACE_HAAR; 965e662bc50SJakub Kruzik def->spacesize = 1; 966e662bc50SJakub Kruzik def->extendsp = PETSC_FALSE; 967e662bc50SJakub Kruzik def->nestedlvl = 0; 968e662bc50SJakub Kruzik def->maxnestedlvl = 0; 96937eeb815SJakub Kruzik 97037eeb815SJakub Kruzik pc->ops->apply = PCApply_Deflation; 971b27c8092SJakub Kruzik pc->ops->presolve = PCPreSolve_Deflation; 97237eeb815SJakub Kruzik pc->ops->setup = PCSetUp_Deflation; 97337eeb815SJakub Kruzik pc->ops->reset = PCReset_Deflation; 97437eeb815SJakub Kruzik pc->ops->destroy = PCDestroy_Deflation; 97537eeb815SJakub Kruzik pc->ops->setfromoptions = PCSetFromOptions_Deflation; 9768513960bSJakub Kruzik pc->ops->view = PCView_Deflation; 97737eeb815SJakub Kruzik 978a122ebaeSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetInitOnly_C",PCDeflationSetInitOnly_Deflation);CHKERRQ(ierr); 97998d6e3deSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetLvl_C",PCDeflationSetLvl_Deflation);CHKERRQ(ierr); 980859a873cSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetReductionFactor_C",PCDeflationSetReductionFactor_Deflation);CHKERRQ(ierr); 9818a71cb68SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetCorrectionFactor_C",PCDeflationSetCorrectionFactor_Deflation);CHKERRQ(ierr); 98239417d7eSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetSpaceToCompute_C",PCDeflationSetSpaceToCompute_Deflation);CHKERRQ(ierr); 983e662bc50SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetSpace_C",PCDeflationSetSpace_Deflation);CHKERRQ(ierr); 9843cf3a049SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetProjectionNullSpaceMat_C",PCDeflationSetProjectionNullSpaceMat_Deflation);CHKERRQ(ierr); 985e924b002SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetCoarseMat_C",PCDeflationSetCoarseMat_Deflation);CHKERRQ(ierr); 9864a99276eSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationGetCoarseKSP_C",PCDeflationGetCoarseKSP_Deflation);CHKERRQ(ierr); 987f3eaa4f0SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetCoarseKSP_C",PCDeflationSetCoarseKSP_Deflation);CHKERRQ(ierr); 98898d6e3deSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationGetPC_C",PCDeflationGetPC_Deflation);CHKERRQ(ierr); 98998d6e3deSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetPC_C",PCDeflationSetPC_Deflation);CHKERRQ(ierr); 99037eeb815SJakub Kruzik PetscFunctionReturn(0); 99137eeb815SJakub Kruzik } 99237eeb815SJakub Kruzik 993