xref: /petsc/src/ksp/pc/impls/parms/parms.c (revision 07c2e4feb6773e78bda63e3a89d5b841667f9670)
1f3161b27SJose E. Roman /*
2f3161b27SJose E. Roman    Provides an interface to pARMS.
3f3161b27SJose E. Roman    Requires pARMS 3.2 or later.
4f3161b27SJose E. Roman */
5f3161b27SJose E. Roman 
6af0996ceSBarry Smith #include <petsc/private/pcimpl.h> /*I "petscpc.h" I*/
7f3161b27SJose E. Roman 
8519f805aSKarl Rupp #if defined(PETSC_USE_COMPLEX)
9f3161b27SJose E. Roman   #define DBL_CMPLX
10f3161b27SJose E. Roman #else
11f3161b27SJose E. Roman   #define DBL
12f3161b27SJose E. Roman #endif
13f3161b27SJose E. Roman #define USE_MPI
14f3161b27SJose E. Roman #define REAL double
15f3161b27SJose E. Roman #define HAS_BLAS
16f3161b27SJose E. Roman #define FORTRAN_UNDERSCORE
17f3161b27SJose E. Roman #include "parms_sys.h"
18f3161b27SJose E. Roman #undef FLOAT
19f3161b27SJose E. Roman #define FLOAT PetscScalar
20aaa7dc30SBarry Smith #include <parms.h>
21f3161b27SJose E. Roman 
22f3161b27SJose E. Roman /*
23f3161b27SJose E. Roman    Private context (data structure) for the  preconditioner.
24f3161b27SJose E. Roman */
25f3161b27SJose E. Roman typedef struct {
26f3161b27SJose E. Roman   parms_Map         map;
27f3161b27SJose E. Roman   parms_Mat         A;
28f3161b27SJose E. Roman   parms_PC          pc;
29f3161b27SJose E. Roman   PCPARMSGlobalType global;
30f3161b27SJose E. Roman   PCPARMSLocalType  local;
31f3161b27SJose E. Roman   PetscInt          levels, blocksize, maxdim, maxits, lfil[7];
32f3161b27SJose E. Roman   PetscBool         nonsymperm, meth[8];
33f3161b27SJose E. Roman   PetscReal         solvetol, indtol, droptol[7];
34f3161b27SJose E. Roman   PetscScalar      *lvec0, *lvec1;
35f3161b27SJose E. Roman } PC_PARMS;
36f3161b27SJose E. Roman 
PCSetUp_PARMS(PC pc)37d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetUp_PARMS(PC pc)
38d71ae5a4SJacob Faibussowitsch {
39f3161b27SJose E. Roman   Mat                pmat;
40f3161b27SJose E. Roman   PC_PARMS          *parms = (PC_PARMS *)pc->data;
41f3161b27SJose E. Roman   const PetscInt    *mapptr0;
42f3161b27SJose E. Roman   PetscInt           n, lsize, low, high, i, pos, ncols, length;
43f3161b27SJose E. Roman   int               *maptmp, *mapptr, *ia, *ja, *ja1, *im;
44f3161b27SJose E. Roman   PetscScalar       *aa, *aa1;
45f3161b27SJose E. Roman   const PetscInt    *cols;
46f3161b27SJose E. Roman   PetscInt           meth[8];
47f3161b27SJose E. Roman   const PetscScalar *values;
48f3161b27SJose E. Roman   MatInfo            matinfo;
49f3161b27SJose E. Roman   PetscMPIInt        rank, npro;
50f3161b27SJose E. Roman 
51f3161b27SJose E. Roman   PetscFunctionBegin;
527addb90fSBarry Smith   /* Get matrix used to compute the preconditioner and setup pARMS structs */
539566063dSJacob Faibussowitsch   PetscCall(PCGetOperators(pc, NULL, &pmat));
54f1580f4eSBarry Smith   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pmat), &npro));
55f1580f4eSBarry Smith   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)pmat), &rank));
56f3161b27SJose E. Roman 
579566063dSJacob Faibussowitsch   PetscCall(MatGetSize(pmat, &n, NULL));
589566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(npro + 1, &mapptr));
599566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n, &maptmp));
609566063dSJacob Faibussowitsch   PetscCall(MatGetOwnershipRanges(pmat, &mapptr0));
61f3161b27SJose E. Roman   low   = mapptr0[rank];
62f3161b27SJose E. Roman   high  = mapptr0[rank + 1];
63f3161b27SJose E. Roman   lsize = high - low;
64f3161b27SJose E. Roman 
652fa5cd67SKarl Rupp   for (i = 0; i < npro + 1; i++) mapptr[i] = mapptr0[i] + 1;
662fa5cd67SKarl Rupp   for (i = 0; i < n; i++) maptmp[i] = i + 1;
67f3161b27SJose E. Roman 
68f3161b27SJose E. Roman   /* if created, destroy the previous map */
69f3161b27SJose E. Roman   if (parms->map) {
70f3161b27SJose E. Roman     parms_MapFree(&parms->map);
710298fd71SBarry Smith     parms->map = NULL;
72f3161b27SJose E. Roman   }
73f3161b27SJose E. Roman 
74f3161b27SJose E. Roman   /* create pARMS map object */
75ce94432eSBarry Smith   parms_MapCreateFromPtr(&parms->map, (int)n, maptmp, mapptr, PetscObjectComm((PetscObject)pmat), 1, NONINTERLACED);
76f3161b27SJose E. Roman 
77f3161b27SJose E. Roman   /* if created, destroy the previous pARMS matrix */
78f3161b27SJose E. Roman   if (parms->A) {
79f3161b27SJose E. Roman     parms_MatFree(&parms->A);
800298fd71SBarry Smith     parms->A = NULL;
81f3161b27SJose E. Roman   }
82f3161b27SJose E. Roman 
83f3161b27SJose E. Roman   /* create pARMS mat object */
84f3161b27SJose E. Roman   parms_MatCreate(&parms->A, parms->map);
85f3161b27SJose E. Roman 
86f3161b27SJose E. Roman   /* setup and copy csr data structure for pARMS */
879566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(lsize + 1, &ia));
88f3161b27SJose E. Roman   ia[0] = 1;
899566063dSJacob Faibussowitsch   PetscCall(MatGetInfo(pmat, MAT_LOCAL, &matinfo));
90f3161b27SJose E. Roman   length = matinfo.nz_used;
919566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(length, &ja));
929566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(length, &aa));
93f3161b27SJose E. Roman 
94f3161b27SJose E. Roman   for (i = low; i < high; i++) {
95f3161b27SJose E. Roman     pos = ia[i - low] - 1;
969566063dSJacob Faibussowitsch     PetscCall(MatGetRow(pmat, i, &ncols, &cols, &values));
97f3161b27SJose E. Roman     ia[i - low + 1] = ia[i - low] + ncols;
98f3161b27SJose E. Roman 
99f3161b27SJose E. Roman     if (ia[i - low + 1] >= length) {
100f3161b27SJose E. Roman       length += ncols;
1019566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(length, &ja1));
1029566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(ja1, ja, ia[i - low] - 1));
1039566063dSJacob Faibussowitsch       PetscCall(PetscFree(ja));
104f3161b27SJose E. Roman       ja = ja1;
1059566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(length, &aa1));
1069566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(aa1, aa, ia[i - low] - 1));
1079566063dSJacob Faibussowitsch       PetscCall(PetscFree(aa));
108f3161b27SJose E. Roman       aa = aa1;
109f3161b27SJose E. Roman     }
1109566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(&ja[pos], cols, ncols));
1119566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(&aa[pos], values, ncols));
1129566063dSJacob Faibussowitsch     PetscCall(MatRestoreRow(pmat, i, &ncols, &cols, &values));
113f3161b27SJose E. Roman   }
114f3161b27SJose E. Roman 
115f3161b27SJose E. Roman   /* csr info is for local matrix so initialize im[] locally */
1169566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(lsize, &im));
1179566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(im, &maptmp[mapptr[rank] - 1], lsize));
118f3161b27SJose E. Roman 
119f3161b27SJose E. Roman   /* 1-based indexing */
1202fa5cd67SKarl Rupp   for (i = 0; i < ia[lsize] - 1; i++) ja[i] = ja[i] + 1;
121f3161b27SJose E. Roman 
122f3161b27SJose E. Roman   /* Now copy csr matrix to parms_mat object */
123f3161b27SJose E. Roman   parms_MatSetValues(parms->A, (int)lsize, im, ia, ja, aa, INSERT);
124f3161b27SJose E. Roman 
125f3161b27SJose E. Roman   /* free memory */
1269566063dSJacob Faibussowitsch   PetscCall(PetscFree(maptmp));
1279566063dSJacob Faibussowitsch   PetscCall(PetscFree(mapptr));
1289566063dSJacob Faibussowitsch   PetscCall(PetscFree(aa));
1299566063dSJacob Faibussowitsch   PetscCall(PetscFree(ja));
1309566063dSJacob Faibussowitsch   PetscCall(PetscFree(ia));
1319566063dSJacob Faibussowitsch   PetscCall(PetscFree(im));
132f3161b27SJose E. Roman 
133f3161b27SJose E. Roman   /* setup parms matrix */
134f3161b27SJose E. Roman   parms_MatSetup(parms->A);
135f3161b27SJose E. Roman 
136f3161b27SJose E. Roman   /* if created, destroy the previous pARMS pc */
137f3161b27SJose E. Roman   if (parms->pc) {
138f3161b27SJose E. Roman     parms_PCFree(&parms->pc);
1390298fd71SBarry Smith     parms->pc = NULL;
140f3161b27SJose E. Roman   }
141f3161b27SJose E. Roman 
142f3161b27SJose E. Roman   /* Now create pARMS preconditioner object based on A */
143f3161b27SJose E. Roman   parms_PCCreate(&parms->pc, parms->A);
144f3161b27SJose E. Roman 
145f3161b27SJose E. Roman   /* Transfer options from PC to pARMS */
146f3161b27SJose E. Roman   switch (parms->global) {
147d71ae5a4SJacob Faibussowitsch   case 0:
148d71ae5a4SJacob Faibussowitsch     parms_PCSetType(parms->pc, PCRAS);
149d71ae5a4SJacob Faibussowitsch     break;
150d71ae5a4SJacob Faibussowitsch   case 1:
151d71ae5a4SJacob Faibussowitsch     parms_PCSetType(parms->pc, PCSCHUR);
152d71ae5a4SJacob Faibussowitsch     break;
153d71ae5a4SJacob Faibussowitsch   case 2:
154d71ae5a4SJacob Faibussowitsch     parms_PCSetType(parms->pc, PCBJ);
155d71ae5a4SJacob Faibussowitsch     break;
156f3161b27SJose E. Roman   }
157f3161b27SJose E. Roman   switch (parms->local) {
158d71ae5a4SJacob Faibussowitsch   case 0:
159d71ae5a4SJacob Faibussowitsch     parms_PCSetILUType(parms->pc, PCILU0);
160d71ae5a4SJacob Faibussowitsch     break;
161d71ae5a4SJacob Faibussowitsch   case 1:
162d71ae5a4SJacob Faibussowitsch     parms_PCSetILUType(parms->pc, PCILUK);
163d71ae5a4SJacob Faibussowitsch     break;
164d71ae5a4SJacob Faibussowitsch   case 2:
165d71ae5a4SJacob Faibussowitsch     parms_PCSetILUType(parms->pc, PCILUT);
166d71ae5a4SJacob Faibussowitsch     break;
167d71ae5a4SJacob Faibussowitsch   case 3:
168d71ae5a4SJacob Faibussowitsch     parms_PCSetILUType(parms->pc, PCARMS);
169d71ae5a4SJacob Faibussowitsch     break;
170f3161b27SJose E. Roman   }
171f3161b27SJose E. Roman   parms_PCSetInnerEps(parms->pc, parms->solvetol);
172f3161b27SJose E. Roman   parms_PCSetNlevels(parms->pc, parms->levels);
173f3161b27SJose E. Roman   parms_PCSetPermType(parms->pc, parms->nonsymperm ? 1 : 0);
174f3161b27SJose E. Roman   parms_PCSetBsize(parms->pc, parms->blocksize);
175f3161b27SJose E. Roman   parms_PCSetTolInd(parms->pc, parms->indtol);
176f3161b27SJose E. Roman   parms_PCSetInnerKSize(parms->pc, parms->maxdim);
177f3161b27SJose E. Roman   parms_PCSetInnerMaxits(parms->pc, parms->maxits);
178f3161b27SJose E. Roman   for (i = 0; i < 8; i++) meth[i] = parms->meth[i] ? 1 : 0;
179f3161b27SJose E. Roman   parms_PCSetPermScalOptions(parms->pc, &meth[0], 1);
180f3161b27SJose E. Roman   parms_PCSetPermScalOptions(parms->pc, &meth[4], 0);
181f3161b27SJose E. Roman   parms_PCSetFill(parms->pc, parms->lfil);
182f3161b27SJose E. Roman   parms_PCSetTol(parms->pc, parms->droptol);
183f3161b27SJose E. Roman 
184f3161b27SJose E. Roman   parms_PCSetup(parms->pc);
185f3161b27SJose E. Roman 
186f3161b27SJose E. Roman   /* Allocate two auxiliary vector of length lsize */
1879566063dSJacob Faibussowitsch   if (parms->lvec0) PetscCall(PetscFree(parms->lvec0));
1889566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(lsize, &parms->lvec0));
1899566063dSJacob Faibussowitsch   if (parms->lvec1) PetscCall(PetscFree(parms->lvec1));
1909566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(lsize, &parms->lvec1));
1913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
192f3161b27SJose E. Roman }
193f3161b27SJose E. Roman 
PCView_PARMS(PC pc,PetscViewer viewer)194d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_PARMS(PC pc, PetscViewer viewer)
195d71ae5a4SJacob Faibussowitsch {
196*9f196a02SMartin Diehl   PetscBool isascii;
197f3161b27SJose E. Roman   PC_PARMS *parms = (PC_PARMS *)pc->data;
198f3161b27SJose E. Roman   char     *str;
199f3161b27SJose E. Roman   double    fill_fact;
200f3161b27SJose E. Roman 
201f3161b27SJose E. Roman   PetscFunctionBegin;
202*9f196a02SMartin Diehl   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
203*9f196a02SMartin Diehl   if (isascii) {
204f3161b27SJose E. Roman     parms_PCGetName(parms->pc, &str);
2059566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  global preconditioner: %s\n", str));
206f3161b27SJose E. Roman     parms_PCILUGetName(parms->pc, &str);
2079566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  local preconditioner: %s\n", str));
208f3161b27SJose E. Roman     parms_PCGetRatio(parms->pc, &fill_fact);
2099566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  non-zero elements/original non-zero entries: %-4.2f\n", fill_fact));
2109566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Tolerance for local solve: %g\n", parms->solvetol));
2119566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Number of levels: %d\n", parms->levels));
21248a46eb9SPierre Jolivet     if (parms->nonsymperm) PetscCall(PetscViewerASCIIPrintf(viewer, "  Using nonsymmetric permutation\n"));
2139566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Block size: %d\n", parms->blocksize));
2149566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Tolerance for independent sets: %g\n", parms->indtol));
2159566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Inner Krylov dimension: %d\n", parms->maxdim));
2169566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Maximum number of inner iterations: %d\n", parms->maxits));
21748a46eb9SPierre Jolivet     if (parms->meth[0]) PetscCall(PetscViewerASCIIPrintf(viewer, "  Using nonsymmetric permutation for interlevel blocks\n"));
21848a46eb9SPierre Jolivet     if (parms->meth[1]) PetscCall(PetscViewerASCIIPrintf(viewer, "  Using column permutation for interlevel blocks\n"));
21948a46eb9SPierre Jolivet     if (parms->meth[2]) PetscCall(PetscViewerASCIIPrintf(viewer, "  Using row scaling for interlevel blocks\n"));
22048a46eb9SPierre Jolivet     if (parms->meth[3]) PetscCall(PetscViewerASCIIPrintf(viewer, "  Using column scaling for interlevel blocks\n"));
22148a46eb9SPierre Jolivet     if (parms->meth[4]) PetscCall(PetscViewerASCIIPrintf(viewer, "  Using nonsymmetric permutation for last level blocks\n"));
22248a46eb9SPierre Jolivet     if (parms->meth[5]) PetscCall(PetscViewerASCIIPrintf(viewer, "  Using column permutation for last level blocks\n"));
22348a46eb9SPierre Jolivet     if (parms->meth[6]) PetscCall(PetscViewerASCIIPrintf(viewer, "  Using row scaling for last level blocks\n"));
22448a46eb9SPierre Jolivet     if (parms->meth[7]) PetscCall(PetscViewerASCIIPrintf(viewer, "  Using column scaling for last level blocks\n"));
2259566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  amount of fill-in for ilut, iluk and arms: %d\n", parms->lfil[0]));
2269566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  amount of fill-in for schur: %d\n", parms->lfil[4]));
2279566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  amount of fill-in for ILUT L and U: %d\n", parms->lfil[5]));
2289566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  drop tolerance for L, U, L^{-1}F and EU^{-1}: %g\n", parms->droptol[0]));
2299566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  drop tolerance for schur complement at each level: %g\n", parms->droptol[4]));
2309566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  drop tolerance for ILUT in last level schur complement: %g\n", parms->droptol[5]));
231f3161b27SJose E. Roman   }
2323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
233f3161b27SJose E. Roman }
234f3161b27SJose E. Roman 
PCDestroy_PARMS(PC pc)235d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCDestroy_PARMS(PC pc)
236d71ae5a4SJacob Faibussowitsch {
237f3161b27SJose E. Roman   PC_PARMS *parms = (PC_PARMS *)pc->data;
238f3161b27SJose E. Roman 
239f3161b27SJose E. Roman   PetscFunctionBegin;
2402fa5cd67SKarl Rupp   if (parms->map) parms_MapFree(&parms->map);
2412fa5cd67SKarl Rupp   if (parms->A) parms_MatFree(&parms->A);
2422fa5cd67SKarl Rupp   if (parms->pc) parms_PCFree(&parms->pc);
2431baa6e33SBarry Smith   if (parms->lvec0) PetscCall(PetscFree(parms->lvec0));
2441baa6e33SBarry Smith   if (parms->lvec1) PetscCall(PetscFree(parms->lvec1));
2459566063dSJacob Faibussowitsch   PetscCall(PetscFree(pc->data));
246f3161b27SJose E. Roman 
2479566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)pc, 0));
2489566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetGlobal_C", NULL));
2499566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetLocal_C", NULL));
2509566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetSolveTolerances_C", NULL));
2519566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetSolveRestart_C", NULL));
2529566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetNonsymPerm_C", NULL));
2539566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetFill_C", NULL));
2543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
255f3161b27SJose E. Roman }
256f3161b27SJose E. Roman 
PCSetFromOptions_PARMS(PC pc,PetscOptionItems PetscOptionsObject)257ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_PARMS(PC pc, PetscOptionItems PetscOptionsObject)
258d71ae5a4SJacob Faibussowitsch {
259f3161b27SJose E. Roman   PC_PARMS         *parms = (PC_PARMS *)pc->data;
260f3161b27SJose E. Roman   PetscBool         flag;
261f3161b27SJose E. Roman   PCPARMSGlobalType global;
262f3161b27SJose E. Roman   PCPARMSLocalType  local;
263f3161b27SJose E. Roman 
264f3161b27SJose E. Roman   PetscFunctionBegin;
265d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "PARMS Options");
2669566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEnum("-pc_parms_global", "Global preconditioner", "PCPARMSSetGlobal", PCPARMSGlobalTypes, (PetscEnum)parms->global, (PetscEnum *)&global, &flag));
2679566063dSJacob Faibussowitsch   if (flag) PetscCall(PCPARMSSetGlobal(pc, global));
2689566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEnum("-pc_parms_local", "Local preconditioner", "PCPARMSSetLocal", PCPARMSLocalTypes, (PetscEnum)parms->local, (PetscEnum *)&local, &flag));
2699566063dSJacob Faibussowitsch   if (flag) PetscCall(PCPARMSSetLocal(pc, local));
2709566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_parms_solve_tol", "Tolerance for local solve", "PCPARMSSetSolveTolerances", parms->solvetol, &parms->solvetol, NULL));
2719566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_parms_levels", "Number of levels", "None", parms->levels, &parms->levels, NULL));
2729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_parms_nonsymmetric_perm", "Use nonsymmetric permutation", "PCPARMSSetNonsymPerm", parms->nonsymperm, &parms->nonsymperm, NULL));
2739566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_parms_blocksize", "Block size", "None", parms->blocksize, &parms->blocksize, NULL));
2749566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_parms_ind_tol", "Tolerance for independent sets", "None", parms->indtol, &parms->indtol, NULL));
2759566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_parms_max_dim", "Inner Krylov dimension", "PCPARMSSetSolveRestart", parms->maxdim, &parms->maxdim, NULL));
2769566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_parms_max_it", "Maximum number of inner iterations", "PCPARMSSetSolveTolerances", parms->maxits, &parms->maxits, NULL));
2779566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_parms_inter_nonsymmetric_perm", "nonsymmetric permutation for interlevel blocks", "None", parms->meth[0], &parms->meth[0], NULL));
2789566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_parms_inter_column_perm", "column permutation for interlevel blocks", "None", parms->meth[1], &parms->meth[1], NULL));
2799566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_parms_inter_row_scaling", "row scaling for interlevel blocks", "None", parms->meth[2], &parms->meth[2], NULL));
2809566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_parms_inter_column_scaling", "column scaling for interlevel blocks", "None", parms->meth[3], &parms->meth[3], NULL));
2819566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_parms_last_nonsymmetric_perm", "nonsymmetric permutation for last level blocks", "None", parms->meth[4], &parms->meth[4], NULL));
2829566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_parms_last_column_perm", "column permutation for last level blocks", "None", parms->meth[5], &parms->meth[5], NULL));
2839566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_parms_last_row_scaling", "row scaling for last level blocks", "None", parms->meth[6], &parms->meth[6], NULL));
2849566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_parms_last_column_scaling", "column scaling for last level blocks", "None", parms->meth[7], &parms->meth[7], NULL));
2859566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_parms_lfil_ilu_arms", "amount of fill-in for ilut, iluk and arms", "PCPARMSSetFill", parms->lfil[0], &parms->lfil[0], &flag));
286f3161b27SJose E. Roman   if (flag) parms->lfil[1] = parms->lfil[2] = parms->lfil[3] = parms->lfil[0];
2879566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_parms_lfil_schur", "amount of fill-in for schur", "PCPARMSSetFill", parms->lfil[4], &parms->lfil[4], NULL));
2889566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_parms_lfil_ilut_L_U", "amount of fill-in for ILUT L and U", "PCPARMSSetFill", parms->lfil[5], &parms->lfil[5], &flag));
289f3161b27SJose E. Roman   if (flag) parms->lfil[6] = parms->lfil[5];
2909566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_parms_droptol_factors", "drop tolerance for L, U, L^{-1}F and EU^{-1}", "None", parms->droptol[0], &parms->droptol[0], NULL));
2919566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_parms_droptol_schur_compl", "drop tolerance for schur complement at each level", "None", parms->droptol[4], &parms->droptol[4], &flag));
292f3161b27SJose E. Roman   if (flag) parms->droptol[1] = parms->droptol[2] = parms->droptol[3] = parms->droptol[0];
2939566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_parms_droptol_last_schur", "drop tolerance for ILUT in last level schur complement", "None", parms->droptol[5], &parms->droptol[5], &flag));
294f3161b27SJose E. Roman   if (flag) parms->droptol[6] = parms->droptol[5];
295d0609cedSBarry Smith   PetscOptionsHeadEnd();
2963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
297f3161b27SJose E. Roman }
298f3161b27SJose E. Roman 
PCApply_PARMS(PC pc,Vec b,Vec x)299d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApply_PARMS(PC pc, Vec b, Vec x)
300d71ae5a4SJacob Faibussowitsch {
301f3161b27SJose E. Roman   PC_PARMS          *parms = (PC_PARMS *)pc->data;
302f3161b27SJose E. Roman   const PetscScalar *b1;
303f3161b27SJose E. Roman   PetscScalar       *x1;
304f3161b27SJose E. Roman 
305f3161b27SJose E. Roman   PetscFunctionBegin;
3069566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(b, &b1));
3079566063dSJacob Faibussowitsch   PetscCall(VecGetArray(x, &x1));
308f3161b27SJose E. Roman   parms_VecPermAux((PetscScalar *)b1, parms->lvec0, parms->map);
309f3161b27SJose E. Roman   parms_PCApply(parms->pc, parms->lvec0, parms->lvec1);
310f3161b27SJose E. Roman   parms_VecInvPermAux(parms->lvec1, x1, parms->map);
3119566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(b, &b1));
3129566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(x, &x1));
3133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
314f3161b27SJose E. Roman }
315f3161b27SJose E. Roman 
PCPARMSSetGlobal_PARMS(PC pc,PCPARMSGlobalType type)316d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCPARMSSetGlobal_PARMS(PC pc, PCPARMSGlobalType type)
317d71ae5a4SJacob Faibussowitsch {
318f3161b27SJose E. Roman   PC_PARMS *parms = (PC_PARMS *)pc->data;
319f3161b27SJose E. Roman 
320f3161b27SJose E. Roman   PetscFunctionBegin;
321f3161b27SJose E. Roman   if (type != parms->global) {
322f3161b27SJose E. Roman     parms->global   = type;
323371d2eb7SMartin Diehl     pc->setupcalled = PETSC_FALSE;
324f3161b27SJose E. Roman   }
3253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
326f3161b27SJose E. Roman }
327f3161b27SJose E. Roman 
3285de0dacdSJose E. Roman /*@
329f1580f4eSBarry Smith   PCPARMSSetGlobal - Sets the global preconditioner to be used in `PCPARMS`.
330f3161b27SJose E. Roman 
331c3339decSBarry Smith   Collective
332f3161b27SJose E. Roman 
333f3161b27SJose E. Roman   Input Parameters:
334f3161b27SJose E. Roman + pc   - the preconditioner context
335f3161b27SJose E. Roman - type - the global preconditioner type, one of
336f3161b27SJose E. Roman .vb
337f3161b27SJose E. Roman      PC_PARMS_GLOBAL_RAS   - Restricted additive Schwarz
338f3161b27SJose E. Roman      PC_PARMS_GLOBAL_SCHUR - Schur complement
339f3161b27SJose E. Roman      PC_PARMS_GLOBAL_BJ    - Block Jacobi
340f3161b27SJose E. Roman .ve
341f3161b27SJose E. Roman 
342f1580f4eSBarry Smith   Options Database Key:
343f1580f4eSBarry Smith . -pc_parms_global [ras,schur,bj] - Sets global preconditioner
344f3161b27SJose E. Roman 
345f3161b27SJose E. Roman   Level: intermediate
346f3161b27SJose E. Roman 
347f1580f4eSBarry Smith   Note:
348f1580f4eSBarry Smith   See the pARMS function `parms_PCSetType()` for more information.
349f3161b27SJose E. Roman 
350562efe2eSBarry Smith .seealso: [](ch_ksp), `PCPARMS`, `PCPARMSSetLocal()`
351f3161b27SJose E. Roman @*/
PCPARMSSetGlobal(PC pc,PCPARMSGlobalType type)352d71ae5a4SJacob Faibussowitsch PetscErrorCode PCPARMSSetGlobal(PC pc, PCPARMSGlobalType type)
353d71ae5a4SJacob Faibussowitsch {
354f3161b27SJose E. Roman   PetscFunctionBegin;
355f3161b27SJose E. Roman   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
356f3161b27SJose E. Roman   PetscValidLogicalCollectiveEnum(pc, type, 2);
357cac4c232SBarry Smith   PetscTryMethod(pc, "PCPARMSSetGlobal_C", (PC, PCPARMSGlobalType), (pc, type));
3583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
359f3161b27SJose E. Roman }
360f3161b27SJose E. Roman 
PCPARMSSetLocal_PARMS(PC pc,PCPARMSLocalType type)361d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCPARMSSetLocal_PARMS(PC pc, PCPARMSLocalType type)
362d71ae5a4SJacob Faibussowitsch {
363f3161b27SJose E. Roman   PC_PARMS *parms = (PC_PARMS *)pc->data;
364f3161b27SJose E. Roman 
365f3161b27SJose E. Roman   PetscFunctionBegin;
366f3161b27SJose E. Roman   if (type != parms->local) {
367f3161b27SJose E. Roman     parms->local    = type;
368371d2eb7SMartin Diehl     pc->setupcalled = PETSC_FALSE;
369f3161b27SJose E. Roman   }
3703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
371f3161b27SJose E. Roman }
372f3161b27SJose E. Roman 
3735de0dacdSJose E. Roman /*@
374f1580f4eSBarry Smith   PCPARMSSetLocal - Sets the local preconditioner to be used in `PCPARMS`.
375f3161b27SJose E. Roman 
376c3339decSBarry Smith   Collective
377f3161b27SJose E. Roman 
378f3161b27SJose E. Roman   Input Parameters:
379f3161b27SJose E. Roman + pc   - the preconditioner context
380f3161b27SJose E. Roman - type - the local preconditioner type, one of
381f3161b27SJose E. Roman .vb
382f3161b27SJose E. Roman      PC_PARMS_LOCAL_ILU0   - ILU0 preconditioner
383f3161b27SJose E. Roman      PC_PARMS_LOCAL_ILUK   - ILU(k) preconditioner
384f3161b27SJose E. Roman      PC_PARMS_LOCAL_ILUT   - ILUT preconditioner
385f3161b27SJose E. Roman      PC_PARMS_LOCAL_ARMS   - ARMS preconditioner
386f3161b27SJose E. Roman .ve
387f3161b27SJose E. Roman 
388f3161b27SJose E. Roman   Options Database Keys:
389feefa0e1SJacob Faibussowitsch . pc_parms_local [ilu0,iluk,ilut,arms] - Sets local preconditioner
390f3161b27SJose E. Roman 
391f3161b27SJose E. Roman   Level: intermediate
392f3161b27SJose E. Roman 
393f3161b27SJose E. Roman   Notes:
394f3161b27SJose E. Roman   For the ARMS preconditioner, one can use either the symmetric ARMS or the non-symmetric
395f3161b27SJose E. Roman   variant (ARMS-ddPQ) by setting the permutation type with PCPARMSSetNonsymPerm().
396f3161b27SJose E. Roman 
397f1580f4eSBarry Smith   See the pARMS function `parms_PCILUSetType()` for more information.
398f3161b27SJose E. Roman 
399562efe2eSBarry Smith .seealso: [](ch_ksp), `PCPARMS`, `PCPARMSSetGlobal()`, `PCPARMSSetNonsymPerm()`
400f3161b27SJose E. Roman 
401f3161b27SJose E. Roman @*/
PCPARMSSetLocal(PC pc,PCPARMSLocalType type)402d71ae5a4SJacob Faibussowitsch PetscErrorCode PCPARMSSetLocal(PC pc, PCPARMSLocalType type)
403d71ae5a4SJacob Faibussowitsch {
404f3161b27SJose E. Roman   PetscFunctionBegin;
405f3161b27SJose E. Roman   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
406f3161b27SJose E. Roman   PetscValidLogicalCollectiveEnum(pc, type, 2);
407cac4c232SBarry Smith   PetscTryMethod(pc, "PCPARMSSetLocal_C", (PC, PCPARMSLocalType), (pc, type));
4083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
409f3161b27SJose E. Roman }
410f3161b27SJose E. Roman 
PCPARMSSetSolveTolerances_PARMS(PC pc,PetscReal tol,PetscInt maxits)411d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCPARMSSetSolveTolerances_PARMS(PC pc, PetscReal tol, PetscInt maxits)
412d71ae5a4SJacob Faibussowitsch {
413f3161b27SJose E. Roman   PC_PARMS *parms = (PC_PARMS *)pc->data;
414f3161b27SJose E. Roman 
415f3161b27SJose E. Roman   PetscFunctionBegin;
416f3161b27SJose E. Roman   if (tol != parms->solvetol) {
417f3161b27SJose E. Roman     parms->solvetol = tol;
418371d2eb7SMartin Diehl     pc->setupcalled = PETSC_FALSE;
419f3161b27SJose E. Roman   }
420f3161b27SJose E. Roman   if (maxits != parms->maxits) {
421f3161b27SJose E. Roman     parms->maxits   = maxits;
422371d2eb7SMartin Diehl     pc->setupcalled = PETSC_FALSE;
423f3161b27SJose E. Roman   }
4243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
425f3161b27SJose E. Roman }
426f3161b27SJose E. Roman 
4275de0dacdSJose E. Roman /*@
428f3161b27SJose E. Roman   PCPARMSSetSolveTolerances - Sets the convergence tolerance and the maximum iterations for the
429f3161b27SJose E. Roman   inner GMRES solver, when the Schur global preconditioner is used.
430f3161b27SJose E. Roman 
431c3339decSBarry Smith   Collective
432f3161b27SJose E. Roman 
433f3161b27SJose E. Roman   Input Parameters:
434f3161b27SJose E. Roman + pc     - the preconditioner context
435f3161b27SJose E. Roman . tol    - the convergence tolerance
436f3161b27SJose E. Roman - maxits - the maximum number of iterations to use
437f3161b27SJose E. Roman 
438f3161b27SJose E. Roman   Options Database Keys:
439f3161b27SJose E. Roman + -pc_parms_solve_tol - set the tolerance for local solve
440f3161b27SJose E. Roman - -pc_parms_max_it    - set the maximum number of inner iterations
441f3161b27SJose E. Roman 
442f3161b27SJose E. Roman   Level: intermediate
443f3161b27SJose E. Roman 
444f1580f4eSBarry Smith   Note:
445f1580f4eSBarry Smith   See the pARMS functions `parms_PCSetInnerEps()` and `parms_PCSetInnerMaxits()` for more information.
446f3161b27SJose E. Roman 
447562efe2eSBarry Smith .seealso: [](ch_ksp), `PCPARMS`, `PCPARMSSetSolveRestart()`
448f3161b27SJose E. Roman @*/
PCPARMSSetSolveTolerances(PC pc,PetscReal tol,PetscInt maxits)449d71ae5a4SJacob Faibussowitsch PetscErrorCode PCPARMSSetSolveTolerances(PC pc, PetscReal tol, PetscInt maxits)
450d71ae5a4SJacob Faibussowitsch {
451f3161b27SJose E. Roman   PetscFunctionBegin;
452f3161b27SJose E. Roman   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
453cac4c232SBarry Smith   PetscTryMethod(pc, "PCPARMSSetSolveTolerances_C", (PC, PetscReal, PetscInt), (pc, tol, maxits));
4543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
455f3161b27SJose E. Roman }
456f3161b27SJose E. Roman 
PCPARMSSetSolveRestart_PARMS(PC pc,PetscInt restart)457d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCPARMSSetSolveRestart_PARMS(PC pc, PetscInt restart)
458d71ae5a4SJacob Faibussowitsch {
459f3161b27SJose E. Roman   PC_PARMS *parms = (PC_PARMS *)pc->data;
460f3161b27SJose E. Roman 
461f3161b27SJose E. Roman   PetscFunctionBegin;
462f3161b27SJose E. Roman   if (restart != parms->maxdim) {
463f3161b27SJose E. Roman     parms->maxdim   = restart;
464371d2eb7SMartin Diehl     pc->setupcalled = PETSC_FALSE;
465f3161b27SJose E. Roman   }
4663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
467f3161b27SJose E. Roman }
468f3161b27SJose E. Roman 
4695de0dacdSJose E. Roman /*@
470f3161b27SJose E. Roman   PCPARMSSetSolveRestart - Sets the number of iterations at which the
471f3161b27SJose E. Roman   inner GMRES solver restarts.
472f3161b27SJose E. Roman 
473c3339decSBarry Smith   Collective
474f3161b27SJose E. Roman 
475f3161b27SJose E. Roman   Input Parameters:
476f3161b27SJose E. Roman + pc      - the preconditioner context
477f3161b27SJose E. Roman - restart - maximum dimension of the Krylov subspace
478f3161b27SJose E. Roman 
479f1580f4eSBarry Smith   Options Database Key:
480f3161b27SJose E. Roman . -pc_parms_max_dim - sets the inner Krylov dimension
481f3161b27SJose E. Roman 
482f3161b27SJose E. Roman   Level: intermediate
483f3161b27SJose E. Roman 
484f1580f4eSBarry Smith   Note:
485f3161b27SJose E. Roman   See the pARMS function parms_PCSetInnerKSize for more information.
486f3161b27SJose E. Roman 
487562efe2eSBarry Smith .seealso: [](ch_ksp), `PCPARMS`, `PCPARMSSetSolveTolerances()`
488f3161b27SJose E. Roman @*/
PCPARMSSetSolveRestart(PC pc,PetscInt restart)489d71ae5a4SJacob Faibussowitsch PetscErrorCode PCPARMSSetSolveRestart(PC pc, PetscInt restart)
490d71ae5a4SJacob Faibussowitsch {
491f3161b27SJose E. Roman   PetscFunctionBegin;
492f3161b27SJose E. Roman   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
493cac4c232SBarry Smith   PetscTryMethod(pc, "PCPARMSSetSolveRestart_C", (PC, PetscInt), (pc, restart));
4943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
495f3161b27SJose E. Roman }
496f3161b27SJose E. Roman 
PCPARMSSetNonsymPerm_PARMS(PC pc,PetscBool nonsym)497d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCPARMSSetNonsymPerm_PARMS(PC pc, PetscBool nonsym)
498d71ae5a4SJacob Faibussowitsch {
499f3161b27SJose E. Roman   PC_PARMS *parms = (PC_PARMS *)pc->data;
500f3161b27SJose E. Roman 
501f3161b27SJose E. Roman   PetscFunctionBegin;
5025de0dacdSJose E. Roman   if ((nonsym && !parms->nonsymperm) || (!nonsym && parms->nonsymperm)) {
503f3161b27SJose E. Roman     parms->nonsymperm = nonsym;
504371d2eb7SMartin Diehl     pc->setupcalled   = PETSC_FALSE;
505f3161b27SJose E. Roman   }
5063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
507f3161b27SJose E. Roman }
508f3161b27SJose E. Roman 
5095de0dacdSJose E. Roman /*@
510f3161b27SJose E. Roman   PCPARMSSetNonsymPerm - Sets the type of permutation for the ARMS preconditioner: the standard
511f3161b27SJose E. Roman   symmetric ARMS or the non-symmetric ARMS (ARMS-ddPQ).
512f3161b27SJose E. Roman 
513c3339decSBarry Smith   Collective
514f3161b27SJose E. Roman 
515f3161b27SJose E. Roman   Input Parameters:
516f3161b27SJose E. Roman + pc     - the preconditioner context
517f1580f4eSBarry Smith - nonsym - `PETSC_TRUE` indicates the non-symmetric ARMS is used;
518f1580f4eSBarry Smith             `PETSC_FALSE` indicates the symmetric ARMS is used
519f3161b27SJose E. Roman 
520f1580f4eSBarry Smith   Options Database Key:
521f3161b27SJose E. Roman . -pc_parms_nonsymmetric_perm - sets the use of nonsymmetric permutation
522f3161b27SJose E. Roman 
523f3161b27SJose E. Roman   Level: intermediate
524f3161b27SJose E. Roman 
525f1580f4eSBarry Smith   Note:
526f1580f4eSBarry Smith   See the pARMS function `parms_PCSetPermType()` for more information.
527f3161b27SJose E. Roman 
528562efe2eSBarry Smith .seealso: [](ch_ksp), `PCPARMS`
529f3161b27SJose E. Roman @*/
PCPARMSSetNonsymPerm(PC pc,PetscBool nonsym)530d71ae5a4SJacob Faibussowitsch PetscErrorCode PCPARMSSetNonsymPerm(PC pc, PetscBool nonsym)
531d71ae5a4SJacob Faibussowitsch {
532f3161b27SJose E. Roman   PetscFunctionBegin;
533f3161b27SJose E. Roman   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
534cac4c232SBarry Smith   PetscTryMethod(pc, "PCPARMSSetNonsymPerm_C", (PC, PetscBool), (pc, nonsym));
5353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
536f3161b27SJose E. Roman }
537f3161b27SJose E. Roman 
PCPARMSSetFill_PARMS(PC pc,PetscInt lfil0,PetscInt lfil1,PetscInt lfil2)538d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCPARMSSetFill_PARMS(PC pc, PetscInt lfil0, PetscInt lfil1, PetscInt lfil2)
539d71ae5a4SJacob Faibussowitsch {
540f3161b27SJose E. Roman   PC_PARMS *parms = (PC_PARMS *)pc->data;
541f3161b27SJose E. Roman 
542f3161b27SJose E. Roman   PetscFunctionBegin;
543f3161b27SJose E. Roman   if (lfil0 != parms->lfil[0] || lfil0 != parms->lfil[1] || lfil0 != parms->lfil[2] || lfil0 != parms->lfil[3]) {
544f3161b27SJose E. Roman     parms->lfil[1] = parms->lfil[2] = parms->lfil[3] = parms->lfil[0] = lfil0;
545371d2eb7SMartin Diehl     pc->setupcalled                                                   = PETSC_FALSE;
546f3161b27SJose E. Roman   }
547f3161b27SJose E. Roman   if (lfil1 != parms->lfil[4]) {
548f3161b27SJose E. Roman     parms->lfil[4]  = lfil1;
549371d2eb7SMartin Diehl     pc->setupcalled = PETSC_FALSE;
550f3161b27SJose E. Roman   }
551f3161b27SJose E. Roman   if (lfil2 != parms->lfil[5] || lfil2 != parms->lfil[6]) {
552f3161b27SJose E. Roman     parms->lfil[5] = parms->lfil[6] = lfil2;
553371d2eb7SMartin Diehl     pc->setupcalled                 = PETSC_FALSE;
554f3161b27SJose E. Roman   }
5553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
556f3161b27SJose E. Roman }
557f3161b27SJose E. Roman 
5585de0dacdSJose E. Roman /*@
559f3161b27SJose E. Roman   PCPARMSSetFill - Sets the fill-in parameters for ILUT, ILUK and ARMS preconditioners.
560f3161b27SJose E. Roman   Consider the original matrix A = [B F; E C] and the approximate version
561f3161b27SJose E. Roman   M = [LB 0; E/UB I]*[UB LB\F; 0 S].
562f3161b27SJose E. Roman 
563c3339decSBarry Smith   Collective
564f3161b27SJose E. Roman 
565f3161b27SJose E. Roman   Input Parameters:
566f3161b27SJose E. Roman + pc    - the preconditioner context
567feefa0e1SJacob Faibussowitsch . lfil0 - the level of fill-in kept in LB, UB, E/UB and LB\F
568feefa0e1SJacob Faibussowitsch . lfil1 - the level of fill-in kept in S
569feefa0e1SJacob Faibussowitsch - lfil2 - the level of fill-in kept in the L and U parts of the LU factorization of S
570f3161b27SJose E. Roman 
571f3161b27SJose E. Roman   Options Database Keys:
572f3161b27SJose E. Roman + -pc_parms_lfil_ilu_arms - set the amount of fill-in for ilut, iluk and arms
573f3161b27SJose E. Roman . -pc_parms_lfil_schur    - set the amount of fill-in for schur
574f3161b27SJose E. Roman - -pc_parms_lfil_ilut_L_U - set the amount of fill-in for ILUT L and U
575f3161b27SJose E. Roman 
576f3161b27SJose E. Roman   Level: intermediate
577f3161b27SJose E. Roman 
578f1580f4eSBarry Smith   Note:
579f1580f4eSBarry Smith   See the pARMS function `parms_PCSetFill()` for more information.
580f3161b27SJose E. Roman 
581562efe2eSBarry Smith .seealso: [](ch_ksp), `PCPARMS`
582f3161b27SJose E. Roman @*/
PCPARMSSetFill(PC pc,PetscInt lfil0,PetscInt lfil1,PetscInt lfil2)583d71ae5a4SJacob Faibussowitsch PetscErrorCode PCPARMSSetFill(PC pc, PetscInt lfil0, PetscInt lfil1, PetscInt lfil2)
584d71ae5a4SJacob Faibussowitsch {
585f3161b27SJose E. Roman   PetscFunctionBegin;
586f3161b27SJose E. Roman   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
587cac4c232SBarry Smith   PetscTryMethod(pc, "PCPARMSSetFill_C", (PC, PetscInt, PetscInt, PetscInt), (pc, lfil0, lfil1, lfil2));
5883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
589f3161b27SJose E. Roman }
590f3161b27SJose E. Roman 
591f3161b27SJose E. Roman /*MC
592f3161b27SJose E. Roman    PCPARMS - Allows the use of the parallel Algebraic Recursive Multilevel Solvers
593f3161b27SJose E. Roman       available in the package pARMS
594f3161b27SJose E. Roman 
595f3161b27SJose E. Roman    Options Database Keys:
596f3161b27SJose E. Roman +  -pc_parms_global - one of ras, schur, bj
597f3161b27SJose E. Roman .  -pc_parms_local - one of ilu0, iluk, ilut, arms
598f3161b27SJose E. Roman .  -pc_parms_solve_tol - set the tolerance for local solve
599f3161b27SJose E. Roman .  -pc_parms_levels - set the number of levels
600f3161b27SJose E. Roman .  -pc_parms_nonsymmetric_perm - set the use of nonsymmetric permutation
601f3161b27SJose E. Roman .  -pc_parms_blocksize - set the block size
602f3161b27SJose E. Roman .  -pc_parms_ind_tol - set the tolerance for independent sets
603f3161b27SJose E. Roman .  -pc_parms_max_dim - set the inner krylov dimension
604f3161b27SJose E. Roman .  -pc_parms_max_it - set the maximum number of inner iterations
6054b62eef3SJose E. Roman .  -pc_parms_inter_nonsymmetric_perm - set the use of nonsymmetric permutation for interlevel blocks
606f3161b27SJose E. Roman .  -pc_parms_inter_column_perm - set the use of column permutation for interlevel blocks
607f3161b27SJose E. Roman .  -pc_parms_inter_row_scaling - set the use of row scaling for interlevel blocks
608f3161b27SJose E. Roman .  -pc_parms_inter_column_scaling - set the use of column scaling for interlevel blocks
6094b62eef3SJose E. Roman .  -pc_parms_last_nonsymmetric_perm - set the use of nonsymmetric permutation for last level blocks
610f3161b27SJose E. Roman .  -pc_parms_last_column_perm - set the use of column permutation for last level blocks
611f3161b27SJose E. Roman .  -pc_parms_last_row_scaling - set the use of row scaling for last level blocks
612f3161b27SJose E. Roman .  -pc_parms_last_column_scaling - set the use of column scaling for last level blocks
613f3161b27SJose E. Roman .  -pc_parms_lfil_ilu_arms - set the amount of fill-in for ilut, iluk and arms
614f3161b27SJose E. Roman .  -pc_parms_lfil_schur - set the amount of fill-in for schur
615f3161b27SJose E. Roman .  -pc_parms_lfil_ilut_L_U - set the amount of fill-in for ILUT L and U
616f3161b27SJose E. Roman .  -pc_parms_droptol_factors - set the drop tolerance for L, U, L^{-1}F and EU^{-1}
617f3161b27SJose E. Roman .  -pc_parms_droptol_schur_compl - set the drop tolerance for schur complement at each level
618f3161b27SJose E. Roman -  -pc_parms_droptol_last_schur - set the drop tolerance for ILUT in last level schur complement
619f3161b27SJose E. Roman 
620f1580f4eSBarry Smith    Note:
621f3161b27SJose E. Roman    Unless configured appropriately, this preconditioner performs an inexact solve
622f3161b27SJose E. Roman    as part of the preconditioner application. Therefore, it must be used in combination
623f1580f4eSBarry Smith    with flexible variants of iterative solvers, such as `KSPFGMRES` or `KSPGCR`.
624f3161b27SJose E. Roman 
625f3161b27SJose E. Roman    Level: intermediate
626f3161b27SJose E. Roman 
627562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCSetType()`, `PCType`, `PC`, `PCMG`, `PCGAMG`, `PCHYPRE`, `PCPARMSSetGlobal()`,
628f1580f4eSBarry Smith           `PCPARMSSetLocal()`, `PCPARMSSetSolveTolerances()`, `PCPARMSSetSolveRestart()`, `PCPARMSSetNonsymPerm()`,
629f1580f4eSBarry Smith           `PCPARMSSetFill()`
630f3161b27SJose E. Roman M*/
631f3161b27SJose E. Roman 
PCCreate_PARMS(PC pc)632d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_PARMS(PC pc)
633d71ae5a4SJacob Faibussowitsch {
634f3161b27SJose E. Roman   PC_PARMS *parms;
635f3161b27SJose E. Roman 
636f3161b27SJose E. Roman   PetscFunctionBegin;
6374dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&parms));
6382fa5cd67SKarl Rupp 
639f3161b27SJose E. Roman   parms->map        = 0;
640f3161b27SJose E. Roman   parms->A          = 0;
641f3161b27SJose E. Roman   parms->pc         = 0;
642abd6c125SJose E. Roman   parms->global     = PC_PARMS_GLOBAL_RAS;
643f3161b27SJose E. Roman   parms->local      = PC_PARMS_LOCAL_ARMS;
644f3161b27SJose E. Roman   parms->levels     = 10;
645f3161b27SJose E. Roman   parms->nonsymperm = PETSC_TRUE;
646f3161b27SJose E. Roman   parms->blocksize  = 250;
647abd6c125SJose E. Roman   parms->maxdim     = 0;
648abd6c125SJose E. Roman   parms->maxits     = 0;
6494b62eef3SJose E. Roman   parms->meth[0]    = PETSC_FALSE;
6504b62eef3SJose E. Roman   parms->meth[1]    = PETSC_FALSE;
6514b62eef3SJose E. Roman   parms->meth[2]    = PETSC_FALSE;
6524b62eef3SJose E. Roman   parms->meth[3]    = PETSC_FALSE;
6534b62eef3SJose E. Roman   parms->meth[4]    = PETSC_FALSE;
6544b62eef3SJose E. Roman   parms->meth[5]    = PETSC_FALSE;
6554b62eef3SJose E. Roman   parms->meth[6]    = PETSC_FALSE;
6564b62eef3SJose E. Roman   parms->meth[7]    = PETSC_FALSE;
657f3161b27SJose E. Roman   parms->solvetol   = 0.01;
658f3161b27SJose E. Roman   parms->indtol     = 0.4;
659f3161b27SJose E. Roman   parms->lfil[0] = parms->lfil[1] = parms->lfil[2] = parms->lfil[3] = 20;
660f3161b27SJose E. Roman   parms->lfil[4] = parms->lfil[5] = parms->lfil[6] = 20;
661f3161b27SJose E. Roman   parms->droptol[0] = parms->droptol[1] = parms->droptol[2] = parms->droptol[3] = 0.00001;
662f3161b27SJose E. Roman   parms->droptol[4]                                                             = 0.001;
663f3161b27SJose E. Roman   parms->droptol[5] = parms->droptol[6] = 0.001;
6642fa5cd67SKarl Rupp 
665f3161b27SJose E. Roman   pc->data                = parms;
666f3161b27SJose E. Roman   pc->ops->destroy        = PCDestroy_PARMS;
667f3161b27SJose E. Roman   pc->ops->setfromoptions = PCSetFromOptions_PARMS;
668f3161b27SJose E. Roman   pc->ops->setup          = PCSetUp_PARMS;
669f3161b27SJose E. Roman   pc->ops->apply          = PCApply_PARMS;
670f3161b27SJose E. Roman   pc->ops->view           = PCView_PARMS;
6712fa5cd67SKarl Rupp 
6729566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetGlobal_C", PCPARMSSetGlobal_PARMS));
6739566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetLocal_C", PCPARMSSetLocal_PARMS));
6749566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetSolveTolerances_C", PCPARMSSetSolveTolerances_PARMS));
6759566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetSolveRestart_C", PCPARMSSetSolveRestart_PARMS));
6769566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetNonsymPerm_C", PCPARMSSetNonsymPerm_PARMS));
6779566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetFill_C", PCPARMSSetFill_PARMS));
6783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
679f3161b27SJose E. Roman }
680