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