1 2 #include <../src/ksp/pc/impls/factor/icc/icc.h> /*I "petscpc.h" I*/ 3 4 static PetscErrorCode PCSetUp_ICC(PC pc) 5 { 6 PC_ICC *icc = (PC_ICC*)pc->data; 7 IS perm = NULL,cperm = NULL; 8 MatInfo info; 9 MatSolverType stype; 10 MatFactorError err; 11 PetscBool canuseordering; 12 const char *prefix; 13 14 PetscFunctionBegin; 15 PetscCall(PCGetOptionsPrefix(pc,&prefix)); 16 PetscCall(MatSetOptionsPrefix(pc->pmat,prefix)); 17 pc->failedreason = PC_NOERROR; 18 19 PetscCall(MatSetErrorIfFailure(pc->pmat,pc->erroriffailure)); 20 if (!pc->setupcalled) { 21 if (!((PC_Factor*)icc)->fact) { 22 PetscCall(MatGetFactor(pc->pmat,((PC_Factor*)icc)->solvertype,MAT_FACTOR_ICC,&((PC_Factor*)icc)->fact)); 23 } 24 PetscCall(MatFactorGetCanUseOrdering(((PC_Factor*)icc)->fact,&canuseordering)); 25 if (canuseordering) { 26 PetscCall(PCFactorSetDefaultOrdering_Factor(pc)); 27 PetscCall(MatGetOrdering(pc->pmat, ((PC_Factor*)icc)->ordering,&perm,&cperm)); 28 } 29 PetscCall(MatICCFactorSymbolic(((PC_Factor*)icc)->fact,pc->pmat,perm,&((PC_Factor*)icc)->info)); 30 } else if (pc->flag != SAME_NONZERO_PATTERN) { 31 PetscBool canuseordering; 32 PetscCall(MatDestroy(&((PC_Factor*)icc)->fact)); 33 PetscCall(MatGetFactor(pc->pmat,((PC_Factor*)icc)->solvertype,MAT_FACTOR_ICC,&((PC_Factor*)icc)->fact)); 34 PetscCall(MatFactorGetCanUseOrdering(((PC_Factor*)icc)->fact,&canuseordering)); 35 if (canuseordering) { 36 PetscCall(PCFactorSetDefaultOrdering_Factor(pc)); 37 PetscCall(MatGetOrdering(pc->pmat, ((PC_Factor*)icc)->ordering,&perm,&cperm)); 38 } 39 PetscCall(MatICCFactorSymbolic(((PC_Factor*)icc)->fact,pc->pmat,perm,&((PC_Factor*)icc)->info)); 40 } 41 PetscCall(MatGetInfo(((PC_Factor*)icc)->fact,MAT_LOCAL,&info)); 42 icc->hdr.actualfill = info.fill_ratio_needed; 43 44 PetscCall(ISDestroy(&cperm)); 45 PetscCall(ISDestroy(&perm)); 46 47 PetscCall(MatFactorGetError(((PC_Factor*)icc)->fact,&err)); 48 if (err) { /* FactorSymbolic() fails */ 49 pc->failedreason = (PCFailedReason)err; 50 PetscFunctionReturn(0); 51 } 52 53 PetscCall(MatCholeskyFactorNumeric(((PC_Factor*)icc)->fact,pc->pmat,&((PC_Factor*)icc)->info)); 54 PetscCall(MatFactorGetError(((PC_Factor*)icc)->fact,&err)); 55 if (err) { /* FactorNumeric() fails */ 56 pc->failedreason = (PCFailedReason)err; 57 } 58 59 PetscCall(PCFactorGetMatSolverType(pc,&stype)); 60 if (!stype) { 61 MatSolverType solverpackage; 62 PetscCall(MatFactorGetSolverType(((PC_Factor*)icc)->fact,&solverpackage)); 63 PetscCall(PCFactorSetMatSolverType(pc,solverpackage)); 64 } 65 PetscFunctionReturn(0); 66 } 67 68 static PetscErrorCode PCReset_ICC(PC pc) 69 { 70 PC_ICC *icc = (PC_ICC*)pc->data; 71 72 PetscFunctionBegin; 73 PetscCall(MatDestroy(&((PC_Factor*)icc)->fact)); 74 PetscFunctionReturn(0); 75 } 76 77 static PetscErrorCode PCDestroy_ICC(PC pc) 78 { 79 PC_ICC *icc = (PC_ICC*)pc->data; 80 81 PetscFunctionBegin; 82 PetscCall(PCReset_ICC(pc)); 83 PetscCall(PetscFree(((PC_Factor*)icc)->ordering)); 84 PetscCall(PetscFree(((PC_Factor*)icc)->solvertype)); 85 PetscCall(PetscFree(pc->data)); 86 PetscFunctionReturn(0); 87 } 88 89 static PetscErrorCode PCApply_ICC(PC pc,Vec x,Vec y) 90 { 91 PC_ICC *icc = (PC_ICC*)pc->data; 92 93 PetscFunctionBegin; 94 PetscCall(MatSolve(((PC_Factor*)icc)->fact,x,y)); 95 PetscFunctionReturn(0); 96 } 97 98 static PetscErrorCode PCMatApply_ICC(PC pc,Mat X,Mat Y) 99 { 100 PC_ICC *icc = (PC_ICC*)pc->data; 101 102 PetscFunctionBegin; 103 PetscCall(MatMatSolve(((PC_Factor*)icc)->fact,X,Y)); 104 PetscFunctionReturn(0); 105 } 106 107 static PetscErrorCode PCApplySymmetricLeft_ICC(PC pc,Vec x,Vec y) 108 { 109 PC_ICC *icc = (PC_ICC*)pc->data; 110 111 PetscFunctionBegin; 112 PetscCall(MatForwardSolve(((PC_Factor*)icc)->fact,x,y)); 113 PetscFunctionReturn(0); 114 } 115 116 static PetscErrorCode PCApplySymmetricRight_ICC(PC pc,Vec x,Vec y) 117 { 118 PC_ICC *icc = (PC_ICC*)pc->data; 119 120 PetscFunctionBegin; 121 PetscCall(MatBackwardSolve(((PC_Factor*)icc)->fact,x,y)); 122 PetscFunctionReturn(0); 123 } 124 125 static PetscErrorCode PCSetFromOptions_ICC(PetscOptionItems *PetscOptionsObject,PC pc) 126 { 127 PC_ICC *icc = (PC_ICC*)pc->data; 128 PetscBool flg; 129 /* PetscReal dt[3];*/ 130 131 PetscFunctionBegin; 132 PetscOptionsHeadBegin(PetscOptionsObject,"ICC Options"); 133 PetscCall(PCSetFromOptions_Factor(PetscOptionsObject,pc)); 134 135 PetscCall(PetscOptionsReal("-pc_factor_levels","levels of fill","PCFactorSetLevels",((PC_Factor*)icc)->info.levels,&((PC_Factor*)icc)->info.levels,&flg)); 136 /*dt[0] = ((PC_Factor*)icc)->info.dt; 137 dt[1] = ((PC_Factor*)icc)->info.dtcol; 138 dt[2] = ((PC_Factor*)icc)->info.dtcount; 139 PetscInt dtmax = 3; 140 PetscCall(PetscOptionsRealArray("-pc_factor_drop_tolerance","<dt,dtcol,maxrowcount>","PCFactorSetDropTolerance",dt,&dtmax,&flg)); 141 if (flg) { 142 PetscCall(PCFactorSetDropTolerance(pc,dt[0],dt[1],(PetscInt)dt[2])); 143 } 144 */ 145 PetscOptionsHeadEnd(); 146 PetscFunctionReturn(0); 147 } 148 149 extern PetscErrorCode PCFactorSetDropTolerance_ILU(PC,PetscReal,PetscReal,PetscInt); 150 151 /*MC 152 PCICC - Incomplete Cholesky factorization preconditioners. 153 154 Options Database Keys: 155 + -pc_factor_levels <k> - number of levels of fill for ICC(k) 156 . -pc_factor_in_place - only for ICC(0) with natural ordering, reuses the space of the matrix for 157 its factorization (overwrites original matrix) 158 . -pc_factor_fill <nfill> - expected amount of fill in factored matrix compared to original matrix, nfill > 1 159 - -pc_factor_mat_ordering_type <natural,nd,1wd,rcm,qmd> - set the row/column ordering of the factored matrix 160 161 Level: beginner 162 163 Notes: 164 Only implemented for some matrix formats. Not implemented in parallel. 165 166 For BAIJ matrices this implements a point block ICC. 167 168 The Manteuffel shift is only implemented for matrices with block size 1 169 170 By default, the Manteuffel is applied (for matrices with block size 1). Call PCFactorSetShiftType(pc,MAT_SHIFT_POSITIVE_DEFINITE); 171 to turn off the shift. 172 173 References: 174 . * - TONY F. CHAN AND HENK A. VAN DER VORST, Review article: APPROXIMATE AND INCOMPLETE FACTORIZATIONS, 175 Chapter in Parallel Numerical Algorithms, edited by D. Keyes, A. Semah, V. Venkatakrishnan, ICASE/LaRC Interdisciplinary Series in 176 Science and Engineering, Kluwer. 177 178 .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`, `PCSOR`, `MatOrderingType`, 179 `PCFactorSetZeroPivot()`, `PCFactorSetShiftType()`, `PCFactorSetShiftAmount()`, 180 `PCFactorSetFill()`, `PCFactorSetMatOrderingType()`, `PCFactorSetReuseOrdering()`, 181 `PCFactorSetLevels()` 182 183 M*/ 184 185 PETSC_EXTERN PetscErrorCode PCCreate_ICC(PC pc) 186 { 187 PC_ICC *icc; 188 189 PetscFunctionBegin; 190 PetscCall(PetscNewLog(pc,&icc)); 191 pc->data = (void*)icc; 192 PetscCall(PCFactorInitialize(pc, MAT_FACTOR_ICC)); 193 194 ((PC_Factor*)icc)->info.fill = 1.0; 195 ((PC_Factor*)icc)->info.dtcol = PETSC_DEFAULT; 196 ((PC_Factor*)icc)->info.shifttype = (PetscReal) MAT_SHIFT_POSITIVE_DEFINITE; 197 198 pc->ops->apply = PCApply_ICC; 199 pc->ops->matapply = PCMatApply_ICC; 200 pc->ops->applytranspose = PCApply_ICC; 201 pc->ops->setup = PCSetUp_ICC; 202 pc->ops->reset = PCReset_ICC; 203 pc->ops->destroy = PCDestroy_ICC; 204 pc->ops->setfromoptions = PCSetFromOptions_ICC; 205 pc->ops->view = PCView_Factor; 206 pc->ops->applysymmetricleft = PCApplySymmetricLeft_ICC; 207 pc->ops->applysymmetricright = PCApplySymmetricRight_ICC; 208 PetscFunctionReturn(0); 209 } 210