15170378fSJakub Kruzik #include <../src/ksp/pc/impls/deflation/deflation.h> /*I "petscksp.h" I*/ /* includes for fortran wrappers */ 237eeb815SJakub Kruzik 38513960bSJakub Kruzik const char *const PCDeflationSpaceTypes[] = { 48513960bSJakub Kruzik "haar", 58513960bSJakub Kruzik "db2", 68513960bSJakub Kruzik "db4", 78513960bSJakub Kruzik "db8", 88513960bSJakub Kruzik "db16", 98513960bSJakub Kruzik "biorth22", 108513960bSJakub Kruzik "meyer", 118513960bSJakub Kruzik "aggregation", 128513960bSJakub Kruzik "user", 130a78af22SJakub Kruzik "PCDeflationSpaceType", 140a78af22SJakub Kruzik "PC_DEFLATION_SPACE_", 158513960bSJakub Kruzik 0 168513960bSJakub Kruzik }; 178513960bSJakub Kruzik 18a122ebaeSJakub Kruzik static PetscErrorCode PCDeflationSetInitOnly_Deflation(PC pc,PetscBool flg) 19a122ebaeSJakub Kruzik { 20a122ebaeSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 21a122ebaeSJakub Kruzik 22a122ebaeSJakub Kruzik PetscFunctionBegin; 23a122ebaeSJakub Kruzik def->init = flg; 24a122ebaeSJakub Kruzik PetscFunctionReturn(0); 25a122ebaeSJakub Kruzik } 26a122ebaeSJakub Kruzik 27a122ebaeSJakub Kruzik /*@ 28a122ebaeSJakub Kruzik PCDeflationSetInitOnly - Do only initialization step. 29e26ad46dSJakub Kruzik Sets initial guess to the solution on the deflation space but does not apply 30e26ad46dSJakub Kruzik the deflation preconditioner. The additional preconditioner is still applied. 31a122ebaeSJakub Kruzik 32e26ad46dSJakub Kruzik Logically Collective 33a122ebaeSJakub Kruzik 34a122ebaeSJakub Kruzik Input Parameters: 35a122ebaeSJakub Kruzik + pc - the preconditioner context 36a122ebaeSJakub Kruzik - flg - default PETSC_FALSE 37a122ebaeSJakub Kruzik 38e26ad46dSJakub Kruzik Options Database Keys: 39e26ad46dSJakub Kruzik . -pc_deflation_init_only <false> - if true computes only the special guess 40e26ad46dSJakub Kruzik 41a122ebaeSJakub Kruzik Level: intermediate 42a122ebaeSJakub Kruzik 43a122ebaeSJakub Kruzik .seealso: PCDEFLATION 44a122ebaeSJakub Kruzik @*/ 45a122ebaeSJakub Kruzik PetscErrorCode PCDeflationSetInitOnly(PC pc,PetscBool flg) 46a122ebaeSJakub Kruzik { 47a122ebaeSJakub Kruzik PetscErrorCode ierr; 48a122ebaeSJakub Kruzik 49a122ebaeSJakub Kruzik PetscFunctionBegin; 50a122ebaeSJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 51a122ebaeSJakub Kruzik PetscValidLogicalCollectiveBool(pc,flg,2); 52a122ebaeSJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetInitOnly_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr); 53a122ebaeSJakub Kruzik PetscFunctionReturn(0); 54a122ebaeSJakub Kruzik } 55a122ebaeSJakub Kruzik 56a122ebaeSJakub Kruzik 5793b79a5aSJakub Kruzik static PetscErrorCode PCDeflationSetLevels_Deflation(PC pc,PetscInt current,PetscInt max) 5898d6e3deSJakub Kruzik { 5998d6e3deSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 6098d6e3deSJakub Kruzik 6198d6e3deSJakub Kruzik PetscFunctionBegin; 626c93e71cSJakub Kruzik if (current) def->lvl = current; 636c93e71cSJakub Kruzik def->maxlvl = max; 6498d6e3deSJakub Kruzik PetscFunctionReturn(0); 6598d6e3deSJakub Kruzik } 6698d6e3deSJakub Kruzik 6798d6e3deSJakub Kruzik /*@ 6893b79a5aSJakub Kruzik PCDeflationSetLevels - Set the maximum level of deflation nesting. 6998d6e3deSJakub Kruzik 70e26ad46dSJakub Kruzik Logically Collective 7198d6e3deSJakub Kruzik 7298d6e3deSJakub Kruzik Input Parameters: 7398d6e3deSJakub Kruzik + pc - the preconditioner context 7498d6e3deSJakub Kruzik - max - maximum deflation level 7598d6e3deSJakub Kruzik 76e26ad46dSJakub Kruzik Options Database Keys: 77e26ad46dSJakub Kruzik . -pc_deflation_max_lvl <0> - maximum number of levels for multilevel deflation 78e26ad46dSJakub Kruzik 7998d6e3deSJakub Kruzik Level: intermediate 8098d6e3deSJakub Kruzik 81e26ad46dSJakub Kruzik .seealso: PCDeflationSetSpaceToCompute(), PCDeflationSetSpace(), PCDEFLATION 8298d6e3deSJakub Kruzik @*/ 8393b79a5aSJakub Kruzik PetscErrorCode PCDeflationSetLevels(PC pc,PetscInt max) 8498d6e3deSJakub Kruzik { 8598d6e3deSJakub Kruzik PetscErrorCode ierr; 8698d6e3deSJakub Kruzik 8798d6e3deSJakub Kruzik PetscFunctionBegin; 8898d6e3deSJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 8998d6e3deSJakub Kruzik PetscValidLogicalCollectiveInt(pc,max,2); 9093b79a5aSJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetLevels_C",(PC,PetscInt,PetscInt),(pc,0,max));CHKERRQ(ierr); 9198d6e3deSJakub Kruzik PetscFunctionReturn(0); 9298d6e3deSJakub Kruzik } 9398d6e3deSJakub Kruzik 94859a873cSJakub Kruzik static PetscErrorCode PCDeflationSetReductionFactor_Deflation(PC pc,PetscInt red) 95859a873cSJakub Kruzik { 96859a873cSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 97859a873cSJakub Kruzik 98859a873cSJakub Kruzik PetscFunctionBegin; 99859a873cSJakub Kruzik def->reductionfact = red; 100859a873cSJakub Kruzik PetscFunctionReturn(0); 101859a873cSJakub Kruzik } 102859a873cSJakub Kruzik 103859a873cSJakub Kruzik /*@ 104e26ad46dSJakub Kruzik PCDeflationSetReductionFactor - Set reduction factor for the bottom PCTELESCOPE coarse problem solver. 105859a873cSJakub Kruzik 106e26ad46dSJakub Kruzik Logically Collective 107859a873cSJakub Kruzik 108859a873cSJakub Kruzik Input Parameters: 109859a873cSJakub Kruzik + pc - the preconditioner context 110859a873cSJakub Kruzik - red - reduction factor (or PETSC_DETERMINE) 111859a873cSJakub Kruzik 112e26ad46dSJakub Kruzik Options Database Keys: 113e26ad46dSJakub Kruzik . -pc_deflation_reduction_factor <-1> - reduction factor on bottom level coarse problem for PCTELESCOPE 114e26ad46dSJakub Kruzik 115e26ad46dSJakub Kruzik Notes: 116e26ad46dSJakub Kruzik Default is computed based on the size of the coarse problem. 117e26ad46dSJakub Kruzik 118859a873cSJakub Kruzik Level: intermediate 119859a873cSJakub Kruzik 120e26ad46dSJakub Kruzik .seealso: PCTELESCOPE, PCDEFLATION 121859a873cSJakub Kruzik @*/ 122859a873cSJakub Kruzik PetscErrorCode PCDeflationSetReductionFactor(PC pc,PetscInt red) 123859a873cSJakub Kruzik { 124859a873cSJakub Kruzik PetscErrorCode ierr; 125859a873cSJakub Kruzik 126859a873cSJakub Kruzik PetscFunctionBegin; 127859a873cSJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 128859a873cSJakub Kruzik PetscValidLogicalCollectiveInt(pc,red,2); 129859a873cSJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetReductionFactor_C",(PC,PetscInt),(pc,red));CHKERRQ(ierr); 130859a873cSJakub Kruzik PetscFunctionReturn(0); 131859a873cSJakub Kruzik } 132859a873cSJakub Kruzik 1338a71cb68SJakub Kruzik static PetscErrorCode PCDeflationSetCorrectionFactor_Deflation(PC pc,PetscScalar fact) 1348a71cb68SJakub Kruzik { 1358a71cb68SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 1368a71cb68SJakub Kruzik 1378a71cb68SJakub Kruzik PetscFunctionBegin; 1388a71cb68SJakub Kruzik /* TODO PETSC_DETERMINE -> compute max eigenvalue with power method */ 1398a71cb68SJakub Kruzik def->correct = PETSC_TRUE; 1408a71cb68SJakub Kruzik def->correctfact = fact; 141e26ad46dSJakub Kruzik if (def->correct == 0.0) { 1428a71cb68SJakub Kruzik def->correct = PETSC_FALSE; 1438a71cb68SJakub Kruzik } 1448a71cb68SJakub Kruzik PetscFunctionReturn(0); 1458a71cb68SJakub Kruzik } 1468a71cb68SJakub Kruzik 1478a71cb68SJakub Kruzik /*@ 1488a71cb68SJakub Kruzik PCDeflationSetCorrectionFactor - Set coarse problem correction factor. 149e26ad46dSJakub Kruzik The Preconditioner becomes P*M^{-1} + fact*Q. 1508a71cb68SJakub Kruzik 151e26ad46dSJakub Kruzik Logically Collective 1528a71cb68SJakub Kruzik 1538a71cb68SJakub Kruzik Input Parameters: 1548a71cb68SJakub Kruzik + pc - the preconditioner context 155e26ad46dSJakub Kruzik - fact - correction factor 156e26ad46dSJakub Kruzik 157e26ad46dSJakub Kruzik Options Database Keys: 158e26ad46dSJakub Kruzik + -pc_deflation_correction <false> - if true apply coarse problem correction 159e26ad46dSJakub Kruzik - -pc_deflation_correction_factor <1.0> - sets coarse problem correction factor 160e26ad46dSJakub Kruzik 161e26ad46dSJakub Kruzik Notes: 162e26ad46dSJakub Kruzik Any non-zero fact enables the coarse problem correction. 1638a71cb68SJakub Kruzik 1648a71cb68SJakub Kruzik Level: intermediate 1658a71cb68SJakub Kruzik 1668a71cb68SJakub Kruzik .seealso: PCDEFLATION 1678a71cb68SJakub Kruzik @*/ 1688a71cb68SJakub Kruzik PetscErrorCode PCDeflationSetCorrectionFactor(PC pc,PetscScalar fact) 1698a71cb68SJakub Kruzik { 1708a71cb68SJakub Kruzik PetscErrorCode ierr; 1718a71cb68SJakub Kruzik 1728a71cb68SJakub Kruzik PetscFunctionBegin; 1738a71cb68SJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1748a71cb68SJakub Kruzik PetscValidLogicalCollectiveScalar(pc,fact,2); 1758a71cb68SJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetCorrectionFactor_C",(PC,PetscScalar),(pc,fact));CHKERRQ(ierr); 1768a71cb68SJakub Kruzik PetscFunctionReturn(0); 1778a71cb68SJakub Kruzik } 1788a71cb68SJakub Kruzik 17939417d7eSJakub Kruzik static PetscErrorCode PCDeflationSetSpaceToCompute_Deflation(PC pc,PCDeflationSpaceType type,PetscInt size) 18039417d7eSJakub Kruzik { 18139417d7eSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 18239417d7eSJakub Kruzik 18339417d7eSJakub Kruzik PetscFunctionBegin; 18439417d7eSJakub Kruzik if (type) def->spacetype = type; 18539417d7eSJakub Kruzik if (size > 0) def->spacesize = size; 18639417d7eSJakub Kruzik PetscFunctionReturn(0); 18739417d7eSJakub Kruzik } 18839417d7eSJakub Kruzik 18939417d7eSJakub Kruzik /*@ 19039417d7eSJakub Kruzik PCDeflationSetSpaceToCompute - Set deflation space type and size to compute. 19139417d7eSJakub Kruzik 192e26ad46dSJakub Kruzik Logically Collective 19339417d7eSJakub Kruzik 19439417d7eSJakub Kruzik Input Parameters: 19539417d7eSJakub Kruzik + pc - the preconditioner context 19639417d7eSJakub Kruzik . type - deflation space type to compute (or PETSC_IGNORE) 19739417d7eSJakub Kruzik - size - size of the space to compute (or PETSC_DEFAULT) 19839417d7eSJakub Kruzik 199e26ad46dSJakub Kruzik Options Database Keys: 200e26ad46dSJakub Kruzik + -pc_deflation_compute_space <haar> - compute PCDeflationSpaceType deflation space 201e26ad46dSJakub Kruzik - -pc_deflation_compute_space_size <1> - size of the deflation space 202e26ad46dSJakub Kruzik 20339417d7eSJakub Kruzik Notes: 20439417d7eSJakub Kruzik For wavelet-based deflation, size represents number of levels. 205e26ad46dSJakub Kruzik 20639417d7eSJakub Kruzik The deflation space is computed in PCSetUP(). 20739417d7eSJakub Kruzik 20839417d7eSJakub Kruzik Level: intermediate 20939417d7eSJakub Kruzik 21093b79a5aSJakub Kruzik .seealso: PCDeflationSetLevels(), PCDEFLATION 21139417d7eSJakub Kruzik @*/ 21239417d7eSJakub Kruzik PetscErrorCode PCDeflationSetSpaceToCompute(PC pc,PCDeflationSpaceType type,PetscInt size) 21339417d7eSJakub Kruzik { 21439417d7eSJakub Kruzik PetscErrorCode ierr; 21539417d7eSJakub Kruzik 21639417d7eSJakub Kruzik PetscFunctionBegin; 21739417d7eSJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 21839417d7eSJakub Kruzik if (type) PetscValidLogicalCollectiveEnum(pc,type,2); 21939417d7eSJakub Kruzik if (size > 0) PetscValidLogicalCollectiveInt(pc,size,3); 22039417d7eSJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetSpaceToCompute_C",(PC,PCDeflationSpaceType,PetscInt),(pc,type,size));CHKERRQ(ierr); 22139417d7eSJakub Kruzik PetscFunctionReturn(0); 22239417d7eSJakub Kruzik } 2238513960bSJakub Kruzik 224e662bc50SJakub Kruzik static PetscErrorCode PCDeflationSetSpace_Deflation(PC pc,Mat W,PetscBool transpose) 225e662bc50SJakub Kruzik { 226e662bc50SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 227e662bc50SJakub Kruzik PetscErrorCode ierr; 228e662bc50SJakub Kruzik 229e662bc50SJakub Kruzik PetscFunctionBegin; 230e662bc50SJakub Kruzik if (transpose) { 231e662bc50SJakub Kruzik def->Wt = W; 232e662bc50SJakub Kruzik def->W = NULL; 233e662bc50SJakub Kruzik } else { 234e662bc50SJakub Kruzik def->W = W; 235e662bc50SJakub Kruzik } 236e662bc50SJakub Kruzik ierr = PetscObjectReference((PetscObject)W);CHKERRQ(ierr); 237e662bc50SJakub Kruzik PetscFunctionReturn(0); 238e662bc50SJakub Kruzik } 239e662bc50SJakub Kruzik 240e662bc50SJakub Kruzik /*@ 241*7e9012c5SJakub Kruzik PCDeflationSetSpace - Set the deflation space matrix (or its (Hermitian) transpose). 242e662bc50SJakub Kruzik 243e26ad46dSJakub Kruzik Logically Collective 244e662bc50SJakub Kruzik 245e662bc50SJakub Kruzik Input Parameters: 246e662bc50SJakub Kruzik + pc - the preconditioner context 247e662bc50SJakub Kruzik . W - deflation matrix 248e26ad46dSJakub Kruzik - transpose - indicates that W is an explicit transpose of the deflation matrix 249e26ad46dSJakub Kruzik 250e26ad46dSJakub Kruzik Notes: 251e26ad46dSJakub Kruzik Setting W as a multipliplicative MATCOMPOSITE enables use of the multilevel 252e26ad46dSJakub Kruzik deflation. If W = W0*W1*W2*...*Wn, W0 is taken as the first deflation space and 253e26ad46dSJakub Kruzik the coarse problem (W0'*A*W0)^{-1} is again preconditioned by deflation with 254e26ad46dSJakub Kruzik W1 as the deflation matrix. This repeats until the maximum level set by 25593b79a5aSJakub Kruzik PCDeflationSetLevels() is reached or there are no more matrices available. 256e26ad46dSJakub Kruzik If there are matrices left after reaching the maximum level, 257e26ad46dSJakub Kruzik they are merged into a deflation matrix ...*W{n-1}*Wn. 258e662bc50SJakub Kruzik 259e662bc50SJakub Kruzik Level: intermediate 260e662bc50SJakub Kruzik 26193b79a5aSJakub Kruzik .seealso: PCDeflationSetLevels(), PCDEFLATION 262e662bc50SJakub Kruzik @*/ 263e662bc50SJakub Kruzik PetscErrorCode PCDeflationSetSpace(PC pc,Mat W,PetscBool transpose) 264e662bc50SJakub Kruzik { 265e662bc50SJakub Kruzik PetscErrorCode ierr; 266e662bc50SJakub Kruzik 267e662bc50SJakub Kruzik PetscFunctionBegin; 268e662bc50SJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 269e662bc50SJakub Kruzik PetscValidHeaderSpecific(W,MAT_CLASSID,2); 270e662bc50SJakub Kruzik PetscValidLogicalCollectiveBool(pc,transpose,3); 271e662bc50SJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetSpace_C",(PC,Mat,PetscBool),(pc,W,transpose));CHKERRQ(ierr); 272e662bc50SJakub Kruzik PetscFunctionReturn(0); 273e662bc50SJakub Kruzik } 274e662bc50SJakub Kruzik 2753cf3a049SJakub Kruzik static PetscErrorCode PCDeflationSetProjectionNullSpaceMat_Deflation(PC pc,Mat mat) 2763cf3a049SJakub Kruzik { 2773cf3a049SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 2783cf3a049SJakub Kruzik PetscErrorCode ierr; 2793cf3a049SJakub Kruzik 2803cf3a049SJakub Kruzik PetscFunctionBegin; 2813cf3a049SJakub Kruzik ierr = MatDestroy(&def->WtA);CHKERRQ(ierr); 2823cf3a049SJakub Kruzik def->WtA = mat; 2833cf3a049SJakub Kruzik ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 2843cf3a049SJakub Kruzik ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)def->WtA);CHKERRQ(ierr); 2853cf3a049SJakub Kruzik PetscFunctionReturn(0); 2863cf3a049SJakub Kruzik } 2873cf3a049SJakub Kruzik 2883cf3a049SJakub Kruzik /*@ 289e26ad46dSJakub Kruzik PCDeflationSetProjectionNullSpaceMat - Set the projection null space matrix (W'*A). 2903cf3a049SJakub Kruzik 291e26ad46dSJakub Kruzik Collective 2923cf3a049SJakub Kruzik 2933cf3a049SJakub Kruzik Input Parameters: 2943cf3a049SJakub Kruzik + pc - preconditioner context 2953cf3a049SJakub Kruzik - mat - projection null space matrix 2963cf3a049SJakub Kruzik 2973cf3a049SJakub Kruzik Level: developer 2983cf3a049SJakub Kruzik 2993cf3a049SJakub Kruzik .seealso: PCDEFLATION 3003cf3a049SJakub Kruzik @*/ 3013cf3a049SJakub Kruzik PetscErrorCode PCDeflationSetProjectionNullSpaceMat(PC pc,Mat mat) 3023cf3a049SJakub Kruzik { 3033cf3a049SJakub Kruzik PetscErrorCode ierr; 3043cf3a049SJakub Kruzik 3053cf3a049SJakub Kruzik PetscFunctionBegin; 3063cf3a049SJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 3073cf3a049SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3083cf3a049SJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetProjectionNullSpaceMat_C",(PC,Mat),(pc,mat));CHKERRQ(ierr); 3093cf3a049SJakub Kruzik PetscFunctionReturn(0); 3103cf3a049SJakub Kruzik } 3113cf3a049SJakub Kruzik 312e924b002SJakub Kruzik static PetscErrorCode PCDeflationSetCoarseMat_Deflation(PC pc,Mat mat) 313e924b002SJakub Kruzik { 314e924b002SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 315e924b002SJakub Kruzik PetscErrorCode ierr; 316e924b002SJakub Kruzik 317e924b002SJakub Kruzik PetscFunctionBegin; 31820cd032fSJakub Kruzik ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 319e924b002SJakub Kruzik ierr = MatDestroy(&def->WtAW);CHKERRQ(ierr); 320e924b002SJakub Kruzik def->WtAW = mat; 321e924b002SJakub Kruzik ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)def->WtAW);CHKERRQ(ierr); 322e924b002SJakub Kruzik PetscFunctionReturn(0); 323e924b002SJakub Kruzik } 324e924b002SJakub Kruzik 325e924b002SJakub Kruzik /*@ 326e26ad46dSJakub Kruzik PCDeflationSetCoarseMat - Set the coarse problem Mat. 327e924b002SJakub Kruzik 328e26ad46dSJakub Kruzik Collective 329e924b002SJakub Kruzik 330e924b002SJakub Kruzik Input Parameters: 331e924b002SJakub Kruzik + pc - preconditioner context 332e924b002SJakub Kruzik - mat - coarse problem mat 333e924b002SJakub Kruzik 334e924b002SJakub Kruzik Level: developer 335e924b002SJakub Kruzik 336e924b002SJakub Kruzik .seealso: PCDEFLATION 337e924b002SJakub Kruzik @*/ 338e924b002SJakub Kruzik PetscErrorCode PCDeflationSetCoarseMat(PC pc,Mat mat) 339e924b002SJakub Kruzik { 340e924b002SJakub Kruzik PetscErrorCode ierr; 341e924b002SJakub Kruzik 342e924b002SJakub Kruzik PetscFunctionBegin; 343e924b002SJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 344e924b002SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 345e924b002SJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationSetCoarseMat_C",(PC,Mat),(pc,mat));CHKERRQ(ierr); 346e924b002SJakub Kruzik PetscFunctionReturn(0); 347e924b002SJakub Kruzik } 348e924b002SJakub Kruzik 34998d6e3deSJakub Kruzik static PetscErrorCode PCDeflationGetCoarseKSP_Deflation(PC pc,KSP *ksp) 3505c0c31c5SJakub Kruzik { 3515c0c31c5SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 3525c0c31c5SJakub Kruzik 3535c0c31c5SJakub Kruzik PetscFunctionBegin; 35498d6e3deSJakub Kruzik *ksp = def->WtAWinv; 3555c0c31c5SJakub Kruzik PetscFunctionReturn(0); 3565c0c31c5SJakub Kruzik } 3575c0c31c5SJakub Kruzik 3585c0c31c5SJakub Kruzik /*@ 359*7e9012c5SJakub Kruzik PCDeflationGetCoarseKSP - Returns the coarse problem KSP. 3605c0c31c5SJakub Kruzik 36198d6e3deSJakub Kruzik Not Collective 3625c0c31c5SJakub Kruzik 3635c0c31c5SJakub Kruzik Input Parameters: 36498d6e3deSJakub Kruzik . pc - preconditioner context 3655c0c31c5SJakub Kruzik 366e26ad46dSJakub Kruzik Output Parameters: 36798d6e3deSJakub Kruzik . ksp - coarse problem KSP context 3685c0c31c5SJakub Kruzik 369e26ad46dSJakub Kruzik Level: advanced 37098d6e3deSJakub Kruzik 3718c4db21fSJakub Kruzik .seealso: PCDEFLATION 3725c0c31c5SJakub Kruzik @*/ 37398d6e3deSJakub Kruzik PetscErrorCode PCDeflationGetCoarseKSP(PC pc,KSP *ksp) 3745c0c31c5SJakub Kruzik { 3755c0c31c5SJakub Kruzik PetscErrorCode ierr; 3765c0c31c5SJakub Kruzik 3775c0c31c5SJakub Kruzik PetscFunctionBegin; 37822b0793eSJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 37998d6e3deSJakub Kruzik PetscValidPointer(ksp,2); 38098d6e3deSJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationGetCoarseKSP_C",(PC,KSP*),(pc,ksp));CHKERRQ(ierr); 38198d6e3deSJakub Kruzik PetscFunctionReturn(0); 38298d6e3deSJakub Kruzik } 38398d6e3deSJakub Kruzik 384268c6673SJakub Kruzik static PetscErrorCode PCDeflationGetPC_Deflation(PC pc,PC *apc) 385268c6673SJakub Kruzik { 386268c6673SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 387268c6673SJakub Kruzik 388268c6673SJakub Kruzik PetscFunctionBegin; 389268c6673SJakub Kruzik *apc = def->pc; 390268c6673SJakub Kruzik PetscFunctionReturn(0); 391268c6673SJakub Kruzik } 392268c6673SJakub Kruzik 393268c6673SJakub Kruzik /*@ 394*7e9012c5SJakub Kruzik PCDeflationGetPC - Returns the additional preconditioner M^{-1}. 395268c6673SJakub Kruzik 396268c6673SJakub Kruzik Not Collective 397268c6673SJakub Kruzik 398268c6673SJakub Kruzik Input Parameters: 399268c6673SJakub Kruzik . pc - the preconditioner context 400268c6673SJakub Kruzik 401e26ad46dSJakub Kruzik Output Parameters: 402268c6673SJakub Kruzik . apc - additional preconditioner 403268c6673SJakub Kruzik 404268c6673SJakub Kruzik Level: advanced 405268c6673SJakub Kruzik 4068c4db21fSJakub Kruzik .seealso: PCDEFLATION 407268c6673SJakub Kruzik @*/ 408268c6673SJakub Kruzik PetscErrorCode PCDeflationGetPC(PC pc,PC *apc) 409268c6673SJakub Kruzik { 410268c6673SJakub Kruzik PetscErrorCode ierr; 411268c6673SJakub Kruzik 412268c6673SJakub Kruzik PetscFunctionBegin; 413268c6673SJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 414268c6673SJakub Kruzik PetscValidPointer(pc,2); 415268c6673SJakub Kruzik ierr = PetscTryMethod(pc,"PCDeflationGetPC_C",(PC,PC*),(pc,apc));CHKERRQ(ierr); 416268c6673SJakub Kruzik PetscFunctionReturn(0); 417268c6673SJakub Kruzik } 418268c6673SJakub Kruzik 41937eeb815SJakub Kruzik /* 420b27c8092SJakub Kruzik x <- x + W*(W'*A*W)^{-1}*W'*r = x + Q*r 421b27c8092SJakub Kruzik */ 422b27c8092SJakub Kruzik static PetscErrorCode PCPreSolve_Deflation(PC pc,KSP ksp,Vec b, Vec x) 423b27c8092SJakub Kruzik { 424b27c8092SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 425b27c8092SJakub Kruzik Mat A; 426b27c8092SJakub Kruzik Vec r,w1,w2; 427b27c8092SJakub Kruzik PetscBool nonzero; 428b27c8092SJakub Kruzik PetscErrorCode ierr; 42937eeb815SJakub Kruzik 430b27c8092SJakub Kruzik PetscFunctionBegin; 431b27c8092SJakub Kruzik w1 = def->workcoarse[0]; 432b27c8092SJakub Kruzik w2 = def->workcoarse[1]; 433b27c8092SJakub Kruzik r = def->work; 434b27c8092SJakub Kruzik ierr = PCGetOperators(pc,NULL,&A);CHKERRQ(ierr); 43537eeb815SJakub Kruzik 436b27c8092SJakub Kruzik ierr = KSPGetInitialGuessNonzero(ksp,&nonzero);CHKERRQ(ierr); 437b27c8092SJakub Kruzik ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 438b27c8092SJakub Kruzik if (nonzero) { 439b27c8092SJakub Kruzik ierr = MatMult(A,x,r);CHKERRQ(ierr); /* r <- b - Ax */ 440b27c8092SJakub Kruzik ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 441b27c8092SJakub Kruzik } else { 442b27c8092SJakub Kruzik ierr = VecCopy(b,r);CHKERRQ(ierr); /* r <- b (x is 0) */ 443b27c8092SJakub Kruzik } 444b27c8092SJakub Kruzik 445a3177931SJakub Kruzik if (def->Wt) { 446a3177931SJakub Kruzik ierr = MatMult(def->Wt,r,w1);CHKERRQ(ierr); /* w1 <- W'*r */ 447a3177931SJakub Kruzik } else { 448a3177931SJakub Kruzik ierr = MatMultHermitianTranspose(def->W,r,w1);CHKERRQ(ierr); /* w1 <- W'*r */ 449a3177931SJakub Kruzik } 450b27c8092SJakub Kruzik ierr = KSPSolve(def->WtAWinv,w1,w2);CHKERRQ(ierr); /* w2 <- (W'*A*W)^{-1}*w1 */ 451b27c8092SJakub Kruzik ierr = MatMult(def->W,w2,r);CHKERRQ(ierr); /* r <- W*w2 */ 452b27c8092SJakub Kruzik ierr = VecAYPX(x,1.0,r);CHKERRQ(ierr); 453b27c8092SJakub Kruzik PetscFunctionReturn(0); 454b27c8092SJakub Kruzik } 45537eeb815SJakub Kruzik 456f8bf229cSJakub Kruzik /* 457f8bf229cSJakub Kruzik if (def->correct) { 458ae029463SJakub Kruzik z <- M^{-1}r - W*(W'*A*W)^{-1}*(W'*A*M^{-1}r - l*W'*r) = (P*M^{-1} + l*Q)*r 459f8bf229cSJakub Kruzik } else { 460ae029463SJakub Kruzik z <- M^{-1}*r - W*(W'*A*W)^{-1}*W'*A*M{-1}*r = P*M^{-1}*r 461f8bf229cSJakub Kruzik } 46237eeb815SJakub Kruzik */ 463f8bf229cSJakub Kruzik static PetscErrorCode PCApply_Deflation(PC pc,Vec r,Vec z) 464f8bf229cSJakub Kruzik { 465f8bf229cSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 466f8bf229cSJakub Kruzik Mat A; 467f8bf229cSJakub Kruzik Vec u,w1,w2; 468f8bf229cSJakub Kruzik PetscErrorCode ierr; 469f8bf229cSJakub Kruzik 470f8bf229cSJakub Kruzik PetscFunctionBegin; 471f8bf229cSJakub Kruzik w1 = def->workcoarse[0]; 472f8bf229cSJakub Kruzik w2 = def->workcoarse[1]; 473f8bf229cSJakub Kruzik u = def->work; 474f8bf229cSJakub Kruzik ierr = PCGetOperators(pc,NULL,&A);CHKERRQ(ierr); 475f8bf229cSJakub Kruzik 476ae029463SJakub Kruzik ierr = PCApply(def->pc,r,z);CHKERRQ(ierr); /* z <- M^{-1}*r */ 47722b0793eSJakub Kruzik if (!def->init) { 478ae029463SJakub Kruzik ierr = MatMult(def->WtA,z,w1);CHKERRQ(ierr); /* w1 <- W'*A*z */ 479f8bf229cSJakub Kruzik if (def->correct) { 480ae029463SJakub Kruzik if (def->Wt) { 481ae029463SJakub Kruzik ierr = MatMult(def->Wt,r,w2);CHKERRQ(ierr); /* w2 <- W'*r */ 482ae029463SJakub Kruzik } else { 483a3177931SJakub Kruzik ierr = MatMultHermitianTranspose(def->W,r,w2);CHKERRQ(ierr); /* w2 <- W'*r */ 484f8bf229cSJakub Kruzik } 485ae029463SJakub Kruzik ierr = VecAXPY(w1,-1.0*def->correctfact,w2);CHKERRQ(ierr); /* w1 <- w1 - l*w2 */ 486f8bf229cSJakub Kruzik } 487f8bf229cSJakub Kruzik ierr = KSPSolve(def->WtAWinv,w1,w2);CHKERRQ(ierr); /* w2 <- (W'*A*W)^{-1}*w1 */ 488f8bf229cSJakub Kruzik ierr = MatMult(def->W,w2,u);CHKERRQ(ierr); /* u <- W*w2 */ 48922b0793eSJakub Kruzik ierr = VecAXPY(z,-1.0,u);CHKERRQ(ierr); /* z <- z - u */ 49022b0793eSJakub Kruzik } 491f8bf229cSJakub Kruzik PetscFunctionReturn(0); 492f8bf229cSJakub Kruzik } 493f8bf229cSJakub Kruzik 49437eeb815SJakub Kruzik static PetscErrorCode PCSetUp_Deflation(PC pc) 49537eeb815SJakub Kruzik { 496409a357bSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 497409a357bSJakub Kruzik KSP innerksp; 498409a357bSJakub Kruzik PC pcinner; 499409a357bSJakub Kruzik Mat Amat,nextDef=NULL,*mats; 500409a357bSJakub Kruzik PetscInt i,m,red,size,commsize; 501409a357bSJakub Kruzik PetscBool match,flgspd,transp=PETSC_FALSE; 502409a357bSJakub Kruzik MatCompositeType ctype; 503409a357bSJakub Kruzik MPI_Comm comm; 5046c93e71cSJakub Kruzik char prefix[128]=""; 50537eeb815SJakub Kruzik PetscErrorCode ierr; 50637eeb815SJakub Kruzik 50737eeb815SJakub Kruzik PetscFunctionBegin; 508409a357bSJakub Kruzik if (pc->setupcalled) PetscFunctionReturn(0); 509409a357bSJakub Kruzik ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 510f8bf229cSJakub Kruzik ierr = PCGetOperators(pc,NULL,&Amat);CHKERRQ(ierr); 5116c93e71cSJakub Kruzik if (!def->lvl && !def->prefix) { 5126c93e71cSJakub Kruzik ierr = PCGetOptionsPrefix(pc,&def->prefix);CHKERRQ(ierr); 5136c93e71cSJakub Kruzik } 5146c93e71cSJakub Kruzik if (def->lvl) { 51520cd032fSJakub Kruzik (void) sprintf(prefix,"%d_",(int)def->lvl); 5166c93e71cSJakub Kruzik } 517f8bf229cSJakub Kruzik 518f8bf229cSJakub Kruzik /* compute a deflation space */ 519409a357bSJakub Kruzik if (def->W || def->Wt) { 520409a357bSJakub Kruzik def->spacetype = PC_DEFLATION_SPACE_USER; 521409a357bSJakub Kruzik } else { 522e53e0a0dSJakub Kruzik ierr = PCDeflationComputeSpace(pc);CHKERRQ(ierr); 52337eeb815SJakub Kruzik } 52437eeb815SJakub Kruzik 525409a357bSJakub Kruzik /* nested deflation */ 526409a357bSJakub Kruzik if (def->W) { 527409a357bSJakub Kruzik ierr = PetscObjectTypeCompare((PetscObject)def->W,MATCOMPOSITE,&match);CHKERRQ(ierr); 528409a357bSJakub Kruzik if (match) { 529409a357bSJakub Kruzik ierr = MatCompositeGetType(def->W,&ctype);CHKERRQ(ierr); 530409a357bSJakub Kruzik ierr = MatCompositeGetNumberMat(def->W,&size);CHKERRQ(ierr); 53137eeb815SJakub Kruzik } 532409a357bSJakub Kruzik } else { 533a3177931SJakub Kruzik ierr = MatCreateHermitianTranspose(def->Wt,&def->W);CHKERRQ(ierr); 534409a357bSJakub Kruzik ierr = PetscObjectTypeCompare((PetscObject)def->Wt,MATCOMPOSITE,&match);CHKERRQ(ierr); 535409a357bSJakub Kruzik if (match) { 536409a357bSJakub Kruzik ierr = MatCompositeGetType(def->Wt,&ctype);CHKERRQ(ierr); 537409a357bSJakub Kruzik ierr = MatCompositeGetNumberMat(def->Wt,&size);CHKERRQ(ierr); 538409a357bSJakub Kruzik } 539409a357bSJakub Kruzik transp = PETSC_TRUE; 540409a357bSJakub Kruzik } 541409a357bSJakub Kruzik if (match && ctype == MAT_COMPOSITE_MULTIPLICATIVE) { 542409a357bSJakub Kruzik if (!transp) { 5436c93e71cSJakub Kruzik if (def->lvl < def->maxlvl) { 54428da0170SJakub Kruzik ierr = PetscMalloc1(size,&mats);CHKERRQ(ierr); 545409a357bSJakub Kruzik for (i=0; i<size; i++) { 546409a357bSJakub Kruzik ierr = MatCompositeGetMat(def->W,i,&mats[i]);CHKERRQ(ierr); 547409a357bSJakub Kruzik } 548409a357bSJakub Kruzik size -= 1; 549409a357bSJakub Kruzik ierr = MatDestroy(&def->W);CHKERRQ(ierr); 550409a357bSJakub Kruzik def->W = mats[size]; 551409a357bSJakub Kruzik ierr = PetscObjectReference((PetscObject)mats[size]);CHKERRQ(ierr); 552409a357bSJakub Kruzik if (size > 1) { 553409a357bSJakub Kruzik ierr = MatCreateComposite(comm,size,mats,&nextDef);CHKERRQ(ierr); 554409a357bSJakub Kruzik ierr = MatCompositeSetType(nextDef,MAT_COMPOSITE_MULTIPLICATIVE);CHKERRQ(ierr); 555409a357bSJakub Kruzik } else { 556409a357bSJakub Kruzik nextDef = mats[0]; 557409a357bSJakub Kruzik ierr = PetscObjectReference((PetscObject)mats[0]);CHKERRQ(ierr); 558409a357bSJakub Kruzik } 55928da0170SJakub Kruzik ierr = PetscFree(mats);CHKERRQ(ierr); 560409a357bSJakub Kruzik } else { 5611fdb00f9SJakub Kruzik /* TODO test merge side performance */ 562409a357bSJakub Kruzik /* ierr = MatCompositeSetMergeType(def->W,MAT_COMPOSITE_MERGE_LEFT);CHKERRQ(ierr); */ 563409a357bSJakub Kruzik ierr = MatCompositeMerge(def->W);CHKERRQ(ierr); 564409a357bSJakub Kruzik } 56528da0170SJakub Kruzik } else { 5666c93e71cSJakub Kruzik if (def->lvl < def->maxlvl) { 56728da0170SJakub Kruzik ierr = PetscMalloc1(size,&mats);CHKERRQ(ierr); 56828da0170SJakub Kruzik for (i=0; i<size; i++) { 56928da0170SJakub Kruzik ierr = MatCompositeGetMat(def->Wt,i,&mats[i]);CHKERRQ(ierr); 57028da0170SJakub Kruzik } 57128da0170SJakub Kruzik size -= 1; 57228da0170SJakub Kruzik ierr = MatDestroy(&def->Wt);CHKERRQ(ierr); 57328da0170SJakub Kruzik def->Wt = mats[0]; 57428da0170SJakub Kruzik ierr = PetscObjectReference((PetscObject)mats[0]);CHKERRQ(ierr); 57528da0170SJakub Kruzik if (size > 1) { 57628da0170SJakub Kruzik ierr = MatCreateComposite(comm,size,&mats[1],&nextDef);CHKERRQ(ierr); 57728da0170SJakub Kruzik ierr = MatCompositeSetType(nextDef,MAT_COMPOSITE_MULTIPLICATIVE);CHKERRQ(ierr); 57828da0170SJakub Kruzik } else { 57928da0170SJakub Kruzik nextDef = mats[1]; 58028da0170SJakub Kruzik ierr = PetscObjectReference((PetscObject)mats[1]);CHKERRQ(ierr); 581409a357bSJakub Kruzik } 582409a357bSJakub Kruzik ierr = PetscFree(mats);CHKERRQ(ierr); 58328da0170SJakub Kruzik } else { 58428da0170SJakub Kruzik /* ierr = MatCompositeSetMergeType(def->W,MAT_COMPOSITE_MERGE_LEFT);CHKERRQ(ierr); */ 58528da0170SJakub Kruzik ierr = MatCompositeMerge(def->Wt);CHKERRQ(ierr); 58628da0170SJakub Kruzik } 58728da0170SJakub Kruzik } 58828da0170SJakub Kruzik } 58928da0170SJakub Kruzik 59028da0170SJakub Kruzik if (transp) { 59128da0170SJakub Kruzik ierr = MatDestroy(&def->W);CHKERRQ(ierr); 592a3177931SJakub Kruzik ierr = MatHermitianTranspose(def->Wt,MAT_INITIAL_MATRIX,&def->W);CHKERRQ(ierr); 593409a357bSJakub Kruzik } 594409a357bSJakub Kruzik 595ae029463SJakub Kruzik /* assemble WtA */ 596ae029463SJakub Kruzik if (!def->WtA) { 597ae029463SJakub Kruzik if (def->Wt) { 598ae029463SJakub Kruzik ierr = MatMatMult(def->Wt,Amat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&def->WtA);CHKERRQ(ierr); 599ae029463SJakub Kruzik } else { 600a3177931SJakub Kruzik #if defined(PETSC_USE_COMPLEX) 601a3177931SJakub Kruzik ierr = MatHermitianTranspose(def->W,MAT_INITIAL_MATRIX,&def->Wt);CHKERRQ(ierr); 6029e56ec8aSJakub Kruzik ierr = MatMatMult(def->Wt,Amat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&def->WtA);CHKERRQ(ierr); 603a3177931SJakub Kruzik #else 604ae029463SJakub Kruzik ierr = MatTransposeMatMult(def->W,Amat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&def->WtA);CHKERRQ(ierr); 605a3177931SJakub Kruzik #endif 606ae029463SJakub Kruzik } 607ae029463SJakub Kruzik } 608409a357bSJakub Kruzik /* setup coarse problem */ 609409a357bSJakub Kruzik if (!def->WtAWinv) { 61028da0170SJakub Kruzik ierr = MatGetSize(def->W,NULL,&m);CHKERRQ(ierr); 611409a357bSJakub Kruzik if (!def->WtAW) { 612ae029463SJakub Kruzik ierr = MatMatMult(def->WtA,def->W,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&def->WtAW);CHKERRQ(ierr); 613409a357bSJakub Kruzik /* TODO create MatInheritOption(Mat,MatOption) */ 614409a357bSJakub Kruzik ierr = MatGetOption(Amat,MAT_SPD,&flgspd);CHKERRQ(ierr); 615409a357bSJakub Kruzik ierr = MatSetOption(def->WtAW,MAT_SPD,flgspd);CHKERRQ(ierr); 616409a357bSJakub Kruzik #if defined(PETSC_USE_DEBUG) 617ae029463SJakub Kruzik /* Check columns of W are not in kernel of A */ 618409a357bSJakub Kruzik PetscReal *norms; 619409a357bSJakub Kruzik ierr = PetscMalloc1(m,&norms);CHKERRQ(ierr); 620409a357bSJakub Kruzik ierr = MatGetColumnNorms(def->WtAW,NORM_INFINITY,norms);CHKERRQ(ierr); 621409a357bSJakub Kruzik for (i=0; i<m; i++) { 622409a357bSJakub Kruzik if (norms[i] < 100*PETSC_MACHINE_EPSILON) { 623409a357bSJakub Kruzik SETERRQ1(comm,PETSC_ERR_SUP,"Column %D of W is in kernel of A.",i); 624409a357bSJakub Kruzik } 625409a357bSJakub Kruzik } 626409a357bSJakub Kruzik ierr = PetscFree(norms);CHKERRQ(ierr); 627409a357bSJakub Kruzik #endif 628409a357bSJakub Kruzik } else { 629409a357bSJakub Kruzik ierr = MatGetOption(def->WtAW,MAT_SPD,&flgspd);CHKERRQ(ierr); 630409a357bSJakub Kruzik } 6311fdb00f9SJakub Kruzik /* TODO use MATINV ? */ 632409a357bSJakub Kruzik ierr = KSPCreate(comm,&def->WtAWinv);CHKERRQ(ierr); 633409a357bSJakub Kruzik ierr = KSPSetOperators(def->WtAWinv,def->WtAW,def->WtAW);CHKERRQ(ierr); 634409a357bSJakub Kruzik ierr = KSPGetPC(def->WtAWinv,&pcinner);CHKERRQ(ierr); 635557a2f7dSJakub Kruzik /* Setup KSP and PC */ 636557a2f7dSJakub Kruzik if (nextDef) { /* next level for multilevel deflation */ 637557a2f7dSJakub Kruzik innerksp = def->WtAWinv; 638557a2f7dSJakub Kruzik /* set default KSPtype */ 639557a2f7dSJakub Kruzik if (!def->ksptype) { 640557a2f7dSJakub Kruzik def->ksptype = KSPFGMRES; 641557a2f7dSJakub Kruzik if (flgspd) { /* SPD system */ 642557a2f7dSJakub Kruzik def->ksptype = KSPFCG; 643557a2f7dSJakub Kruzik } 644557a2f7dSJakub Kruzik } 645ae029463SJakub Kruzik ierr = KSPSetType(innerksp,def->ksptype);CHKERRQ(ierr); /* TODO iherit from KSP + tolerances */ 646557a2f7dSJakub Kruzik ierr = PCSetType(pcinner,PCDEFLATION);CHKERRQ(ierr); /* TODO create coarse preconditinoner M_c = WtMW ? */ 647557a2f7dSJakub Kruzik ierr = PCDeflationSetSpace(pcinner,nextDef,transp);CHKERRQ(ierr); 64893b79a5aSJakub Kruzik ierr = PCDeflationSetLevels_Deflation(pcinner,def->lvl+1,def->maxlvl);CHKERRQ(ierr); 649ae029463SJakub Kruzik /* inherit options */ 6506c93e71cSJakub Kruzik if (def->prefix) ((PC_Deflation*)(pcinner->data))->prefix = def->prefix; 6519f604af8SJakub Kruzik ((PC_Deflation*)(pcinner->data))->init = def->init; 652557a2f7dSJakub Kruzik ((PC_Deflation*)(pcinner->data))->ksptype = def->ksptype; 653557a2f7dSJakub Kruzik ((PC_Deflation*)(pcinner->data))->correct = def->correct; 6549f604af8SJakub Kruzik ((PC_Deflation*)(pcinner->data))->correctfact = def->correctfact; 6559f604af8SJakub Kruzik ((PC_Deflation*)(pcinner->data))->reductionfact = def->reductionfact; 656557a2f7dSJakub Kruzik ierr = MatDestroy(&nextDef);CHKERRQ(ierr); 657557a2f7dSJakub Kruzik } else { /* the last level */ 658557a2f7dSJakub Kruzik ierr = KSPSetType(def->WtAWinv,KSPPREONLY);CHKERRQ(ierr); 659409a357bSJakub Kruzik ierr = PCSetType(pcinner,PCTELESCOPE);CHKERRQ(ierr); 6606c93e71cSJakub Kruzik /* do not overwrite PCTELESCOPE */ 6616c93e71cSJakub Kruzik if (def->prefix) { 6626c93e71cSJakub Kruzik ierr = KSPSetOptionsPrefix(def->WtAWinv,def->prefix);CHKERRQ(ierr); 663ac66f006SJakub Kruzik } 6646c93e71cSJakub Kruzik ierr = KSPAppendOptionsPrefix(def->WtAWinv,"def_tel_");CHKERRQ(ierr); 665ac66f006SJakub Kruzik ierr = PCSetFromOptions(pcinner);CHKERRQ(ierr); 666409a357bSJakub Kruzik /* Reduction factor choice */ 667409a357bSJakub Kruzik red = def->reductionfact; 668409a357bSJakub Kruzik if (red < 0) { 669409a357bSJakub Kruzik ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 670409a357bSJakub Kruzik red = ceil((float)commsize/ceil((float)m/commsize)); 671409a357bSJakub Kruzik ierr = PetscObjectTypeCompareAny((PetscObject)(def->WtAW),&match,MATSEQDENSE,MATMPIDENSE,MATDENSE,"");CHKERRQ(ierr); 672409a357bSJakub Kruzik if (match) red = commsize; 6736c93e71cSJakub Kruzik ierr = PetscInfo1(pc,"Auto choosing reduction factor %D\n",red);CHKERRQ(ierr); 674409a357bSJakub Kruzik } 675409a357bSJakub Kruzik ierr = PCTelescopeSetReductionFactor(pcinner,red);CHKERRQ(ierr); 676ac66f006SJakub Kruzik ierr = PCSetUp(pcinner);CHKERRQ(ierr); 677409a357bSJakub Kruzik ierr = PCTelescopeGetKSP(pcinner,&innerksp);CHKERRQ(ierr); 678ac66f006SJakub Kruzik if (innerksp) { 679409a357bSJakub Kruzik ierr = KSPGetPC(innerksp,&pcinner);CHKERRQ(ierr); 680ac66f006SJakub Kruzik ierr = PCSetType(pcinner,PCLU);CHKERRQ(ierr); 681481b7641SJakub Kruzik #if defined(PETSC_HAVE_SUPERLU) 682481b7641SJakub Kruzik ierr = MatGetFactorAvailable(def->WtAW,MATSOLVERSUPERLU,MAT_FACTOR_LU,&match);CHKERRQ(ierr); 683481b7641SJakub Kruzik if (match) { 684ac66f006SJakub Kruzik ierr = PCFactorSetMatSolverType(pcinner,MATSOLVERSUPERLU);CHKERRQ(ierr); 685481b7641SJakub Kruzik } 686481b7641SJakub Kruzik #endif 687481b7641SJakub Kruzik #if defined(PETSC_HAVE_SUPERLU_DIST) 688481b7641SJakub Kruzik ierr = MatGetFactorAvailable(def->WtAW,MATSOLVERSUPERLU_DIST,MAT_FACTOR_LU,&match);CHKERRQ(ierr); 689481b7641SJakub Kruzik if (match) { 690ac66f006SJakub Kruzik ierr = PCFactorSetMatSolverType(pcinner,MATSOLVERSUPERLU_DIST);CHKERRQ(ierr); 691409a357bSJakub Kruzik } 692481b7641SJakub Kruzik #endif 693409a357bSJakub Kruzik } 694557a2f7dSJakub Kruzik } 695557a2f7dSJakub Kruzik 696557a2f7dSJakub Kruzik if (innerksp) { 6976c93e71cSJakub Kruzik if (def->prefix) { 6986c93e71cSJakub Kruzik ierr = KSPSetOptionsPrefix(innerksp,def->prefix);CHKERRQ(ierr); 69922b0793eSJakub Kruzik ierr = KSPAppendOptionsPrefix(innerksp,"def_");CHKERRQ(ierr); 7006c93e71cSJakub Kruzik } else { 7016c93e71cSJakub Kruzik ierr = KSPSetOptionsPrefix(innerksp,"def_");CHKERRQ(ierr); 7026c93e71cSJakub Kruzik } 7036c93e71cSJakub Kruzik ierr = KSPAppendOptionsPrefix(innerksp,prefix);CHKERRQ(ierr); 704557a2f7dSJakub Kruzik ierr = KSPSetFromOptions(innerksp);CHKERRQ(ierr); 705557a2f7dSJakub Kruzik ierr = KSPSetUp(innerksp);CHKERRQ(ierr); 706ac66f006SJakub Kruzik } 707409a357bSJakub Kruzik } 708557a2f7dSJakub Kruzik ierr = KSPSetFromOptions(def->WtAWinv);CHKERRQ(ierr); 709557a2f7dSJakub Kruzik ierr = KSPSetUp(def->WtAWinv);CHKERRQ(ierr); 710409a357bSJakub Kruzik 7111fdb00f9SJakub Kruzik /* create preconditioner */ 71222b0793eSJakub Kruzik if (!def->pc) { 71322b0793eSJakub Kruzik ierr = PCCreate(comm,&def->pc);CHKERRQ(ierr); 71422b0793eSJakub Kruzik ierr = PCSetOperators(def->pc,Amat,Amat);CHKERRQ(ierr); 71522b0793eSJakub Kruzik ierr = PCSetType(def->pc,PCNONE);CHKERRQ(ierr); 7166c93e71cSJakub Kruzik if (def->prefix) { 7176c93e71cSJakub Kruzik ierr = PCSetOptionsPrefix(def->pc,def->prefix);CHKERRQ(ierr); 71822b0793eSJakub Kruzik } 7196c93e71cSJakub Kruzik ierr = PCAppendOptionsPrefix(def->pc,"def_");CHKERRQ(ierr); 7206c93e71cSJakub Kruzik ierr = PCAppendOptionsPrefix(def->pc,prefix);CHKERRQ(ierr); 7216c93e71cSJakub Kruzik ierr = PCAppendOptionsPrefix(def->pc,"pc_");CHKERRQ(ierr); 72222b0793eSJakub Kruzik ierr = PCSetFromOptions(def->pc);CHKERRQ(ierr); 72322b0793eSJakub Kruzik ierr = PCSetUp(def->pc);CHKERRQ(ierr); 72422b0793eSJakub Kruzik } 72522b0793eSJakub Kruzik 726f8bf229cSJakub Kruzik /* create work vecs */ 727f8bf229cSJakub Kruzik ierr = MatCreateVecs(Amat,NULL,&def->work);CHKERRQ(ierr); 728f8bf229cSJakub Kruzik ierr = KSPCreateVecs(def->WtAWinv,2,&def->workcoarse,0,NULL);CHKERRQ(ierr); 72937eeb815SJakub Kruzik PetscFunctionReturn(0); 73037eeb815SJakub Kruzik } 731b30d4775SJakub Kruzik 73237eeb815SJakub Kruzik static PetscErrorCode PCReset_Deflation(PC pc) 73337eeb815SJakub Kruzik { 734b30d4775SJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 73537eeb815SJakub Kruzik PetscErrorCode ierr; 73637eeb815SJakub Kruzik 73737eeb815SJakub Kruzik PetscFunctionBegin; 738b30d4775SJakub Kruzik ierr = VecDestroy(&def->work);CHKERRQ(ierr); 739b30d4775SJakub Kruzik ierr = VecDestroyVecs(2,&def->workcoarse);CHKERRQ(ierr); 740b30d4775SJakub Kruzik ierr = MatDestroy(&def->W);CHKERRQ(ierr); 741b30d4775SJakub Kruzik ierr = MatDestroy(&def->Wt);CHKERRQ(ierr); 742ae029463SJakub Kruzik ierr = MatDestroy(&def->WtA);CHKERRQ(ierr); 743b30d4775SJakub Kruzik ierr = MatDestroy(&def->WtAW);CHKERRQ(ierr); 744b30d4775SJakub Kruzik ierr = KSPDestroy(&def->WtAWinv);CHKERRQ(ierr); 74522b0793eSJakub Kruzik ierr = PCDestroy(&def->pc);CHKERRQ(ierr); 74637eeb815SJakub Kruzik PetscFunctionReturn(0); 74737eeb815SJakub Kruzik } 74837eeb815SJakub Kruzik 74937eeb815SJakub Kruzik static PetscErrorCode PCDestroy_Deflation(PC pc) 75037eeb815SJakub Kruzik { 75137eeb815SJakub Kruzik PetscErrorCode ierr; 75237eeb815SJakub Kruzik 75337eeb815SJakub Kruzik PetscFunctionBegin; 75437eeb815SJakub Kruzik ierr = PCReset_Deflation(pc);CHKERRQ(ierr); 75537eeb815SJakub Kruzik ierr = PetscFree(pc->data);CHKERRQ(ierr); 75637eeb815SJakub Kruzik PetscFunctionReturn(0); 75737eeb815SJakub Kruzik } 75837eeb815SJakub Kruzik 7598513960bSJakub Kruzik static PetscErrorCode PCView_Deflation(PC pc,PetscViewer viewer) 7608513960bSJakub Kruzik { 7618513960bSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 7621ac6250aSJakub Kruzik PetscInt its; 7638513960bSJakub Kruzik PetscBool iascii; 7648513960bSJakub Kruzik PetscErrorCode ierr; 7658513960bSJakub Kruzik 7668513960bSJakub Kruzik PetscFunctionBegin; 7678513960bSJakub Kruzik ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 7688513960bSJakub Kruzik if (iascii) { 7698513960bSJakub Kruzik if (def->correct) { 7701ac6250aSJakub Kruzik ierr = PetscViewerASCIIPrintf(viewer,"using CP correction, factor = %g+%gi\n", 7711ac6250aSJakub Kruzik (double)PetscRealPart(def->correctfact), 7721ac6250aSJakub Kruzik (double)PetscImaginaryPart(def->correctfact));CHKERRQ(ierr); 7738513960bSJakub Kruzik } 7746c93e71cSJakub Kruzik if (!def->lvl) { 7751ac6250aSJakub Kruzik ierr = PetscViewerASCIIPrintf(viewer,"deflation space type: %s\n",PCDeflationSpaceTypes[def->spacetype]);CHKERRQ(ierr); 7768513960bSJakub Kruzik } 7778513960bSJakub Kruzik 7781ac6250aSJakub Kruzik ierr = PetscViewerASCIIPrintf(viewer,"--- Additional PC:\n");CHKERRQ(ierr); 77922b0793eSJakub Kruzik ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 78022b0793eSJakub Kruzik ierr = PCView(def->pc,viewer);CHKERRQ(ierr); 78122b0793eSJakub Kruzik ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 78222b0793eSJakub Kruzik 7831ac6250aSJakub Kruzik ierr = PetscViewerASCIIPrintf(viewer,"--- Coarse problem solver:\n");CHKERRQ(ierr); 7848513960bSJakub Kruzik ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 7851ac6250aSJakub Kruzik ierr = KSPGetTotalIterations(def->WtAWinv,&its);CHKERRQ(ierr); 7861ac6250aSJakub Kruzik ierr = PetscViewerASCIIPrintf(viewer,"total number of iterations: %D\n",its);CHKERRQ(ierr); 7878513960bSJakub Kruzik ierr = KSPView(def->WtAWinv,viewer);CHKERRQ(ierr); 7888513960bSJakub Kruzik ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 7898513960bSJakub Kruzik } 7908513960bSJakub Kruzik PetscFunctionReturn(0); 7918513960bSJakub Kruzik } 7928513960bSJakub Kruzik 79337eeb815SJakub Kruzik static PetscErrorCode PCSetFromOptions_Deflation(PetscOptionItems *PetscOptionsObject,PC pc) 79437eeb815SJakub Kruzik { 795880d05ceSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 79637eeb815SJakub Kruzik PetscErrorCode ierr; 79737eeb815SJakub Kruzik 79837eeb815SJakub Kruzik PetscFunctionBegin; 79937eeb815SJakub Kruzik ierr = PetscOptionsHead(PetscOptionsObject,"Deflation options");CHKERRQ(ierr); 800a122ebaeSJakub Kruzik ierr = PetscOptionsBool("-pc_deflation_init_only","Use only initialization step - Initdef","PCDeflationSetInitOnly",def->init,&def->init,NULL);CHKERRQ(ierr); 80193b79a5aSJakub Kruzik ierr = PetscOptionsInt("-pc_deflation_levels","Maximum of deflation levels","PCDeflationSetLevels",def->maxlvl,&def->maxlvl,NULL);CHKERRQ(ierr); 802859a873cSJakub Kruzik ierr = PetscOptionsInt("-pc_deflation_reduction_factor","Reduction factor for coarse problem solution using PCTELESCOPE","PCDeflationSetReductionFactor",def->reductionfact,&def->reductionfact,NULL);CHKERRQ(ierr); 8038a71cb68SJakub Kruzik ierr = PetscOptionsBool("-pc_deflation_correction","Add coarse problem correction Q to P","PCDeflationSetCorrectionFactor",def->correct,&def->correct,NULL);CHKERRQ(ierr); 8048a71cb68SJakub 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); 805880d05ceSJakub Kruzik ierr = PetscOptionsEnum("-pc_deflation_compute_space","Compute deflation space","PCDeflationSetSpace",PCDeflationSpaceTypes,(PetscEnum)def->spacetype,(PetscEnum*)&def->spacetype,NULL);CHKERRQ(ierr); 806880d05ceSJakub Kruzik ierr = PetscOptionsInt("-pc_deflation_compute_space_size","Set size of the deflation space to compute","PCDeflationSetSpace",def->spacesize,&def->spacesize,NULL);CHKERRQ(ierr); 807880d05ceSJakub Kruzik ierr = PetscOptionsBool("-pc_deflation_space_extend","Extend deflation space instead of truncating (wavelets)","PCDeflation",def->extendsp,&def->extendsp,NULL);CHKERRQ(ierr); 80837eeb815SJakub Kruzik ierr = PetscOptionsTail();CHKERRQ(ierr); 80937eeb815SJakub Kruzik PetscFunctionReturn(0); 81037eeb815SJakub Kruzik } 81137eeb815SJakub Kruzik 81237eeb815SJakub Kruzik /*MC 813e26ad46dSJakub Kruzik PCDEFLATION - Deflation preconditioner shifts (deflates) part of the spectrum to zero or to a predefined value. 81437eeb815SJakub Kruzik 815e26ad46dSJakub Kruzik Options Database Keys: 816e26ad46dSJakub Kruzik + -pc_deflation_init_only <false> - if true computes only the special guess 817e26ad46dSJakub Kruzik . -pc_deflation_max_lvl <0> - maximum number of levels for multilevel deflation 818e26ad46dSJakub Kruzik . -pc_deflation_reduction_factor <-1> - reduction factor on bottom level coarse problem for PCTELESCOPE (default based on the size of the coarse problem) 819e26ad46dSJakub Kruzik . -pc_deflation_correction <false> - if true apply coarse problem correction 820e26ad46dSJakub Kruzik . -pc_deflation_correction_factor <1.0> - sets coarse problem correction factor 821e26ad46dSJakub Kruzik . -pc_deflation_compute_space <haar> - compute PCDeflationSpaceType deflation space 822e26ad46dSJakub Kruzik - -pc_deflation_compute_space_size <1> - size of the deflation space (corresponds to number of levels for wavelet-based deflation) 82337eeb815SJakub Kruzik 82437eeb815SJakub Kruzik Notes: 825*7e9012c5SJakub Kruzik Given a (complex - transpose is always Hermitian) full rank deflation matrix W, the deflation (introduced in [1,2]) 826e26ad46dSJakub Kruzik preconditioner uses projections Q = W*(W'*A*W)^{-1}*W' and P = I - Q*A, where A is pmat. 827e26ad46dSJakub Kruzik 828e26ad46dSJakub Kruzik The deflation computes initial guess x0 = x_{-1} - Q*r_{-1}, which is the solution on the deflation space. 829e26ad46dSJakub Kruzik If PCDeflationSetInitOnly() or -pc_deflation_init_only is set to PETSC_TRUE (InitDef scheme), the application of the 830e26ad46dSJakub Kruzik preconditioner consists only of application of the additional preconditioner M^{-1}. Otherwise, the preconditioner 8311fdb00f9SJakub Kruzik application consists of P*M^{-1} + factor*Q. The first part of the preconditioner (PM^{-1}) shifts some eigenvalues 832e26ad46dSJakub Kruzik to zero while the addition of the coarse problem correction (factor*Q) makes the preconditioner to shift some 833e26ad46dSJakub Kruzik eigenvalues to the given factor. The InitDef scheme is recommended for deflation using high accuracy estimates 834e26ad46dSJakub Kruzik of eigenvectors of A when it exhibits similar convergence to the full deflation but is cheaper. 835e26ad46dSJakub Kruzik 836e26ad46dSJakub Kruzik The deflation matrix is by default automatically computed. The type of deflation matrix and its size to compute can 837e26ad46dSJakub Kruzik be controlled by PCDeflationSetSpaceToCompute() or -pc_deflation_compute_space and -pc_deflation_compute_space_size. 838e26ad46dSJakub Kruzik User can set an arbitrary deflation space matrix with PCDeflationSetSpace(). If the deflation matrix 839e26ad46dSJakub Kruzik is a multiplicative MATCOMPOSITE, a multilevel deflation [3] is used. The first matrix in the composite is used as the 8401fdb00f9SJakub Kruzik deflation matrix, and the coarse problem (W'*A*W)^{-1} is solved by KSPFCG (if A is MAT_SPD) or KSPFGMRES preconditioned 841e26ad46dSJakub Kruzik by deflation with deflation matrix being the next matrix in the MATCOMPOSITE. This scheme repeats until the maximum 8421fdb00f9SJakub Kruzik level is reached or there are no more matrices. If the maximum level is reached, the remaining matrices are merged 8431fdb00f9SJakub Kruzik (multiplied) to create the last deflation matrix. The maximum level defaults to 0 and can be set by 84493b79a5aSJakub Kruzik PCDeflationSetLevels() or by -pc_deflation_levels. 845e26ad46dSJakub Kruzik 8466c93e71cSJakub Kruzik The coarse problem KSP can be controlled from the command line with prefix -def_ for the first level and -def_[lvl-1] 8476c93e71cSJakub Kruzik from the second level onward. You can also use 8488c4db21fSJakub Kruzik PCDeflationGetCoarseKSP() to control it from code. The bottom level KSP defaults to 8491fdb00f9SJakub Kruzik KSPPREONLY with PCLU direct solver (MATSOLVERSUPERLU/MATSOLVERSUPERLU_DIST if available) wrapped into PCTELESCOPE. 850481b7641SJakub Kruzik For convenience, the reduction factor can be set by PCDeflationSetReductionFactor() 851481b7641SJakub Kruzik or -pc_deflation_recduction_factor. The default is chosen heuristically based on the coarse problem size. 852e26ad46dSJakub Kruzik 8536c93e71cSJakub Kruzik The additional preconditioner can be controlled from command line with prefix -def_[lvl]_pc (same rules used for 8546c93e71cSJakub Kruzik coarse problem KSP apply for [lvl]_ part of prefix), e.g., -def_1_pc_pc_type bjacobi. You can also use 8558c4db21fSJakub Kruzik PCDeflationGetPC() to control the additional preconditioner from code. It defaults to PCNONE. 856e26ad46dSJakub Kruzik 857e26ad46dSJakub Kruzik The coarse problem correction term (factor*Q) can be turned on by -pc_deflation_correction and the factor value can 858e26ad46dSJakub Kruzik be set by pc_deflation_correction_factor or by PCDeflationSetCorrectionFactor(). The coarse problem can 859e26ad46dSJakub Kruzik significantly improve convergence when the deflation coarse problem is not solved with high enough accuracy. We 860e26ad46dSJakub Kruzik recommend setting factor to some eigenvalue, e.g., the largest eigenvalue so that the preconditioner does not create 861e26ad46dSJakub Kruzik an isolated eigenvalue. 862e26ad46dSJakub Kruzik 8631fdb00f9SJakub Kruzik The options are automatically inherited from the previous deflation level. 8649f604af8SJakub Kruzik 865e26ad46dSJakub Kruzik The preconditioner supports KSPMonitorDynamicTolerance(). This is useful for the multilevel scheme for which we also 8661fdb00f9SJakub Kruzik recommend limiting the number of iterations for the coarse problems. 867e26ad46dSJakub Kruzik 868e26ad46dSJakub Kruzik See section 3 of [4] for additional references and decription of the algorithm when used for conjugate gradients. 869e26ad46dSJakub Kruzik Section 4 describes some possible choices for the deflation space. 870e26ad46dSJakub Kruzik 871e26ad46dSJakub Kruzik Developer Notes: 872e26ad46dSJakub Kruzik Contributed by Jakub Kruzik (PERMON), Institute of Geonics of the Czech 873e26ad46dSJakub Kruzik Academy of Sciences and VSB - TU Ostrava. 874e26ad46dSJakub Kruzik 875e26ad46dSJakub Kruzik Developed from PERMON code used in [4] while on a research stay with 876e26ad46dSJakub Kruzik Prof. Reinhard Nabben at the Institute of Mathematics, TU Berlin. 877e26ad46dSJakub Kruzik 878e26ad46dSJakub Kruzik References: 879e26ad46dSJakub Kruzik + [1] - A. Nicolaides. “Deflation of conjugate gradients with applications to boundary valueproblems”, SIAM J. Numer. Anal. 24.2, 1987. 880e26ad46dSJakub Kruzik . [2] - Z. Dostal. "Conjugate gradient method with preconditioning by projector", Int J. Comput. Math. 23.3-4, 1988. 881e26ad46dSJakub 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. 8821fdb00f9SJakub 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 883e26ad46dSJakub Kruzik 884e26ad46dSJakub Kruzik Level: intermediate 88537eeb815SJakub Kruzik 88637eeb815SJakub Kruzik .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 88793b79a5aSJakub Kruzik PCDeflationSetInitOnly(), PCDeflationSetLevels(), PCDeflationSetReductionFactor(), 8881fdb00f9SJakub Kruzik PCDeflationSetCorrectionFactor(), PCDeflationSetSpaceToCompute(), 889e26ad46dSJakub Kruzik PCDeflationSetSpace(), PCDeflationSpaceType, PCDeflationSetProjectionNullSpaceMat(), 8908c4db21fSJakub Kruzik PCDeflationSetCoarseMat(), PCDeflationGetCoarseKSP(), PCDeflationGetPC() 89137eeb815SJakub Kruzik M*/ 89237eeb815SJakub Kruzik 89337eeb815SJakub Kruzik PETSC_EXTERN PetscErrorCode PCCreate_Deflation(PC pc) 89437eeb815SJakub Kruzik { 89537eeb815SJakub Kruzik PC_Deflation *def; 89637eeb815SJakub Kruzik PetscErrorCode ierr; 89737eeb815SJakub Kruzik 89837eeb815SJakub Kruzik PetscFunctionBegin; 89937eeb815SJakub Kruzik ierr = PetscNewLog(pc,&def);CHKERRQ(ierr); 90037eeb815SJakub Kruzik pc->data = (void*)def; 90137eeb815SJakub Kruzik 902e662bc50SJakub Kruzik def->init = PETSC_FALSE; 903e662bc50SJakub Kruzik def->correct = PETSC_FALSE; 904fcb31d99SJakub Kruzik def->correctfact = 1.0; 905e662bc50SJakub Kruzik def->reductionfact = -1; 906e662bc50SJakub Kruzik def->spacetype = PC_DEFLATION_SPACE_HAAR; 907e662bc50SJakub Kruzik def->spacesize = 1; 908e662bc50SJakub Kruzik def->extendsp = PETSC_FALSE; 9096c93e71cSJakub Kruzik def->lvl = 0; 9106c93e71cSJakub Kruzik def->maxlvl = 0; 91137eeb815SJakub Kruzik 91237eeb815SJakub Kruzik pc->ops->apply = PCApply_Deflation; 913b27c8092SJakub Kruzik pc->ops->presolve = PCPreSolve_Deflation; 91437eeb815SJakub Kruzik pc->ops->setup = PCSetUp_Deflation; 91537eeb815SJakub Kruzik pc->ops->reset = PCReset_Deflation; 91637eeb815SJakub Kruzik pc->ops->destroy = PCDestroy_Deflation; 91737eeb815SJakub Kruzik pc->ops->setfromoptions = PCSetFromOptions_Deflation; 9188513960bSJakub Kruzik pc->ops->view = PCView_Deflation; 91937eeb815SJakub Kruzik 920a122ebaeSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetInitOnly_C",PCDeflationSetInitOnly_Deflation);CHKERRQ(ierr); 92193b79a5aSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetLevels_C",PCDeflationSetLevels_Deflation);CHKERRQ(ierr); 922859a873cSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetReductionFactor_C",PCDeflationSetReductionFactor_Deflation);CHKERRQ(ierr); 9238a71cb68SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetCorrectionFactor_C",PCDeflationSetCorrectionFactor_Deflation);CHKERRQ(ierr); 92439417d7eSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetSpaceToCompute_C",PCDeflationSetSpaceToCompute_Deflation);CHKERRQ(ierr); 925e662bc50SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetSpace_C",PCDeflationSetSpace_Deflation);CHKERRQ(ierr); 9263cf3a049SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetProjectionNullSpaceMat_C",PCDeflationSetProjectionNullSpaceMat_Deflation);CHKERRQ(ierr); 927e924b002SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetCoarseMat_C",PCDeflationSetCoarseMat_Deflation);CHKERRQ(ierr); 9284a99276eSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationGetCoarseKSP_C",PCDeflationGetCoarseKSP_Deflation);CHKERRQ(ierr); 92998d6e3deSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationGetPC_C",PCDeflationGetPC_Deflation);CHKERRQ(ierr); 93037eeb815SJakub Kruzik PetscFunctionReturn(0); 93137eeb815SJakub Kruzik } 93237eeb815SJakub Kruzik 933