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