xref: /petsc/src/ksp/pc/impls/factor/factor.c (revision bcee047adeeb73090d7e36cc71e39fc287cdbb97)
1 
2 #include <../src/ksp/pc/impls/factor/factor.h> /*I "petscpc.h" I*/
3 #include <petsc/private/matimpl.h>
4 
5 /*
6     If an ordering is not yet set and the matrix is available determine a default ordering
7 */
8 PetscErrorCode PCFactorSetDefaultOrdering_Factor(PC pc)
9 {
10   PetscBool   foundmtype, flg, destroy = PETSC_FALSE;
11   const char *prefix;
12 
13   PetscFunctionBegin;
14   if (pc->pmat) {
15     PetscCall(PCGetOptionsPrefix(pc, &prefix));
16     PetscCall(MatSetOptionsPrefixFactor(pc->pmat, prefix));
17     PC_Factor *fact = (PC_Factor *)pc->data;
18     PetscCall(MatSolverTypeGet(fact->solvertype, ((PetscObject)pc->pmat)->type_name, fact->factortype, NULL, &foundmtype, NULL));
19     if (foundmtype) {
20       if (!fact->fact) {
21         /* factored matrix is not present at this point, we want to create it during PCSetUp.
22            Since this can be called from setfromoptions, we destroy it when we are done with it */
23         PetscCall(MatGetFactor(pc->pmat, fact->solvertype, fact->factortype, &fact->fact));
24         destroy = PETSC_TRUE;
25       }
26       if (!fact->fact) PetscFunctionReturn(PETSC_SUCCESS);
27       if (!fact->fact->assembled) {
28         PetscCall(PetscStrcmp(fact->solvertype, fact->fact->solvertype, &flg));
29         if (!flg) {
30           Mat B;
31           PetscCall(MatGetFactor(pc->pmat, fact->solvertype, fact->factortype, &B));
32           PetscCall(MatHeaderReplace(fact->fact, &B));
33         }
34       }
35       if (!fact->ordering) {
36         PetscBool       canuseordering;
37         MatOrderingType otype;
38 
39         PetscCall(MatFactorGetCanUseOrdering(fact->fact, &canuseordering));
40         if (canuseordering) {
41           PetscCall(MatFactorGetPreferredOrdering(fact->fact, fact->factortype, &otype));
42         } else otype = MATORDERINGEXTERNAL;
43         PetscCall(PetscStrallocpy(otype, (char **)&fact->ordering));
44       }
45       if (destroy) PetscCall(MatDestroy(&fact->fact));
46     }
47   }
48   PetscFunctionReturn(PETSC_SUCCESS);
49 }
50 
51 static PetscErrorCode PCFactorSetReuseOrdering_Factor(PC pc, PetscBool flag)
52 {
53   PC_Factor *lu = (PC_Factor *)pc->data;
54 
55   PetscFunctionBegin;
56   lu->reuseordering = flag;
57   PetscFunctionReturn(PETSC_SUCCESS);
58 }
59 
60 static PetscErrorCode PCFactorSetReuseFill_Factor(PC pc, PetscBool flag)
61 {
62   PC_Factor *lu = (PC_Factor *)pc->data;
63 
64   PetscFunctionBegin;
65   lu->reusefill = flag;
66   PetscFunctionReturn(PETSC_SUCCESS);
67 }
68 
69 static PetscErrorCode PCFactorSetUseInPlace_Factor(PC pc, PetscBool flg)
70 {
71   PC_Factor *dir = (PC_Factor *)pc->data;
72 
73   PetscFunctionBegin;
74   dir->inplace = flg;
75   PetscFunctionReturn(PETSC_SUCCESS);
76 }
77 
78 static PetscErrorCode PCFactorGetUseInPlace_Factor(PC pc, PetscBool *flg)
79 {
80   PC_Factor *dir = (PC_Factor *)pc->data;
81 
82   PetscFunctionBegin;
83   *flg = dir->inplace;
84   PetscFunctionReturn(PETSC_SUCCESS);
85 }
86 
87 /*@
88     PCFactorSetUpMatSolverType - Can be called after `KSPSetOperators()` or `PCSetOperators()`, causes `MatGetFactor()` to be called so then one may
89        set the options for that particular factorization object.
90 
91   Input Parameter:
92 .  pc  - the preconditioner context
93 
94   Note:
95   After you have called this function (which has to be after the `KSPSetOperators()` or `PCSetOperators()`) you can call `PCFactorGetMatrix()` and then set factor options on that matrix.
96   This function raises an error if the requested combination of solver package and matrix type is not supported.
97 
98   Level: intermediate
99 
100 .seealso: `PCCHOLESKY`, `PCLU`, `PCFactorSetMatSolverType()`, `PCFactorGetMatrix()`
101 @*/
102 PetscErrorCode PCFactorSetUpMatSolverType(PC pc)
103 {
104   PetscFunctionBegin;
105   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
106   PetscTryMethod(pc, "PCFactorSetUpMatSolverType_C", (PC), (pc));
107   PetscFunctionReturn(PETSC_SUCCESS);
108 }
109 
110 /*@
111    PCFactorSetZeroPivot - Sets the size at which smaller pivots are declared to be zero
112 
113    Logically Collective
114 
115    Input Parameters:
116 +  pc - the preconditioner context
117 -  zero - all pivots smaller than this will be considered zero
118 
119    Options Database Key:
120 .  -pc_factor_zeropivot <zero> - Sets tolerance for what is considered a zero pivot
121 
122    Level: intermediate
123 
124 .seealso: `PCCHOLESKY`, `PCLU`, `PCFactorSetShiftType()`, `PCFactorSetShiftAmount()`
125 @*/
126 PetscErrorCode PCFactorSetZeroPivot(PC pc, PetscReal zero)
127 {
128   PetscFunctionBegin;
129   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
130   PetscValidLogicalCollectiveReal(pc, zero, 2);
131   PetscTryMethod(pc, "PCFactorSetZeroPivot_C", (PC, PetscReal), (pc, zero));
132   PetscFunctionReturn(PETSC_SUCCESS);
133 }
134 
135 /*@
136    PCFactorSetShiftType - adds a particular type of quantity to the diagonal of the matrix during
137      numerical factorization, thus the matrix has nonzero pivots
138 
139    Logically Collective
140 
141    Input Parameters:
142 +  pc - the preconditioner context
143 -  shifttype - type of shift; one of `MAT_SHIFT_NONE`, `MAT_SHIFT_NONZERO`, `MAT_SHIFT_POSITIVE_DEFINITE`, `MAT_SHIFT_INBLOCKS`
144 
145    Options Database Key:
146 .  -pc_factor_shift_type <shifttype> - Sets shift type; use '-help' for a list of available types
147 
148    Level: intermediate
149 
150 .seealso: `PCCHOLESKY`, `PCLU`, `PCFactorSetZeroPivot()`, `PCFactorSetShiftAmount()`
151 @*/
152 PetscErrorCode PCFactorSetShiftType(PC pc, MatFactorShiftType shifttype)
153 {
154   PetscFunctionBegin;
155   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
156   PetscValidLogicalCollectiveEnum(pc, shifttype, 2);
157   PetscTryMethod(pc, "PCFactorSetShiftType_C", (PC, MatFactorShiftType), (pc, shifttype));
158   PetscFunctionReturn(PETSC_SUCCESS);
159 }
160 
161 /*@
162    PCFactorSetShiftAmount - adds a quantity to the diagonal of the matrix during
163      numerical factorization, thus the matrix has nonzero pivots
164 
165    Logically Collective
166 
167    Input Parameters:
168 +  pc - the preconditioner context
169 -  shiftamount - amount of shift or `PETSC_DECIDE` for the default
170 
171    Options Database Key:
172 .  -pc_factor_shift_amount <shiftamount> - Sets shift amount or -1 for the default
173 
174    Level: intermediate
175 
176 .seealso: `PCCHOLESKY`, `PCLU`, ``PCFactorSetZeroPivot()`, `PCFactorSetShiftType()`
177 @*/
178 PetscErrorCode PCFactorSetShiftAmount(PC pc, PetscReal shiftamount)
179 {
180   PetscFunctionBegin;
181   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
182   PetscValidLogicalCollectiveReal(pc, shiftamount, 2);
183   PetscTryMethod(pc, "PCFactorSetShiftAmount_C", (PC, PetscReal), (pc, shiftamount));
184   PetscFunctionReturn(PETSC_SUCCESS);
185 }
186 
187 /*@
188    PCFactorSetDropTolerance - The preconditioner will use an `PCILU`
189    based on a drop tolerance.
190 
191    Logically Collective
192 
193    Input Parameters:
194 +  pc - the preconditioner context
195 .  dt - the drop tolerance, try from 1.e-10 to .1
196 .  dtcol - tolerance for column pivot, good values [0.1 to 0.01]
197 -  maxrowcount - the max number of nonzeros allowed in a row, best value
198                  depends on the number of nonzeros in row of original matrix
199 
200    Options Database Key:
201 .  -pc_factor_drop_tolerance <dt,dtcol,maxrowcount> - Sets drop tolerance
202 
203    Level: intermediate
204 
205    Note:
206    There are NO default values for the 3 parameters, you must set them with reasonable values for your
207    matrix. We don't know how to compute reasonable values.
208 
209 .seealso: `PCILU`
210 @*/
211 PetscErrorCode PCFactorSetDropTolerance(PC pc, PetscReal dt, PetscReal dtcol, PetscInt maxrowcount)
212 {
213   PetscFunctionBegin;
214   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
215   PetscValidLogicalCollectiveReal(pc, dtcol, 3);
216   PetscValidLogicalCollectiveInt(pc, maxrowcount, 4);
217   PetscTryMethod(pc, "PCFactorSetDropTolerance_C", (PC, PetscReal, PetscReal, PetscInt), (pc, dt, dtcol, maxrowcount));
218   PetscFunctionReturn(PETSC_SUCCESS);
219 }
220 
221 /*@
222    PCFactorGetZeroPivot - Gets the tolerance used to define a zero privot
223 
224    Not Collective
225 
226    Input Parameter:
227 .  pc - the preconditioner context
228 
229    Output Parameter:
230 .  pivot - the tolerance
231 
232    Level: intermediate
233 
234 .seealso: `PCLU`, `PCCHOLESKY`, `PCFactorSetZeroPivot()`
235 @*/
236 PetscErrorCode PCFactorGetZeroPivot(PC pc, PetscReal *pivot)
237 {
238   PetscFunctionBegin;
239   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
240   PetscUseMethod(pc, "PCFactorGetZeroPivot_C", (PC, PetscReal *), (pc, pivot));
241   PetscFunctionReturn(PETSC_SUCCESS);
242 }
243 
244 /*@
245    PCFactorGetShiftAmount - Gets the tolerance used to define a zero privot
246 
247    Not Collective
248 
249    Input Parameter:
250 .  pc - the preconditioner context
251 
252    Output Parameter:
253 .  shift - how much to shift the diagonal entry
254 
255    Level: intermediate
256 
257 .seealso: `PCLU`, `PCCHOLESKY`, `PCFactorSetShiftAmount()`, `PCFactorSetShiftType()`, `PCFactorGetShiftType()`
258 @*/
259 PetscErrorCode PCFactorGetShiftAmount(PC pc, PetscReal *shift)
260 {
261   PetscFunctionBegin;
262   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
263   PetscUseMethod(pc, "PCFactorGetShiftAmount_C", (PC, PetscReal *), (pc, shift));
264   PetscFunctionReturn(PETSC_SUCCESS);
265 }
266 
267 /*@
268    PCFactorGetShiftType - Gets the type of shift, if any, done when a zero pivot is detected
269 
270    Not Collective
271 
272    Input Parameter:
273 .  pc - the preconditioner context
274 
275    Output Parameter:
276 .  type - one of `MAT_SHIFT_NONE`, `MAT_SHIFT_NONZERO`, `MAT_SHIFT_POSITIVE_DEFINITE`, or `MAT_SHIFT_INBLOCKS`
277 
278    Level: intermediate
279 
280 .seealso: `PCLU`, `PCCHOLESKY`, `PCFactorSetShiftType()`, `MatFactorShiftType`, `PCFactorSetShiftAmount()`, `PCFactorGetShiftAmount()`
281 @*/
282 PetscErrorCode PCFactorGetShiftType(PC pc, MatFactorShiftType *type)
283 {
284   PetscFunctionBegin;
285   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
286   PetscUseMethod(pc, "PCFactorGetShiftType_C", (PC, MatFactorShiftType *), (pc, type));
287   PetscFunctionReturn(PETSC_SUCCESS);
288 }
289 
290 /*@
291    PCFactorGetLevels - Gets the number of levels of fill to use.
292 
293    Logically Collective
294 
295    Input Parameter:
296 .  pc - the preconditioner context
297 
298    Output Parameter:
299 .  levels - number of levels of fill
300 
301    Level: intermediate
302 
303 .seealso: `PCILU`, `PCICC`, `PCFactorSetLevels()`
304 @*/
305 PetscErrorCode PCFactorGetLevels(PC pc, PetscInt *levels)
306 {
307   PetscFunctionBegin;
308   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
309   PetscUseMethod(pc, "PCFactorGetLevels_C", (PC, PetscInt *), (pc, levels));
310   PetscFunctionReturn(PETSC_SUCCESS);
311 }
312 
313 /*@
314    PCFactorSetLevels - Sets the number of levels of fill to use.
315 
316    Logically Collective
317 
318    Input Parameters:
319 +  pc - the preconditioner context
320 -  levels - number of levels of fill
321 
322    Options Database Key:
323 .  -pc_factor_levels <levels> - Sets fill level
324 
325    Level: intermediate
326 
327 .seealso: `PCILU`, `PCICC`, `PCFactorGetLevels()`
328 @*/
329 PetscErrorCode PCFactorSetLevels(PC pc, PetscInt levels)
330 {
331   PetscFunctionBegin;
332   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
333   PetscCheck(levels >= 0, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "negative levels");
334   PetscValidLogicalCollectiveInt(pc, levels, 2);
335   PetscTryMethod(pc, "PCFactorSetLevels_C", (PC, PetscInt), (pc, levels));
336   PetscFunctionReturn(PETSC_SUCCESS);
337 }
338 
339 /*@
340    PCFactorSetAllowDiagonalFill - Causes all diagonal matrix entries to be
341    treated as level 0 fill even if there is no non-zero location.
342 
343    Logically Collective
344 
345    Input Parameters:
346 +  pc - the preconditioner context
347 -  flg - `PETSC_TRUE` to turn on, `PETSC_FALSE` to turn off
348 
349    Options Database Key:
350 .  -pc_factor_diagonal_fill <bool> - allow the diagonal fill
351 
352    Note:
353    Does not apply with 0 fill.
354 
355    Level: intermediate
356 
357 .seealso: `PCILU`, `PCICC`, `PCFactorGetAllowDiagonalFill()`
358 @*/
359 PetscErrorCode PCFactorSetAllowDiagonalFill(PC pc, PetscBool flg)
360 {
361   PetscFunctionBegin;
362   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
363   PetscTryMethod(pc, "PCFactorSetAllowDiagonalFill_C", (PC, PetscBool), (pc, flg));
364   PetscFunctionReturn(PETSC_SUCCESS);
365 }
366 
367 /*@
368    PCFactorGetAllowDiagonalFill - Determines if all diagonal matrix entries are
369        treated as level 0 fill even if there is no non-zero location.
370 
371    Logically Collective
372 
373    Input Parameter:
374 .  pc - the preconditioner context
375 
376    Output Parameter:
377 .   flg - `PETSC_TRUE` to turn on, `PETSC_FALSE` to turn off
378 
379    Note:
380    Does not apply with 0 fill.
381 
382    Level: intermediate
383 
384 .seealso:  `PCILU`, `PCICC`, `PCFactorSetAllowDiagonalFill()`
385 @*/
386 PetscErrorCode PCFactorGetAllowDiagonalFill(PC pc, PetscBool *flg)
387 {
388   PetscFunctionBegin;
389   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
390   PetscUseMethod(pc, "PCFactorGetAllowDiagonalFill_C", (PC, PetscBool *), (pc, flg));
391   PetscFunctionReturn(PETSC_SUCCESS);
392 }
393 
394 /*@
395    PCFactorReorderForNonzeroDiagonal - reorders rows/columns of matrix to remove zeros from diagonal
396 
397    Logically Collective
398 
399    Input Parameters:
400 +  pc - the preconditioner context
401 -  tol - diagonal entries smaller than this in absolute value are considered zero
402 
403    Options Database Key:
404 .  -pc_factor_nonzeros_along_diagonal <tol> - perform the reordering with the given tolerance
405 
406    Level: intermediate
407 
408 .seealso:  `PCILU`, `PCICC`, `PCFactorSetFill()`, `PCFactorSetShiftNonzero()`, `PCFactorSetZeroPivot()`, `MatReorderForNonzeroDiagonal()`
409 @*/
410 PetscErrorCode PCFactorReorderForNonzeroDiagonal(PC pc, PetscReal rtol)
411 {
412   PetscFunctionBegin;
413   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
414   PetscValidLogicalCollectiveReal(pc, rtol, 2);
415   PetscTryMethod(pc, "PCFactorReorderForNonzeroDiagonal_C", (PC, PetscReal), (pc, rtol));
416   PetscFunctionReturn(PETSC_SUCCESS);
417 }
418 
419 /*@C
420    PCFactorSetMatSolverType - sets the solver package that is used to perform the factorization
421 
422    Logically Collective
423 
424    Input Parameters:
425 +  pc - the preconditioner context
426 -  stype - for example, `MATSOLVERSUPERLU`, `MATSOLVERSUPERLU_DIST`, `MATSOLVERMUMPS`
427 
428    Options Database Key:
429 .  -pc_factor_mat_solver_type <stype> - petsc, superlu, superlu_dist, mumps, cusparse
430 
431    Level: intermediate
432 
433    Note:
434    By default this will use the PETSc factorization if it exists
435 
436 .seealso: `PCLU`, `PCCHOLESKY`, `MatGetFactor()`, `MatSolverType`, `PCFactorGetMatSolverType()`, `MatSolverType`,
437           `MATSOLVERSUPERLU`, `MATSOLVERSUPERLU_DIST`, `MATSOLVERMUMPS`
438 @*/
439 PetscErrorCode PCFactorSetMatSolverType(PC pc, MatSolverType stype)
440 {
441   PetscFunctionBegin;
442   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
443   PetscTryMethod(pc, "PCFactorSetMatSolverType_C", (PC, MatSolverType), (pc, stype));
444   PetscFunctionReturn(PETSC_SUCCESS);
445 }
446 
447 /*@C
448    PCFactorGetMatSolverType - gets the solver package that is used to perform the factorization
449 
450    Not Collective
451 
452    Input Parameter:
453 .  pc - the preconditioner context
454 
455    Output Parameter:
456 .   stype - for example, `MATSOLVERSUPERLU`, `MATSOLVERSUPERLU_DIST`, `MATSOLVERMUMPS`
457 
458    Level: intermediate
459 
460 .seealso: `PCLU`, `PCCHOLESKY`, `MatGetFactor()`, `MatSolverType`, `PCFactorGetMatSolverType()`, `MatSolverType`,
461           `MATSOLVERSUPERLU`, `MATSOLVERSUPERLU_DIST`, `MATSOLVERMUMPS`
462 @*/
463 PetscErrorCode PCFactorGetMatSolverType(PC pc, MatSolverType *stype)
464 {
465   PetscErrorCode (*f)(PC, MatSolverType *);
466 
467   PetscFunctionBegin;
468   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
469   PetscValidPointer(stype, 2);
470   PetscCall(PetscObjectQueryFunction((PetscObject)pc, "PCFactorGetMatSolverType_C", &f));
471   if (f) PetscCall((*f)(pc, stype));
472   else *stype = NULL;
473   PetscFunctionReturn(PETSC_SUCCESS);
474 }
475 
476 /*@
477    PCFactorSetFill - Indicate the amount of fill you expect in the factored matrix,
478    fill = number nonzeros in factor/number nonzeros in original matrix.
479 
480    Not Collective, each process can expect a different amount of fill
481 
482    Input Parameters:
483 +  pc - the preconditioner context
484 -  fill - amount of expected fill
485 
486    Options Database Key:
487 .  -pc_factor_fill <fill> - Sets fill amount
488 
489    Level: intermediate
490 
491    Notes:
492    For sparse matrix factorizations it is difficult to predict how much
493    fill to expect. By running with the option -info PETSc will print the
494    actual amount of fill used; allowing you to set the value accurately for
495    future runs. Default PETSc uses a value of 5.0
496 
497    This is ignored for most solver packages
498 
499    This parameter has NOTHING to do with the levels-of-fill of ILU(). That is set with `PCFactorSetLevels()` or -pc_factor_levels.
500 
501 .seealso: `PCLU`, `PCCHOLESKY`, `PCILU`, `PCICC`, `PCFactorSetReuseFill()`
502 @*/
503 PetscErrorCode PCFactorSetFill(PC pc, PetscReal fill)
504 {
505   PetscFunctionBegin;
506   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
507   PetscCheck(fill >= 1.0, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Fill factor cannot be less then 1.0");
508   PetscTryMethod(pc, "PCFactorSetFill_C", (PC, PetscReal), (pc, fill));
509   PetscFunctionReturn(PETSC_SUCCESS);
510 }
511 
512 /*@
513    PCFactorSetUseInPlace - Tells the system to do an in-place factorization.
514    For dense matrices, this enables the solution of much larger problems.
515    For sparse matrices the factorization cannot be done truly in-place
516    so this does not save memory during the factorization, but after the matrix
517    is factored, the original unfactored matrix is freed, thus recovering that
518    space. For ICC(0) and ILU(0) with the default natural ordering the factorization is done efficiently in-place.
519 
520    Logically Collective
521 
522    Input Parameters:
523 +  pc - the preconditioner context
524 -  flg - `PETSC_TRUE` to enable, `PETSC_FALSE` to disable
525 
526    Options Database Key:
527 .  -pc_factor_in_place <true,false>- Activate/deactivate in-place factorization
528 
529    Note:
530    `PCFactorSetUseInplace()` can only be used with the `KSP` method `KSPPREONLY` or when
531    a different matrix is provided for the multiply and the preconditioner in
532    a call to `KSPSetOperators()`.
533    This is because the Krylov space methods require an application of the
534    matrix multiplication, which is not possible here because the matrix has
535    been factored in-place, replacing the original matrix.
536 
537    Level: intermediate
538 
539 .seealso: `PCLU`, `PCCHOLESKY`, `PCILU`, `PCICC`, `PCFactorGetUseInPlace()`
540 @*/
541 PetscErrorCode PCFactorSetUseInPlace(PC pc, PetscBool flg)
542 {
543   PetscFunctionBegin;
544   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
545   PetscTryMethod(pc, "PCFactorSetUseInPlace_C", (PC, PetscBool), (pc, flg));
546   PetscFunctionReturn(PETSC_SUCCESS);
547 }
548 
549 /*@
550    PCFactorGetUseInPlace - Determines if an in-place factorization is being used.
551 
552    Logically Collective
553 
554    Input Parameter:
555 .  pc - the preconditioner context
556 
557    Output Parameter:
558 .  flg - `PETSC_TRUE` to enable, `PETSC_FALSE` to disable
559 
560    Level: intermediate
561 
562 .seealso: `PCLU`, `PCCHOLESKY`, `PCILU`, `PCICC`, `PCFactorSetUseInPlace()`
563 @*/
564 PetscErrorCode PCFactorGetUseInPlace(PC pc, PetscBool *flg)
565 {
566   PetscFunctionBegin;
567   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
568   PetscUseMethod(pc, "PCFactorGetUseInPlace_C", (PC, PetscBool *), (pc, flg));
569   PetscFunctionReturn(PETSC_SUCCESS);
570 }
571 
572 /*@C
573     PCFactorSetMatOrderingType - Sets the ordering routine (to reduce fill) to
574     be used in the `PCLU`, `PCCHOLESKY`, `PCILU`,  or `PCICC` preconditioners
575 
576     Logically Collective
577 
578     Input Parameters:
579 +   pc - the preconditioner context
580 -   ordering - the matrix ordering name, for example, `MATORDERINGND` or `MATORDERINGRCM`
581 
582     Options Database Key:
583 .   -pc_factor_mat_ordering_type <nd,rcm,...,external> - Sets ordering routine
584 
585     Level: intermediate
586 
587     Notes:
588       Nested dissection is used by default for some of PETSc's sparse matrix formats
589 
590      For `PCCHOLESKY` and `PCICC` and the `MATSBAIJ` format the only reordering available is natural since only the upper half of the matrix is stored
591      and reordering this matrix is very expensive.
592 
593     You can use a `MATSEQAIJ` matrix with Cholesky and ICC and use any ordering.
594 
595     `MATORDERINGEXTERNAL` means PETSc will not compute an ordering and the package will use its own ordering, usable with `MATSOLVERCHOLMOD`, `MATSOLVERUMFPACK`, and others.
596 
597 .seealso: `PCLU`, `PCCHOLESKY`, `PCILU`, `PCICC`, `MatOrderingType`, `MATORDERINGEXTERNAL`, `MATORDERINGND`, `MATORDERINGRCM`
598 @*/
599 PetscErrorCode PCFactorSetMatOrderingType(PC pc, MatOrderingType ordering)
600 {
601   PetscFunctionBegin;
602   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
603   PetscTryMethod(pc, "PCFactorSetMatOrderingType_C", (PC, MatOrderingType), (pc, ordering));
604   PetscFunctionReturn(PETSC_SUCCESS);
605 }
606 
607 /*@
608     PCFactorSetColumnPivot - Determines when column pivoting is done during matrix factorization.
609       For PETSc dense matrices column pivoting is always done, for PETSc sparse matrices
610       it is never done. For the MATLAB and `MATSOLVERSUPERLU` factorization this is used.
611 
612     Logically Collective
613 
614     Input Parameters:
615 +   pc - the preconditioner context
616 -   dtcol - 0.0 implies no pivoting, 1.0 complete pivoting (slower, requires more memory but more stable)
617 
618     Options Database Key:
619 .   -pc_factor_pivoting <dtcol> - perform the pivoting with the given tolerance
620 
621     Level: intermediate
622 
623 .seealso: `PCLU`, `PCCHOLESKY`, `PCILU`, `PCICC`, `PCILUSetMatOrdering()`, `PCFactorSetPivotInBlocks()`
624 @*/
625 PetscErrorCode PCFactorSetColumnPivot(PC pc, PetscReal dtcol)
626 {
627   PetscFunctionBegin;
628   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
629   PetscValidLogicalCollectiveReal(pc, dtcol, 2);
630   PetscTryMethod(pc, "PCFactorSetColumnPivot_C", (PC, PetscReal), (pc, dtcol));
631   PetscFunctionReturn(PETSC_SUCCESS);
632 }
633 
634 /*@
635     PCFactorSetPivotInBlocks - Determines if pivoting is done while factoring each block
636       with `MATBAIJ` or `MATSBAIJ` matrices
637 
638     Logically Collective
639 
640     Input Parameters:
641 +   pc - the preconditioner context
642 -   pivot - `PETSC_TRUE` or `PETSC_FALSE`
643 
644     Options Database Key:
645 .   -pc_factor_pivot_in_blocks <true,false> - Pivot inside matrix dense blocks for `MATBAIJ` and `MATSBAIJ`
646 
647     Level: intermediate
648 
649 .seealso: `PCLU`, `PCCHOLESKY`, `PCILU`, `PCICC`, `PCILUSetMatOrdering()`, `PCFactorSetColumnPivot()`
650 @*/
651 PetscErrorCode PCFactorSetPivotInBlocks(PC pc, PetscBool pivot)
652 {
653   PetscFunctionBegin;
654   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
655   PetscValidLogicalCollectiveBool(pc, pivot, 2);
656   PetscTryMethod(pc, "PCFactorSetPivotInBlocks_C", (PC, PetscBool), (pc, pivot));
657   PetscFunctionReturn(PETSC_SUCCESS);
658 }
659 
660 /*@
661    PCFactorSetReuseFill - When matrices with different nonzero structure are factored,
662    this causes later ones to use the fill ratio computed in the initial factorization.
663 
664    Logically Collective
665 
666    Input Parameters:
667 +  pc - the preconditioner context
668 -  flag - `PETSC_TRUE` to reuse else `PETSC_FALSE`
669 
670    Options Database Key:
671 .  -pc_factor_reuse_fill - Activates `PCFactorSetReuseFill()`
672 
673    Level: intermediate
674 
675 .seealso: `PCLU`, `PCCHOLESKY`, `PCILU`, `PCICC`, `PCFactorSetReuseOrdering()`, `PCFactorSetFill()`
676 @*/
677 PetscErrorCode PCFactorSetReuseFill(PC pc, PetscBool flag)
678 {
679   PetscFunctionBegin;
680   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
681   PetscValidLogicalCollectiveBool(pc, flag, 2);
682   PetscTryMethod(pc, "PCFactorSetReuseFill_C", (PC, PetscBool), (pc, flag));
683   PetscFunctionReturn(PETSC_SUCCESS);
684 }
685 
686 PetscErrorCode PCFactorInitialize(PC pc, MatFactorType ftype)
687 {
688   PC_Factor *fact = (PC_Factor *)pc->data;
689 
690   PetscFunctionBegin;
691   PetscCall(MatFactorInfoInitialize(&fact->info));
692   fact->factortype           = ftype;
693   fact->info.shifttype       = (PetscReal)MAT_SHIFT_NONE;
694   fact->info.shiftamount     = 100.0 * PETSC_MACHINE_EPSILON;
695   fact->info.zeropivot       = 100.0 * PETSC_MACHINE_EPSILON;
696   fact->info.pivotinblocks   = 1.0;
697   pc->ops->getfactoredmatrix = PCFactorGetMatrix_Factor;
698 
699   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetZeroPivot_C", PCFactorSetZeroPivot_Factor));
700   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorGetZeroPivot_C", PCFactorGetZeroPivot_Factor));
701   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetShiftType_C", PCFactorSetShiftType_Factor));
702   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorGetShiftType_C", PCFactorGetShiftType_Factor));
703   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetShiftAmount_C", PCFactorSetShiftAmount_Factor));
704   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorGetShiftAmount_C", PCFactorGetShiftAmount_Factor));
705   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorGetMatSolverType_C", PCFactorGetMatSolverType_Factor));
706   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetMatSolverType_C", PCFactorSetMatSolverType_Factor));
707   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetUpMatSolverType_C", PCFactorSetUpMatSolverType_Factor));
708   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetFill_C", PCFactorSetFill_Factor));
709   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetMatOrderingType_C", PCFactorSetMatOrderingType_Factor));
710   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetLevels_C", PCFactorSetLevels_Factor));
711   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorGetLevels_C", PCFactorGetLevels_Factor));
712   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetAllowDiagonalFill_C", PCFactorSetAllowDiagonalFill_Factor));
713   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorGetAllowDiagonalFill_C", PCFactorGetAllowDiagonalFill_Factor));
714   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetPivotInBlocks_C", PCFactorSetPivotInBlocks_Factor));
715   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetUseInPlace_C", PCFactorSetUseInPlace_Factor));
716   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorGetUseInPlace_C", PCFactorGetUseInPlace_Factor));
717   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetReuseOrdering_C", PCFactorSetReuseOrdering_Factor));
718   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetReuseFill_C", PCFactorSetReuseFill_Factor));
719   PetscFunctionReturn(PETSC_SUCCESS);
720 }
721 
722 PetscErrorCode PCFactorClearComposedFunctions(PC pc)
723 {
724   PetscFunctionBegin;
725   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetZeroPivot_C", NULL));
726   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorGetZeroPivot_C", NULL));
727   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetShiftType_C", NULL));
728   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorGetShiftType_C", NULL));
729   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetShiftAmount_C", NULL));
730   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorGetShiftAmount_C", NULL));
731   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorGetMatSolverType_C", NULL));
732   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetMatSolverType_C", NULL));
733   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetUpMatSolverType_C", NULL));
734   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetFill_C", NULL));
735   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetMatOrderingType_C", NULL));
736   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetLevels_C", NULL));
737   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorGetLevels_C", NULL));
738   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetAllowDiagonalFill_C", NULL));
739   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorGetAllowDiagonalFill_C", NULL));
740   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetPivotInBlocks_C", NULL));
741   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetUseInPlace_C", NULL));
742   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorGetUseInPlace_C", NULL));
743   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetReuseOrdering_C", NULL));
744   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetReuseFill_C", NULL));
745   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorReorderForNonzeroDiagonal_C", NULL));
746   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCFactorSetDropTolerance_C", NULL));
747   PetscFunctionReturn(PETSC_SUCCESS);
748 }
749