xref: /petsc/src/ksp/pc/impls/factor/factimpl.c (revision b2a8bc5c908ef2af5b08c02a70bef9ae6ac1e274)
1 #define PETSCKSP_DLL
2 
3 #include "../src/ksp/pc/impls/factor/factor.h"     /*I "petscpc.h"  I*/
4 
5 /* ------------------------------------------------------------------------------------------*/
6 
7 EXTERN_C_BEGIN
8 #undef __FUNCT__
9 #define __FUNCT__ "PCFactorSetZeroPivot_Factor"
10 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetZeroPivot_Factor(PC pc,PetscReal z)
11 {
12   PC_Factor *ilu = (PC_Factor*)pc->data;
13 
14   PetscFunctionBegin;
15   ilu->info.zeropivot = z;
16   PetscFunctionReturn(0);
17 }
18 EXTERN_C_END
19 
20 EXTERN_C_BEGIN
21 #undef __FUNCT__
22 #define __FUNCT__ "PCFactorSetShiftNonzero_Factor"
23 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetShiftNonzero_Factor(PC pc,PetscReal shift)
24 {
25   PC_Factor *dir = (PC_Factor*)pc->data;
26 
27   PetscFunctionBegin;
28   if (shift == (PetscReal) PETSC_DECIDE) {
29     dir->info.shiftnz = 1.e-12;
30   } else {
31     dir->info.shiftnz = shift;
32   }
33   PetscFunctionReturn(0);
34 }
35 EXTERN_C_END
36 
37 EXTERN_C_BEGIN
38 #undef __FUNCT__
39 #define __FUNCT__ "PCFactorSetShiftPd_Factor"
40 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetShiftPd_Factor(PC pc,PetscTruth shift)
41 {
42   PC_Factor *dir = (PC_Factor*)pc->data;
43 
44   PetscFunctionBegin;
45   if (shift) {
46     dir->info.shiftpd = 1.0;
47   } else {
48     dir->info.shiftpd = 0.0;
49   }
50   PetscFunctionReturn(0);
51 }
52 EXTERN_C_END
53 
54 EXTERN_C_BEGIN
55 #undef __FUNCT__
56 #define __FUNCT__ "PCFactorSetUseDropTolerance_Factor"
57 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetUseDropTolerance_Factor(PC pc,PetscReal dt,PetscReal dtcol,PetscInt dtcount)
58 {
59   PC_Factor         *ilu = (PC_Factor*)pc->data;
60 
61   PetscFunctionBegin;
62   if (pc->setupcalled && (!ilu->info.usedt || ((PC_Factor*)ilu)->info.dt != dt || ((PC_Factor*)ilu)->info.dtcol != dtcol || ((PC_Factor*)ilu)->info.dtcount != dtcount)) {
63     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot change tolerance after use");
64   }
65   ilu->info.usedt   = PETSC_TRUE;
66   ilu->info.dt      = dt;
67   ilu->info.dtcol   = dtcol;
68   ilu->info.dtcount = dtcount;
69   ilu->info.fill    = PETSC_DEFAULT;
70   PetscFunctionReturn(0);
71 }
72 EXTERN_C_END
73 
74 EXTERN_C_BEGIN
75 #undef __FUNCT__
76 #define __FUNCT__ "PCFactorSetFill_Factor"
77 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetFill_Factor(PC pc,PetscReal fill)
78 {
79   PC_Factor *dir = (PC_Factor*)pc->data;
80 
81   PetscFunctionBegin;
82   dir->info.fill = fill;
83   PetscFunctionReturn(0);
84 }
85 EXTERN_C_END
86 
87 EXTERN_C_BEGIN
88 #undef __FUNCT__
89 #define __FUNCT__ "PCFactorSetMatOrderingType_Factor"
90 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetMatOrderingType_Factor(PC pc,const MatOrderingType ordering)
91 {
92   PC_Factor      *dir = (PC_Factor*)pc->data;
93   PetscErrorCode ierr;
94   PetscTruth     flg;
95 
96   PetscFunctionBegin;
97   if (!pc->setupcalled) {
98      ierr = PetscStrfree(dir->ordering);CHKERRQ(ierr);
99      ierr = PetscStrallocpy(ordering,&dir->ordering);CHKERRQ(ierr);
100   } else {
101     ierr = PetscStrcmp(dir->ordering,ordering,&flg);CHKERRQ(ierr);
102     if (!flg) {
103       SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot change ordering after use");
104     }
105   }
106   PetscFunctionReturn(0);
107 }
108 EXTERN_C_END
109 
110 EXTERN_C_BEGIN
111 #undef __FUNCT__
112 #define __FUNCT__ "PCFactorSetLevels_Factor"
113 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetLevels_Factor(PC pc,PetscInt levels)
114 {
115   PC_Factor      *ilu = (PC_Factor*)pc->data;
116 
117   PetscFunctionBegin;
118   if (!pc->setupcalled) {
119     ilu->info.levels = levels;
120   } else if (ilu->info.usedt || ilu->info.levels != levels) {
121     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot change levels after use");
122   }
123   PetscFunctionReturn(0);
124 }
125 EXTERN_C_END
126 
127 EXTERN_C_BEGIN
128 #undef __FUNCT__
129 #define __FUNCT__ "PCFactorSetAllowDiagonalFill_Factor"
130 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetAllowDiagonalFill_Factor(PC pc)
131 {
132   PC_Factor *dir = (PC_Factor*)pc->data;
133 
134   PetscFunctionBegin;
135   dir->info.diagonal_fill = 1;
136   PetscFunctionReturn(0);
137 }
138 EXTERN_C_END
139 
140 
141 /* ------------------------------------------------------------------------------------------*/
142 
143 EXTERN_C_BEGIN
144 #undef __FUNCT__
145 #define __FUNCT__ "PCFactorSetPivotInBlocks_Factor"
146 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetPivotInBlocks_Factor(PC pc,PetscTruth pivot)
147 {
148   PC_Factor *dir = (PC_Factor*)pc->data;
149 
150   PetscFunctionBegin;
151   dir->info.pivotinblocks = pivot ? 1.0 : 0.0;
152   PetscFunctionReturn(0);
153 }
154 EXTERN_C_END
155 
156 EXTERN_C_BEGIN
157 #undef __FUNCT__
158 #define __FUNCT__ "PCFactorSetShiftInBlocks_Factor"
159 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetShiftInBlocks_Factor(PC pc,PetscReal shift)
160 {
161   PC_Factor *dir = (PC_Factor*)pc->data;
162 
163   PetscFunctionBegin;
164   if (shift == PETSC_DEFAULT) {
165     dir->info.shiftinblocks = 1.e-12;
166   } else {
167     dir->info.shiftinblocks = shift;
168   }
169   PetscFunctionReturn(0);
170 }
171 EXTERN_C_END
172 
173 
174 EXTERN_C_BEGIN
175 #undef __FUNCT__
176 #define __FUNCT__ "PCFactorGetMatrix_Factor"
177 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorGetMatrix_Factor(PC pc,Mat *mat)
178 {
179   PC_Factor *ilu = (PC_Factor*)pc->data;
180 
181   PetscFunctionBegin;
182   if (!ilu->fact) SETERRQ(PETSC_ERR_ORDER,"Matrix not yet factored; call after KSPSetUp() or PCSetUp()");
183   *mat = ilu->fact;
184   PetscFunctionReturn(0);
185 }
186 EXTERN_C_END
187 
188 EXTERN_C_BEGIN
189 #undef __FUNCT__
190 #define __FUNCT__ "PCFactorSetMatSolverPackage_Factor"
191 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetMatSolverPackage_Factor(PC pc,const MatSolverPackage stype)
192 {
193   PetscErrorCode ierr;
194   PC_Factor      *lu = (PC_Factor*)pc->data;
195 
196   PetscFunctionBegin;
197   if (lu->fact) {
198     const MatSolverPackage ltype;
199     PetscTruth             flg;
200     ierr = MatFactorGetSolverPackage(lu->fact,&ltype);CHKERRQ(ierr);
201     ierr = PetscStrcmp(stype,ltype,&flg);CHKERRQ(ierr);
202     if (!flg) {
203       SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot change solver matrix package after PC has been setup or used");
204     }
205   }
206   ierr = PetscStrfree(lu->solvertype);CHKERRQ(ierr);
207   ierr = PetscStrallocpy(stype,&lu->solvertype);CHKERRQ(ierr);
208   PetscFunctionReturn(0);
209 }
210 EXTERN_C_END
211 
212 EXTERN_C_BEGIN
213 #undef __FUNCT__
214 #define __FUNCT__ "PCFactorGetMatSolverPackage_Factor"
215 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorGetMatSolverPackage_Factor(PC pc,const MatSolverPackage *stype)
216 {
217   PC_Factor      *lu = (PC_Factor*)pc->data;
218 
219   PetscFunctionBegin;
220   *stype = lu->solvertype;
221   PetscFunctionReturn(0);
222 }
223 EXTERN_C_END
224 
225 EXTERN_C_BEGIN
226 #undef __FUNCT__
227 #define __FUNCT__ "PCFactorSetColumnPivot_Factor"
228 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetColumnPivot_Factor(PC pc,PetscReal dtcol)
229 {
230   PC_Factor       *dir = (PC_Factor*)pc->data;
231 
232   PetscFunctionBegin;
233   if (dtcol < 0.0 || dtcol > 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Column pivot tolerance is %G must be between 0 and 1",dtcol);
234   dir->info.dtcol = dtcol;
235   PetscFunctionReturn(0);
236 }
237 EXTERN_C_END
238 
239 EXTERN_C_BEGIN
240 #undef __FUNCT__
241 #define __FUNCT__ "PCSetFromOptions_Factor"
242 PetscErrorCode PETSCKSP_DLLEXPORT PCSetFromOptions_Factor(PC pc)
243 {
244   PC_Factor       *factor = (PC_Factor*)pc->data;
245   PetscErrorCode  ierr;
246   PetscTruth      flg = PETSC_FALSE,set;
247   char            tname[256], solvertype[64];
248   PetscFList      ordlist;
249 
250   PetscFunctionBegin;
251   if (!MatOrderingRegisterAllCalled) {ierr = MatOrderingRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
252   ierr = PetscOptionsTruth("-pc_factor_in_place","Form factored matrix in the same memory as the matrix","PCFactorSetUseInPlace",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
253     if (flg) {
254       ierr = PCFactorSetUseInPlace(pc);CHKERRQ(ierr);
255     }
256     ierr = PetscOptionsReal("-pc_factor_fill","Expected non-zeros in factored matrix","PCFactorSetFill",((PC_Factor*)factor)->info.fill,&((PC_Factor*)factor)->info.fill,0);CHKERRQ(ierr);
257 
258     flg  = PETSC_FALSE;
259     ierr = PetscOptionsName("-pc_factor_shift_nonzero","Shift added to diagonal","PCFactorSetShiftNonzero",&flg);CHKERRQ(ierr);
260     if (flg) {
261       ierr = PCFactorSetShiftNonzero(pc,(PetscReal) PETSC_DECIDE);CHKERRQ(ierr);
262     }
263     ierr = PetscOptionsReal("-pc_factor_shift_nonzero","Shift added to diagonal","PCFactorSetShiftNonzero",((PC_Factor*)factor)->info.shiftnz,&((PC_Factor*)factor)->info.shiftnz,0);CHKERRQ(ierr);
264     flg  = PETSC_FALSE;
265     ierr = PetscOptionsTruth("-pc_factor_shift_positive_definite","Manteuffel shift applied to diagonal","PCFactorSetShiftPd",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
266     if (flg) {
267       ierr = PCFactorSetShiftPd(pc,PETSC_TRUE);CHKERRQ(ierr);
268     }
269     flg  = PETSC_FALSE;
270     ierr = PetscOptionsName("-pc_factor_shift_in_blocks","Shift added to diagonal dense blocks","PCFactorSetShiftInBlocks",&flg);CHKERRQ(ierr);
271     if (flg) {
272       ierr = PCFactorSetShiftInBlocks(pc,(PetscReal) PETSC_DEFAULT);CHKERRQ(ierr);
273     }
274     ierr = PetscOptionsReal("-pc_factor_shift_in_blocks","Shift added to diagonal dense blocks","PCFactorSetShiftInBlocks",((PC_Factor*)factor)->info.shiftinblocks,&((PC_Factor*)factor)->info.shiftinblocks,0);CHKERRQ(ierr);
275 
276     ierr = PetscOptionsReal("-pc_factor_zeropivot","Pivot is considered zero if less than","PCFactorSetZeroPivot",((PC_Factor*)factor)->info.zeropivot,&((PC_Factor*)factor)->info.zeropivot,0);CHKERRQ(ierr);
277     ierr = PetscOptionsReal("-pc_factor_column_pivot","Column pivot tolerance (used only for some factorization)","PCFactorSetColumnPivot",((PC_Factor*)factor)->info.dtcol,&((PC_Factor*)factor)->info.dtcol,&flg);CHKERRQ(ierr);
278 
279     flg = ((PC_Factor*)factor)->info.pivotinblocks ? PETSC_TRUE : PETSC_FALSE;
280     ierr = PetscOptionsTruth("-pc_factor_pivot_in_blocks","Pivot inside matrix dense blocks for BAIJ and SBAIJ","PCFactorSetPivotInBlocks",flg,&flg,&set);CHKERRQ(ierr);
281     if (set) {
282       ierr = PCFactorSetPivotInBlocks(pc,flg);CHKERRQ(ierr);
283     }
284 
285     flg  = PETSC_FALSE;
286     ierr = PetscOptionsTruth("-pc_factor_reuse_fill","Use fill from previous factorization","PCFactorSetReuseFill",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
287     if (flg) {
288       ierr = PCFactorSetReuseFill(pc,PETSC_TRUE);CHKERRQ(ierr);
289     }
290     flg  = PETSC_FALSE;
291     ierr = PetscOptionsTruth("-pc_factor_reuse_ordering","Reuse ordering from previous factorization","PCFactorSetReuseOrdering",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
292     if (flg) {
293       ierr = PCFactorSetReuseOrdering(pc,PETSC_TRUE);CHKERRQ(ierr);
294     }
295 
296     ierr = MatGetOrderingList(&ordlist);CHKERRQ(ierr);
297     ierr = PetscOptionsList("-pc_factor_mat_ordering_type","Reordering to reduce nonzeros in factored matrix","PCFactorSetMatOrderingType",ordlist,((PC_Factor*)factor)->ordering,tname,256,&flg);CHKERRQ(ierr);
298     if (flg) {
299       ierr = PCFactorSetMatOrderingType(pc,tname);CHKERRQ(ierr);
300     }
301 
302     /* maybe should have MatGetSolverTypes(Mat,&list) like the ordering list */
303     ierr = PetscOptionsString("-pc_factor_mat_solver_package","Specific direct solver to use","MatGetFactor",((PC_Factor*)factor)->solvertype,solvertype,64,&flg);CHKERRQ(ierr);
304     if (flg) {
305       ierr = PCFactorSetMatSolverPackage(pc,solvertype);CHKERRQ(ierr);
306     }
307 
308     /*
309     ierr = PetscOptionsReal("-pc_factor_column_pivot","Column pivot tolerance (used only for some factorization)","PCFactorSetColumnPivot",((PC_Factor*)factor)->info.dtcol,&((PC_Factor*)factor)->info.dtcol,&flg);CHKERRQ(ierr);
310 
311     flg = ((PC_Factor*)factor)->info.pivotinblocks ? PETSC_TRUE : PETSC_FALSE;
312     ierr = PetscOptionsTruth("-pc_factor_pivot_in_blocks","Pivot inside matrix dense blocks for BAIJ and SBAIJ","PCFactorSetPivotInBlocks",flg,&flg,&set);CHKERRQ(ierr);
313     if (set) {
314       ierr = PCFactorSetPivotInBlocks(pc,flg);CHKERRQ(ierr);
315     }
316     */
317   PetscFunctionReturn(0);
318 }
319 EXTERN_C_END
320