xref: /petsc/src/ksp/pc/impls/parms/parms.c (revision f6a5184a3a2c27ff00638537a9572f94b3ab6275)
1f3161b27SJose E. Roman #define PETSCKSP_DLL
2f3161b27SJose E. Roman 
3f3161b27SJose E. Roman /*
4f3161b27SJose E. Roman    Provides an interface to pARMS.
5f3161b27SJose E. Roman    Requires pARMS 3.2 or later.
6f3161b27SJose E. Roman */
7f3161b27SJose E. Roman 
8af0996ceSBarry Smith #include <petsc/private/pcimpl.h>          /*I "petscpc.h" I*/
9f3161b27SJose E. Roman 
10519f805aSKarl Rupp #if defined(PETSC_USE_COMPLEX)
11f3161b27SJose E. Roman #define DBL_CMPLX
12f3161b27SJose E. Roman #else
13f3161b27SJose E. Roman #define DBL
14f3161b27SJose E. Roman #endif
15f3161b27SJose E. Roman #define USE_MPI
16f3161b27SJose E. Roman #define REAL double
17f3161b27SJose E. Roman #define HAS_BLAS
18f3161b27SJose E. Roman #define FORTRAN_UNDERSCORE
19f3161b27SJose E. Roman #include "parms_sys.h"
20f3161b27SJose E. Roman #undef FLOAT
21f3161b27SJose E. Roman #define FLOAT PetscScalar
22aaa7dc30SBarry Smith #include <parms.h>
23f3161b27SJose E. Roman 
24f3161b27SJose E. Roman /*
25f3161b27SJose E. Roman    Private context (data structure) for the  preconditioner.
26f3161b27SJose E. Roman */
27f3161b27SJose E. Roman typedef struct {
28f3161b27SJose E. Roman   parms_Map         map;
29f3161b27SJose E. Roman   parms_Mat         A;
30f3161b27SJose E. Roman   parms_PC          pc;
31f3161b27SJose E. Roman   PCPARMSGlobalType global;
32f3161b27SJose E. Roman   PCPARMSLocalType  local;
33f3161b27SJose E. Roman   PetscInt          levels, blocksize, maxdim, maxits, lfil[7];
34f3161b27SJose E. Roman   PetscBool         nonsymperm, meth[8];
35f3161b27SJose E. Roman   PetscReal         solvetol, indtol, droptol[7];
36f3161b27SJose E. Roman   PetscScalar       *lvec0, *lvec1;
37f3161b27SJose E. Roman } PC_PARMS;
38f3161b27SJose E. Roman 
39f3161b27SJose E. Roman 
40f3161b27SJose E. Roman static PetscErrorCode PCSetUp_PARMS(PC pc)
41f3161b27SJose E. Roman {
42f3161b27SJose E. Roman   Mat               pmat;
43f3161b27SJose E. Roman   PC_PARMS          *parms = (PC_PARMS*)pc->data;
44f3161b27SJose E. Roman   const PetscInt    *mapptr0;
45f3161b27SJose E. Roman   PetscInt          n, lsize, low, high, i, pos, ncols, length;
46f3161b27SJose E. Roman   int               *maptmp, *mapptr, *ia, *ja, *ja1, *im;
47f3161b27SJose E. Roman   PetscScalar       *aa, *aa1;
48f3161b27SJose E. Roman   const PetscInt    *cols;
49f3161b27SJose E. Roman   PetscInt          meth[8];
50f3161b27SJose E. Roman   const PetscScalar *values;
51f3161b27SJose E. Roman   PetscErrorCode    ierr;
52f3161b27SJose E. Roman   MatInfo           matinfo;
53f3161b27SJose E. Roman   PetscMPIInt       rank, npro;
54f3161b27SJose E. Roman 
55f3161b27SJose E. Roman   PetscFunctionBegin;
56f3161b27SJose E. Roman   /* Get preconditioner matrix from PETSc and setup pARMS structs */
5762279869SBarry Smith   ierr = PCGetOperators(pc,NULL,&pmat);CHKERRQ(ierr);
58ce94432eSBarry Smith   MPI_Comm_size(PetscObjectComm((PetscObject)pmat),&npro);
59ce94432eSBarry Smith   MPI_Comm_rank(PetscObjectComm((PetscObject)pmat),&rank);
60f3161b27SJose E. Roman 
610298fd71SBarry Smith   ierr  = MatGetSize(pmat,&n,NULL);CHKERRQ(ierr);
62854ce69bSBarry Smith   ierr  = PetscMalloc1(npro+1,&mapptr);CHKERRQ(ierr);
63785e854fSJed Brown   ierr  = PetscMalloc1(n,&maptmp);CHKERRQ(ierr);
64f3161b27SJose E. Roman   ierr  = MatGetOwnershipRanges(pmat,&mapptr0);CHKERRQ(ierr);
65f3161b27SJose E. Roman   low   = mapptr0[rank];
66f3161b27SJose E. Roman   high  = mapptr0[rank+1];
67f3161b27SJose E. Roman   lsize = high - low;
68f3161b27SJose E. Roman 
692fa5cd67SKarl Rupp   for (i=0; i<npro+1; i++) mapptr[i] = mapptr0[i]+1;
702fa5cd67SKarl Rupp   for (i = 0; i<n; i++) maptmp[i] = i+1;
71f3161b27SJose E. Roman 
72f3161b27SJose E. Roman   /* if created, destroy the previous map */
73f3161b27SJose E. Roman   if (parms->map) {
74f3161b27SJose E. Roman     parms_MapFree(&parms->map);
750298fd71SBarry Smith     parms->map = NULL;
76f3161b27SJose E. Roman   }
77f3161b27SJose E. Roman 
78f3161b27SJose E. Roman   /* create pARMS map object */
79ce94432eSBarry Smith   parms_MapCreateFromPtr(&parms->map,(int)n,maptmp,mapptr,PetscObjectComm((PetscObject)pmat),1,NONINTERLACED);
80f3161b27SJose E. Roman 
81f3161b27SJose E. Roman   /* if created, destroy the previous pARMS matrix */
82f3161b27SJose E. Roman   if (parms->A) {
83f3161b27SJose E. Roman     parms_MatFree(&parms->A);
840298fd71SBarry Smith     parms->A = NULL;
85f3161b27SJose E. Roman   }
86f3161b27SJose E. Roman 
87f3161b27SJose E. Roman   /* create pARMS mat object */
88f3161b27SJose E. Roman   parms_MatCreate(&parms->A,parms->map);
89f3161b27SJose E. Roman 
90f3161b27SJose E. Roman   /* setup and copy csr data structure for pARMS */
91854ce69bSBarry Smith   ierr   = PetscMalloc1(lsize+1,&ia);CHKERRQ(ierr);
92f3161b27SJose E. Roman   ia[0]  = 1;
93f3161b27SJose E. Roman   ierr   = MatGetInfo(pmat,MAT_LOCAL,&matinfo);CHKERRQ(ierr);
94f3161b27SJose E. Roman   length = matinfo.nz_used;
95785e854fSJed Brown   ierr   = PetscMalloc1(length,&ja);CHKERRQ(ierr);
96785e854fSJed Brown   ierr   = PetscMalloc1(length,&aa);CHKERRQ(ierr);
97f3161b27SJose E. Roman 
98f3161b27SJose E. Roman   for (i = low; i<high; i++) {
99f3161b27SJose E. Roman     pos         = ia[i-low]-1;
100f3161b27SJose E. Roman     ierr        = MatGetRow(pmat,i,&ncols,&cols,&values);CHKERRQ(ierr);
101f3161b27SJose E. Roman     ia[i-low+1] = ia[i-low] + ncols;
102f3161b27SJose E. Roman 
103f3161b27SJose E. Roman     if (ia[i-low+1] >= length) {
104f3161b27SJose E. Roman       length += ncols;
105785e854fSJed Brown       ierr    = PetscMalloc1(length,&ja1);CHKERRQ(ierr);
106f3161b27SJose E. Roman       ierr    = PetscMemcpy(ja1,ja,(ia[i-low]-1)*sizeof(int));CHKERRQ(ierr);
107f3161b27SJose E. Roman       ierr    = PetscFree(ja);CHKERRQ(ierr);
108f3161b27SJose E. Roman       ja      = ja1;
109785e854fSJed Brown       ierr    = PetscMalloc1(length,&aa1);CHKERRQ(ierr);
110f3161b27SJose E. Roman       ierr    = PetscMemcpy(aa1,aa,(ia[i-low]-1)*sizeof(PetscScalar));CHKERRQ(ierr);
111f3161b27SJose E. Roman       ierr    = PetscFree(aa);CHKERRQ(ierr);
112f3161b27SJose E. Roman       aa      = aa1;
113f3161b27SJose E. Roman     }
114f3161b27SJose E. Roman     ierr = PetscMemcpy(&ja[pos],cols,ncols*sizeof(int));CHKERRQ(ierr);
115f3161b27SJose E. Roman     ierr = PetscMemcpy(&aa[pos],values,ncols*sizeof(PetscScalar));CHKERRQ(ierr);
116f3161b27SJose E. Roman     ierr = MatRestoreRow(pmat,i,&ncols,&cols,&values);CHKERRQ(ierr);
117f3161b27SJose E. Roman   }
118f3161b27SJose E. Roman 
119f3161b27SJose E. Roman   /* csr info is for local matrix so initialize im[] locally */
120785e854fSJed Brown   ierr = PetscMalloc1(lsize,&im);CHKERRQ(ierr);
121f3161b27SJose E. Roman   ierr = PetscMemcpy(im,&maptmp[mapptr[rank]-1],lsize*sizeof(int));CHKERRQ(ierr);
122f3161b27SJose E. Roman 
123f3161b27SJose E. Roman   /* 1-based indexing */
1242fa5cd67SKarl Rupp   for (i=0; i<ia[lsize]-1; i++) ja[i] = ja[i]+1;
125f3161b27SJose E. Roman 
126f3161b27SJose E. Roman   /* Now copy csr matrix to parms_mat object */
127f3161b27SJose E. Roman   parms_MatSetValues(parms->A,(int)lsize,im,ia,ja,aa,INSERT);
128f3161b27SJose E. Roman 
129f3161b27SJose E. Roman   /* free memory */
130f3161b27SJose E. Roman   ierr = PetscFree(maptmp);CHKERRQ(ierr);
131f3161b27SJose E. Roman   ierr = PetscFree(mapptr);CHKERRQ(ierr);
132f3161b27SJose E. Roman   ierr = PetscFree(aa);CHKERRQ(ierr);
133f3161b27SJose E. Roman   ierr = PetscFree(ja);CHKERRQ(ierr);
134f3161b27SJose E. Roman   ierr = PetscFree(ia);CHKERRQ(ierr);
135f3161b27SJose E. Roman   ierr = PetscFree(im);CHKERRQ(ierr);
136f3161b27SJose E. Roman 
137f3161b27SJose E. Roman   /* setup parms matrix */
138f3161b27SJose E. Roman   parms_MatSetup(parms->A);
139f3161b27SJose E. Roman 
140f3161b27SJose E. Roman   /* if created, destroy the previous pARMS pc */
141f3161b27SJose E. Roman   if (parms->pc) {
142f3161b27SJose E. Roman     parms_PCFree(&parms->pc);
1430298fd71SBarry Smith     parms->pc = NULL;
144f3161b27SJose E. Roman   }
145f3161b27SJose E. Roman 
146f3161b27SJose E. Roman   /* Now create pARMS preconditioner object based on A */
147f3161b27SJose E. Roman   parms_PCCreate(&parms->pc,parms->A);
148f3161b27SJose E. Roman 
149f3161b27SJose E. Roman   /* Transfer options from PC to pARMS */
150f3161b27SJose E. Roman   switch (parms->global) {
151f3161b27SJose E. Roman   case 0: parms_PCSetType(parms->pc, PCRAS); break;
152f3161b27SJose E. Roman   case 1: parms_PCSetType(parms->pc, PCSCHUR); break;
153f3161b27SJose E. Roman   case 2: parms_PCSetType(parms->pc, PCBJ); break;
154f3161b27SJose E. Roman   }
155f3161b27SJose E. Roman   switch (parms->local) {
156f3161b27SJose E. Roman   case 0: parms_PCSetILUType(parms->pc, PCILU0); break;
157f3161b27SJose E. Roman   case 1: parms_PCSetILUType(parms->pc, PCILUK); break;
158f3161b27SJose E. Roman   case 2: parms_PCSetILUType(parms->pc, PCILUT); break;
159f3161b27SJose E. Roman   case 3: parms_PCSetILUType(parms->pc, PCARMS); break;
160f3161b27SJose E. Roman   }
161f3161b27SJose E. Roman   parms_PCSetInnerEps(parms->pc, parms->solvetol);
162f3161b27SJose E. Roman   parms_PCSetNlevels(parms->pc, parms->levels);
163f3161b27SJose E. Roman   parms_PCSetPermType(parms->pc, parms->nonsymperm ? 1 : 0);
164f3161b27SJose E. Roman   parms_PCSetBsize(parms->pc, parms->blocksize);
165f3161b27SJose E. Roman   parms_PCSetTolInd(parms->pc, parms->indtol);
166f3161b27SJose E. Roman   parms_PCSetInnerKSize(parms->pc, parms->maxdim);
167f3161b27SJose E. Roman   parms_PCSetInnerMaxits(parms->pc, parms->maxits);
168f3161b27SJose E. Roman   for (i=0; i<8; i++) meth[i] = parms->meth[i] ? 1 : 0;
169f3161b27SJose E. Roman   parms_PCSetPermScalOptions(parms->pc, &meth[0], 1);
170f3161b27SJose E. Roman   parms_PCSetPermScalOptions(parms->pc, &meth[4], 0);
171f3161b27SJose E. Roman   parms_PCSetFill(parms->pc, parms->lfil);
172f3161b27SJose E. Roman   parms_PCSetTol(parms->pc, parms->droptol);
173f3161b27SJose E. Roman 
174f3161b27SJose E. Roman   parms_PCSetup(parms->pc);
175f3161b27SJose E. Roman 
176f3161b27SJose E. Roman   /* Allocate two auxiliary vector of length lsize */
177f3161b27SJose E. Roman   if (parms->lvec0) { ierr = PetscFree(parms->lvec0);CHKERRQ(ierr); }
178785e854fSJed Brown   ierr = PetscMalloc1(lsize, &parms->lvec0);CHKERRQ(ierr);
179f3161b27SJose E. Roman   if (parms->lvec1) { ierr = PetscFree(parms->lvec1);CHKERRQ(ierr); }
180785e854fSJed Brown   ierr = PetscMalloc1(lsize, &parms->lvec1);CHKERRQ(ierr);
181f3161b27SJose E. Roman   PetscFunctionReturn(0);
182f3161b27SJose E. Roman }
183f3161b27SJose E. Roman 
184f3161b27SJose E. Roman static PetscErrorCode PCView_PARMS(PC pc,PetscViewer viewer)
185f3161b27SJose E. Roman {
186f3161b27SJose E. Roman   PetscErrorCode ierr;
187f3161b27SJose E. Roman   PetscBool      iascii;
188f3161b27SJose E. Roman   PC_PARMS       *parms = (PC_PARMS*)pc->data;
189f3161b27SJose E. Roman   char           *str;
190f3161b27SJose E. Roman   double         fill_fact;
191f3161b27SJose E. Roman 
192f3161b27SJose E. Roman   PetscFunctionBegin;
193251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
194f3161b27SJose E. Roman   if (iascii) {
195f3161b27SJose E. Roman     parms_PCGetName(parms->pc,&str);
196f3161b27SJose E. Roman     ierr = PetscViewerASCIIPrintf(viewer,"  global preconditioner: %s\n",str);CHKERRQ(ierr);
197f3161b27SJose E. Roman     parms_PCILUGetName(parms->pc,&str);
198f3161b27SJose E. Roman     ierr = PetscViewerASCIIPrintf(viewer,"  local preconditioner: %s\n",str);CHKERRQ(ierr);
199f3161b27SJose E. Roman     parms_PCGetRatio(parms->pc,&fill_fact);
200f3161b27SJose E. Roman     ierr = PetscViewerASCIIPrintf(viewer,"  non-zero elements/original non-zero entries: %-4.2f\n",fill_fact);CHKERRQ(ierr);
201f3161b27SJose E. Roman     ierr = PetscViewerASCIIPrintf(viewer,"  Tolerance for local solve: %g\n",parms->solvetol);CHKERRQ(ierr);
202f3161b27SJose E. Roman     ierr = PetscViewerASCIIPrintf(viewer,"  Number of levels: %d\n",parms->levels);CHKERRQ(ierr);
203f3161b27SJose E. Roman     if (parms->nonsymperm) {
204f3161b27SJose E. Roman       ierr = PetscViewerASCIIPrintf(viewer,"  Using nonsymmetric permutation\n");CHKERRQ(ierr);
205f3161b27SJose E. Roman     }
206f3161b27SJose E. Roman     ierr = PetscViewerASCIIPrintf(viewer,"  Block size: %d\n",parms->blocksize);CHKERRQ(ierr);
207f3161b27SJose E. Roman     ierr = PetscViewerASCIIPrintf(viewer,"  Tolerance for independent sets: %g\n",parms->indtol);CHKERRQ(ierr);
208f3161b27SJose E. Roman     ierr = PetscViewerASCIIPrintf(viewer,"  Inner Krylov dimension: %d\n",parms->maxdim);CHKERRQ(ierr);
209f3161b27SJose E. Roman     ierr = PetscViewerASCIIPrintf(viewer,"  Maximum number of inner iterations: %d\n",parms->maxits);CHKERRQ(ierr);
210f3161b27SJose E. Roman     if (parms->meth[0]) {
211f3161b27SJose E. Roman       ierr = PetscViewerASCIIPrintf(viewer,"  Using nonsymmetric permutation for interlevel blocks\n");CHKERRQ(ierr);
212f3161b27SJose E. Roman     }
213f3161b27SJose E. Roman     if (parms->meth[1]) {
214f3161b27SJose E. Roman       ierr = PetscViewerASCIIPrintf(viewer,"  Using column permutation for interlevel blocks\n");CHKERRQ(ierr);
215f3161b27SJose E. Roman     }
216f3161b27SJose E. Roman     if (parms->meth[2]) {
217f3161b27SJose E. Roman       ierr = PetscViewerASCIIPrintf(viewer,"  Using row scaling for interlevel blocks\n");CHKERRQ(ierr);
218f3161b27SJose E. Roman     }
219f3161b27SJose E. Roman     if (parms->meth[3]) {
220f3161b27SJose E. Roman       ierr = PetscViewerASCIIPrintf(viewer,"  Using column scaling for interlevel blocks\n");CHKERRQ(ierr);
221f3161b27SJose E. Roman     }
222f3161b27SJose E. Roman     if (parms->meth[4]) {
223f3161b27SJose E. Roman       ierr = PetscViewerASCIIPrintf(viewer,"  Using nonsymmetric permutation for last level blocks\n");CHKERRQ(ierr);
224f3161b27SJose E. Roman     }
225f3161b27SJose E. Roman     if (parms->meth[5]) {
226f3161b27SJose E. Roman       ierr = PetscViewerASCIIPrintf(viewer,"  Using column permutation for last level blocks\n");CHKERRQ(ierr);
227f3161b27SJose E. Roman     }
228f3161b27SJose E. Roman     if (parms->meth[6]) {
229f3161b27SJose E. Roman       ierr = PetscViewerASCIIPrintf(viewer,"  Using row scaling for last level blocks\n");CHKERRQ(ierr);
230f3161b27SJose E. Roman     }
231f3161b27SJose E. Roman     if (parms->meth[7]) {
232f3161b27SJose E. Roman       ierr = PetscViewerASCIIPrintf(viewer,"  Using column scaling for last level blocks\n");CHKERRQ(ierr);
233f3161b27SJose E. Roman     }
234f3161b27SJose E. Roman     ierr = PetscViewerASCIIPrintf(viewer,"  amount of fill-in for ilut, iluk and arms: %d\n",parms->lfil[0]);CHKERRQ(ierr);
235f3161b27SJose E. Roman     ierr = PetscViewerASCIIPrintf(viewer,"  amount of fill-in for schur: %d\n",parms->lfil[4]);CHKERRQ(ierr);
236f3161b27SJose E. Roman     ierr = PetscViewerASCIIPrintf(viewer,"  amount of fill-in for ILUT L and U: %d\n",parms->lfil[5]);CHKERRQ(ierr);
237f3161b27SJose E. Roman     ierr = PetscViewerASCIIPrintf(viewer,"  drop tolerance for L, U, L^{-1}F and EU^{-1}: %g\n",parms->droptol[0]);CHKERRQ(ierr);
238f3161b27SJose E. Roman     ierr = PetscViewerASCIIPrintf(viewer,"  drop tolerance for schur complement at each level: %g\n",parms->droptol[4]);CHKERRQ(ierr);
239f3161b27SJose E. Roman     ierr = PetscViewerASCIIPrintf(viewer,"  drop tolerance for ILUT in last level schur complement: %g\n",parms->droptol[5]);CHKERRQ(ierr);
240f3161b27SJose E. Roman   }
241f3161b27SJose E. Roman   PetscFunctionReturn(0);
242f3161b27SJose E. Roman }
243f3161b27SJose E. Roman 
244f3161b27SJose E. Roman static PetscErrorCode PCDestroy_PARMS(PC pc)
245f3161b27SJose E. Roman {
246f3161b27SJose E. Roman   PC_PARMS       *parms = (PC_PARMS*)pc->data;
247f3161b27SJose E. Roman   PetscErrorCode ierr;
248f3161b27SJose E. Roman 
249f3161b27SJose E. Roman   PetscFunctionBegin;
2502fa5cd67SKarl Rupp   if (parms->map) parms_MapFree(&parms->map);
2512fa5cd67SKarl Rupp   if (parms->A) parms_MatFree(&parms->A);
2522fa5cd67SKarl Rupp   if (parms->pc) parms_PCFree(&parms->pc);
253f3161b27SJose E. Roman   if (parms->lvec0) {
254f3161b27SJose E. Roman     ierr = PetscFree(parms->lvec0);CHKERRQ(ierr);
255f3161b27SJose E. Roman   }
256f3161b27SJose E. Roman   if (parms->lvec1) {
257f3161b27SJose E. Roman     ierr = PetscFree(parms->lvec1);CHKERRQ(ierr);
258f3161b27SJose E. Roman   }
259f3161b27SJose E. Roman   ierr = PetscFree(pc->data);CHKERRQ(ierr);
260f3161b27SJose E. Roman 
261f3161b27SJose E. Roman   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
262bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetGlobal_C",NULL);CHKERRQ(ierr);
263bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetLocal_C",NULL);CHKERRQ(ierr);
264bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetSolveTolerances_C",NULL);CHKERRQ(ierr);
265bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetSolveRestart_C",NULL);CHKERRQ(ierr);
266bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetNonsymPerm_C",NULL);CHKERRQ(ierr);
267bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetFill_C",NULL);CHKERRQ(ierr);
268f3161b27SJose E. Roman   PetscFunctionReturn(0);
269f3161b27SJose E. Roman }
270f3161b27SJose E. Roman 
2714416b707SBarry Smith static PetscErrorCode PCSetFromOptions_PARMS(PetscOptionItems *PetscOptionsObject,PC pc)
272f3161b27SJose E. Roman {
273f3161b27SJose E. Roman   PC_PARMS          *parms = (PC_PARMS*)pc->data;
274f3161b27SJose E. Roman   PetscBool         flag;
275f3161b27SJose E. Roman   PCPARMSGlobalType global;
276f3161b27SJose E. Roman   PCPARMSLocalType  local;
277f3161b27SJose E. Roman   PetscErrorCode    ierr;
278f3161b27SJose E. Roman 
279f3161b27SJose E. Roman   PetscFunctionBegin;
280e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PARMS Options");CHKERRQ(ierr);
281f3161b27SJose E. Roman   ierr = PetscOptionsEnum("-pc_parms_global","Global preconditioner","PCPARMSSetGlobal",PCPARMSGlobalTypes,(PetscEnum)parms->global,(PetscEnum*)&global,&flag);CHKERRQ(ierr);
282f3161b27SJose E. Roman   if (flag) {ierr = PCPARMSSetGlobal(pc,global);CHKERRQ(ierr);}
283f3161b27SJose E. Roman   ierr = PetscOptionsEnum("-pc_parms_local","Local preconditioner","PCPARMSSetLocal",PCPARMSLocalTypes,(PetscEnum)parms->local,(PetscEnum*)&local,&flag);CHKERRQ(ierr);
284f3161b27SJose E. Roman   if (flag) {ierr = PCPARMSSetLocal(pc,local);CHKERRQ(ierr);}
28594ae4db5SBarry Smith   ierr = PetscOptionsReal("-pc_parms_solve_tol","Tolerance for local solve","PCPARMSSetSolveTolerances",parms->solvetol,&parms->solvetol,NULL);CHKERRQ(ierr);
28694ae4db5SBarry Smith   ierr = PetscOptionsInt("-pc_parms_levels","Number of levels","None",parms->levels,&parms->levels,NULL);CHKERRQ(ierr);
28794ae4db5SBarry Smith   ierr = PetscOptionsBool("-pc_parms_nonsymmetric_perm","Use nonsymmetric permutation","PCPARMSSetNonsymPerm",parms->nonsymperm,&parms->nonsymperm,NULL);CHKERRQ(ierr);
28894ae4db5SBarry Smith   ierr = PetscOptionsInt("-pc_parms_blocksize","Block size","None",parms->blocksize,&parms->blocksize,NULL);CHKERRQ(ierr);
28994ae4db5SBarry Smith   ierr = PetscOptionsReal("-pc_parms_ind_tol","Tolerance for independent sets","None",parms->indtol,&parms->indtol,NULL);CHKERRQ(ierr);
29094ae4db5SBarry Smith   ierr = PetscOptionsInt("-pc_parms_max_dim","Inner Krylov dimension","PCPARMSSetSolveRestart",parms->maxdim,&parms->maxdim,NULL);CHKERRQ(ierr);
29194ae4db5SBarry Smith   ierr = PetscOptionsInt("-pc_parms_max_it","Maximum number of inner iterations","PCPARMSSetSolveTolerances",parms->maxits,&parms->maxits,NULL);CHKERRQ(ierr);
29294ae4db5SBarry Smith   ierr = PetscOptionsBool("-pc_parms_inter_nonsymmetric_perm","nonsymmetric permutation for interlevel blocks","None",parms->meth[0],&parms->meth[0],NULL);CHKERRQ(ierr);
29394ae4db5SBarry Smith   ierr = PetscOptionsBool("-pc_parms_inter_column_perm","column permutation for interlevel blocks","None",parms->meth[1],&parms->meth[1],NULL);CHKERRQ(ierr);
29494ae4db5SBarry Smith   ierr = PetscOptionsBool("-pc_parms_inter_row_scaling","row scaling for interlevel blocks","None",parms->meth[2],&parms->meth[2],NULL);CHKERRQ(ierr);
29594ae4db5SBarry Smith   ierr = PetscOptionsBool("-pc_parms_inter_column_scaling","column scaling for interlevel blocks","None",parms->meth[3],&parms->meth[3],NULL);CHKERRQ(ierr);
29694ae4db5SBarry Smith   ierr = PetscOptionsBool("-pc_parms_last_nonsymmetric_perm","nonsymmetric permutation for last level blocks","None",parms->meth[4],&parms->meth[4],NULL);CHKERRQ(ierr);
29794ae4db5SBarry Smith   ierr = PetscOptionsBool("-pc_parms_last_column_perm","column permutation for last level blocks","None",parms->meth[5],&parms->meth[5],NULL);CHKERRQ(ierr);
29894ae4db5SBarry Smith   ierr = PetscOptionsBool("-pc_parms_last_row_scaling","row scaling for last level blocks","None",parms->meth[6],&parms->meth[6],NULL);CHKERRQ(ierr);
29994ae4db5SBarry Smith   ierr = PetscOptionsBool("-pc_parms_last_column_scaling","column scaling for last level blocks","None",parms->meth[7],&parms->meth[7],NULL);CHKERRQ(ierr);
300f3161b27SJose E. Roman   ierr = PetscOptionsInt("-pc_parms_lfil_ilu_arms","amount of fill-in for ilut, iluk and arms","PCPARMSSetFill",parms->lfil[0],&parms->lfil[0],&flag);CHKERRQ(ierr);
301f3161b27SJose E. Roman   if (flag) parms->lfil[1] = parms->lfil[2] = parms->lfil[3] = parms->lfil[0];
30294ae4db5SBarry Smith   ierr = PetscOptionsInt("-pc_parms_lfil_schur","amount of fill-in for schur","PCPARMSSetFill",parms->lfil[4],&parms->lfil[4],NULL);CHKERRQ(ierr);
303f3161b27SJose E. Roman   ierr = PetscOptionsInt("-pc_parms_lfil_ilut_L_U","amount of fill-in for ILUT L and U","PCPARMSSetFill",parms->lfil[5],&parms->lfil[5],&flag);CHKERRQ(ierr);
304f3161b27SJose E. Roman   if (flag) parms->lfil[6] = parms->lfil[5];
30594ae4db5SBarry Smith   ierr = PetscOptionsReal("-pc_parms_droptol_factors","drop tolerance for L, U, L^{-1}F and EU^{-1}","None",parms->droptol[0],&parms->droptol[0],NULL);CHKERRQ(ierr);
306f3161b27SJose E. Roman   ierr = PetscOptionsReal("-pc_parms_droptol_schur_compl","drop tolerance for schur complement at each level","None",parms->droptol[4],&parms->droptol[4],&flag);CHKERRQ(ierr);
307f3161b27SJose E. Roman   if (flag) parms->droptol[1] = parms->droptol[2] = parms->droptol[3] = parms->droptol[0];
308f3161b27SJose E. Roman   ierr = PetscOptionsReal("-pc_parms_droptol_last_schur","drop tolerance for ILUT in last level schur complement","None",parms->droptol[5],&parms->droptol[5],&flag);CHKERRQ(ierr);
309f3161b27SJose E. Roman   if (flag) parms->droptol[6] = parms->droptol[5];
310f3161b27SJose E. Roman   ierr = PetscOptionsTail();CHKERRQ(ierr);
311f3161b27SJose E. Roman   PetscFunctionReturn(0);
312f3161b27SJose E. Roman }
313f3161b27SJose E. Roman 
314f3161b27SJose E. Roman static PetscErrorCode PCApply_PARMS(PC pc,Vec b,Vec x)
315f3161b27SJose E. Roman {
316f3161b27SJose E. Roman   PetscErrorCode    ierr;
317f3161b27SJose E. Roman   PC_PARMS          *parms = (PC_PARMS*)pc->data;
318f3161b27SJose E. Roman   const PetscScalar *b1;
319f3161b27SJose E. Roman   PetscScalar       *x1;
320f3161b27SJose E. Roman 
321f3161b27SJose E. Roman   PetscFunctionBegin;
322f3161b27SJose E. Roman   ierr = VecGetArrayRead(b,&b1);CHKERRQ(ierr);
323f3161b27SJose E. Roman   ierr = VecGetArray(x,&x1);CHKERRQ(ierr);
324f3161b27SJose E. Roman   parms_VecPermAux((PetscScalar*)b1,parms->lvec0,parms->map);
325f3161b27SJose E. Roman   parms_PCApply(parms->pc,parms->lvec0,parms->lvec1);
326f3161b27SJose E. Roman   parms_VecInvPermAux(parms->lvec1,x1,parms->map);
327f3161b27SJose E. Roman   ierr = VecRestoreArrayRead(b,&b1);CHKERRQ(ierr);
328f3161b27SJose E. Roman   ierr = VecRestoreArray(x,&x1);CHKERRQ(ierr);
329f3161b27SJose E. Roman   PetscFunctionReturn(0);
330f3161b27SJose E. Roman }
331f3161b27SJose E. Roman 
332f7a08781SBarry Smith static PetscErrorCode PCPARMSSetGlobal_PARMS(PC pc,PCPARMSGlobalType type)
333f3161b27SJose E. Roman {
334f3161b27SJose E. Roman   PC_PARMS *parms = (PC_PARMS*)pc->data;
335f3161b27SJose E. Roman 
336f3161b27SJose E. Roman   PetscFunctionBegin;
337f3161b27SJose E. Roman   if (type != parms->global) {
338f3161b27SJose E. Roman     parms->global   = type;
339f3161b27SJose E. Roman     pc->setupcalled = 0;
340f3161b27SJose E. Roman   }
341f3161b27SJose E. Roman   PetscFunctionReturn(0);
342f3161b27SJose E. Roman }
343f3161b27SJose E. Roman 
3445de0dacdSJose E. Roman /*@
345f3161b27SJose E. Roman    PCPARMSSetGlobal - Sets the global preconditioner to be used in PARMS.
346f3161b27SJose E. Roman 
347f3161b27SJose E. Roman    Collective on PC
348f3161b27SJose E. Roman 
349f3161b27SJose E. Roman    Input Parameters:
350f3161b27SJose E. Roman +  pc - the preconditioner context
351f3161b27SJose E. Roman -  type - the global preconditioner type, one of
352f3161b27SJose E. Roman .vb
353f3161b27SJose E. Roman      PC_PARMS_GLOBAL_RAS   - Restricted additive Schwarz
354f3161b27SJose E. Roman      PC_PARMS_GLOBAL_SCHUR - Schur complement
355f3161b27SJose E. Roman      PC_PARMS_GLOBAL_BJ    - Block Jacobi
356f3161b27SJose E. Roman .ve
357f3161b27SJose E. Roman 
358f3161b27SJose E. Roman    Options Database Keys:
359f3161b27SJose E. Roman    -pc_parms_global [ras,schur,bj] - Sets global preconditioner
360f3161b27SJose E. Roman 
361f3161b27SJose E. Roman    Level: intermediate
362f3161b27SJose E. Roman 
363f3161b27SJose E. Roman    Notes:
364f3161b27SJose E. Roman    See the pARMS function parms_PCSetType for more information.
365f3161b27SJose E. Roman 
366f3161b27SJose E. Roman .seealso: PCPARMS, PCPARMSSetLocal()
367f3161b27SJose E. Roman @*/
368f3161b27SJose E. Roman PetscErrorCode PCPARMSSetGlobal(PC pc,PCPARMSGlobalType type)
369f3161b27SJose E. Roman {
370f3161b27SJose E. Roman   PetscErrorCode ierr;
371f3161b27SJose E. Roman 
372f3161b27SJose E. Roman   PetscFunctionBegin;
373f3161b27SJose E. Roman   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
374f3161b27SJose E. Roman   PetscValidLogicalCollectiveEnum(pc,type,2);
375f3161b27SJose E. Roman   ierr = PetscTryMethod(pc,"PCPARMSSetGlobal_C",(PC,PCPARMSGlobalType),(pc,type));CHKERRQ(ierr);
376f3161b27SJose E. Roman   PetscFunctionReturn(0);
377f3161b27SJose E. Roman }
378f3161b27SJose E. Roman 
379f7a08781SBarry Smith static PetscErrorCode PCPARMSSetLocal_PARMS(PC pc,PCPARMSLocalType type)
380f3161b27SJose E. Roman {
381f3161b27SJose E. Roman   PC_PARMS *parms = (PC_PARMS*)pc->data;
382f3161b27SJose E. Roman 
383f3161b27SJose E. Roman   PetscFunctionBegin;
384f3161b27SJose E. Roman   if (type != parms->local) {
385f3161b27SJose E. Roman     parms->local    = type;
386f3161b27SJose E. Roman     pc->setupcalled = 0;
387f3161b27SJose E. Roman   }
388f3161b27SJose E. Roman   PetscFunctionReturn(0);
389f3161b27SJose E. Roman }
390f3161b27SJose E. Roman 
3915de0dacdSJose E. Roman /*@
392f3161b27SJose E. Roman    PCPARMSSetLocal - Sets the local preconditioner to be used in PARMS.
393f3161b27SJose E. Roman 
394f3161b27SJose E. Roman    Collective on PC
395f3161b27SJose E. Roman 
396f3161b27SJose E. Roman    Input Parameters:
397f3161b27SJose E. Roman +  pc - the preconditioner context
398f3161b27SJose E. Roman -  type - the local preconditioner type, one of
399f3161b27SJose E. Roman .vb
400f3161b27SJose E. Roman      PC_PARMS_LOCAL_ILU0   - ILU0 preconditioner
401f3161b27SJose E. Roman      PC_PARMS_LOCAL_ILUK   - ILU(k) preconditioner
402f3161b27SJose E. Roman      PC_PARMS_LOCAL_ILUT   - ILUT preconditioner
403f3161b27SJose E. Roman      PC_PARMS_LOCAL_ARMS   - ARMS preconditioner
404f3161b27SJose E. Roman .ve
405f3161b27SJose E. Roman 
406f3161b27SJose E. Roman    Options Database Keys:
407f3161b27SJose E. Roman    -pc_parms_local [ilu0,iluk,ilut,arms] - Sets local preconditioner
408f3161b27SJose E. Roman 
409f3161b27SJose E. Roman    Level: intermediate
410f3161b27SJose E. Roman 
411f3161b27SJose E. Roman    Notes:
412f3161b27SJose E. Roman    For the ARMS preconditioner, one can use either the symmetric ARMS or the non-symmetric
413f3161b27SJose E. Roman    variant (ARMS-ddPQ) by setting the permutation type with PCPARMSSetNonsymPerm().
414f3161b27SJose E. Roman 
415f3161b27SJose E. Roman    See the pARMS function parms_PCILUSetType for more information.
416f3161b27SJose E. Roman 
417f3161b27SJose E. Roman .seealso: PCPARMS, PCPARMSSetGlobal(), PCPARMSSetNonsymPerm()
418f3161b27SJose E. Roman 
419f3161b27SJose E. Roman @*/
420f3161b27SJose E. Roman PetscErrorCode PCPARMSSetLocal(PC pc,PCPARMSLocalType type)
421f3161b27SJose E. Roman {
422f3161b27SJose E. Roman   PetscErrorCode ierr;
423f3161b27SJose E. Roman 
424f3161b27SJose E. Roman   PetscFunctionBegin;
425f3161b27SJose E. Roman   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
426f3161b27SJose E. Roman   PetscValidLogicalCollectiveEnum(pc,type,2);
427f3161b27SJose E. Roman   ierr = PetscTryMethod(pc,"PCPARMSSetLocal_C",(PC,PCPARMSLocalType),(pc,type));CHKERRQ(ierr);
428f3161b27SJose E. Roman   PetscFunctionReturn(0);
429f3161b27SJose E. Roman }
430f3161b27SJose E. Roman 
431f7a08781SBarry Smith static PetscErrorCode PCPARMSSetSolveTolerances_PARMS(PC pc,PetscReal tol,PetscInt maxits)
432f3161b27SJose E. Roman {
433f3161b27SJose E. Roman   PC_PARMS *parms = (PC_PARMS*)pc->data;
434f3161b27SJose E. Roman 
435f3161b27SJose E. Roman   PetscFunctionBegin;
436f3161b27SJose E. Roman   if (tol != parms->solvetol) {
437f3161b27SJose E. Roman     parms->solvetol = tol;
438f3161b27SJose E. Roman     pc->setupcalled = 0;
439f3161b27SJose E. Roman   }
440f3161b27SJose E. Roman   if (maxits != parms->maxits) {
441f3161b27SJose E. Roman     parms->maxits   = maxits;
442f3161b27SJose E. Roman     pc->setupcalled = 0;
443f3161b27SJose E. Roman   }
444f3161b27SJose E. Roman   PetscFunctionReturn(0);
445f3161b27SJose E. Roman }
446f3161b27SJose E. Roman 
4475de0dacdSJose E. Roman /*@
448f3161b27SJose E. Roman    PCPARMSSetSolveTolerances - Sets the convergence tolerance and the maximum iterations for the
449f3161b27SJose E. Roman    inner GMRES solver, when the Schur global preconditioner is used.
450f3161b27SJose E. Roman 
451f3161b27SJose E. Roman    Collective on PC
452f3161b27SJose E. Roman 
453f3161b27SJose E. Roman    Input Parameters:
454f3161b27SJose E. Roman +  pc - the preconditioner context
455f3161b27SJose E. Roman .  tol - the convergence tolerance
456f3161b27SJose E. Roman -  maxits - the maximum number of iterations to use
457f3161b27SJose E. Roman 
458f3161b27SJose E. Roman    Options Database Keys:
459f3161b27SJose E. Roman +  -pc_parms_solve_tol - set the tolerance for local solve
460f3161b27SJose E. Roman -  -pc_parms_max_it - set the maximum number of inner iterations
461f3161b27SJose E. Roman 
462f3161b27SJose E. Roman    Level: intermediate
463f3161b27SJose E. Roman 
464f3161b27SJose E. Roman    Notes:
465f3161b27SJose E. Roman    See the pARMS functions parms_PCSetInnerEps and parms_PCSetInnerMaxits for more information.
466f3161b27SJose E. Roman 
467f3161b27SJose E. Roman .seealso: PCPARMS, PCPARMSSetSolveRestart()
468f3161b27SJose E. Roman @*/
469f3161b27SJose E. Roman PetscErrorCode PCPARMSSetSolveTolerances(PC pc,PetscReal tol,PetscInt maxits)
470f3161b27SJose E. Roman {
471f3161b27SJose E. Roman   PetscErrorCode ierr;
472f3161b27SJose E. Roman 
473f3161b27SJose E. Roman   PetscFunctionBegin;
474f3161b27SJose E. Roman   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
475f3161b27SJose E. Roman   ierr = PetscTryMethod(pc,"PCPARMSSetSolveTolerances_C",(PC,PetscReal,PetscInt),(pc,tol,maxits));CHKERRQ(ierr);
476f3161b27SJose E. Roman   PetscFunctionReturn(0);
477f3161b27SJose E. Roman }
478f3161b27SJose E. Roman 
479f7a08781SBarry Smith static PetscErrorCode PCPARMSSetSolveRestart_PARMS(PC pc,PetscInt restart)
480f3161b27SJose E. Roman {
481f3161b27SJose E. Roman   PC_PARMS *parms = (PC_PARMS*)pc->data;
482f3161b27SJose E. Roman 
483f3161b27SJose E. Roman   PetscFunctionBegin;
484f3161b27SJose E. Roman   if (restart != parms->maxdim) {
485f3161b27SJose E. Roman     parms->maxdim   = restart;
486f3161b27SJose E. Roman     pc->setupcalled = 0;
487f3161b27SJose E. Roman   }
488f3161b27SJose E. Roman   PetscFunctionReturn(0);
489f3161b27SJose E. Roman }
490f3161b27SJose E. Roman 
4915de0dacdSJose E. Roman /*@
492f3161b27SJose E. Roman    PCPARMSSetSolveRestart - Sets the number of iterations at which the
493f3161b27SJose E. Roman    inner GMRES solver restarts.
494f3161b27SJose E. Roman 
495f3161b27SJose E. Roman    Collective on PC
496f3161b27SJose E. Roman 
497f3161b27SJose E. Roman    Input Parameters:
498f3161b27SJose E. Roman +  pc - the preconditioner context
499f3161b27SJose E. Roman -  restart - maximum dimension of the Krylov subspace
500f3161b27SJose E. Roman 
501f3161b27SJose E. Roman    Options Database Keys:
502f3161b27SJose E. Roman .  -pc_parms_max_dim - sets the inner Krylov dimension
503f3161b27SJose E. Roman 
504f3161b27SJose E. Roman    Level: intermediate
505f3161b27SJose E. Roman 
506f3161b27SJose E. Roman    Notes:
507f3161b27SJose E. Roman    See the pARMS function parms_PCSetInnerKSize for more information.
508f3161b27SJose E. Roman 
509f3161b27SJose E. Roman .seealso: PCPARMS, PCPARMSSetSolveTolerances()
510f3161b27SJose E. Roman @*/
511f3161b27SJose E. Roman PetscErrorCode PCPARMSSetSolveRestart(PC pc,PetscInt restart)
512f3161b27SJose E. Roman {
513f3161b27SJose E. Roman   PetscErrorCode ierr;
514f3161b27SJose E. Roman 
515f3161b27SJose E. Roman   PetscFunctionBegin;
516f3161b27SJose E. Roman   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
517f3161b27SJose E. Roman   ierr = PetscTryMethod(pc,"PCPARMSSetSolveRestart_C",(PC,PetscInt),(pc,restart));CHKERRQ(ierr);
518f3161b27SJose E. Roman   PetscFunctionReturn(0);
519f3161b27SJose E. Roman }
520f3161b27SJose E. Roman 
521f7a08781SBarry Smith static PetscErrorCode PCPARMSSetNonsymPerm_PARMS(PC pc,PetscBool nonsym)
522f3161b27SJose E. Roman {
523f3161b27SJose E. Roman   PC_PARMS *parms = (PC_PARMS*)pc->data;
524f3161b27SJose E. Roman 
525f3161b27SJose E. Roman   PetscFunctionBegin;
5265de0dacdSJose E. Roman   if ((nonsym && !parms->nonsymperm) || (!nonsym && parms->nonsymperm)) {
527f3161b27SJose E. Roman     parms->nonsymperm = nonsym;
528f3161b27SJose E. Roman     pc->setupcalled   = 0;
529f3161b27SJose E. Roman   }
530f3161b27SJose E. Roman   PetscFunctionReturn(0);
531f3161b27SJose E. Roman }
532f3161b27SJose E. Roman 
5335de0dacdSJose E. Roman /*@
534f3161b27SJose E. Roman    PCPARMSSetNonsymPerm - Sets the type of permutation for the ARMS preconditioner: the standard
535f3161b27SJose E. Roman    symmetric ARMS or the non-symmetric ARMS (ARMS-ddPQ).
536f3161b27SJose E. Roman 
537f3161b27SJose E. Roman    Collective on PC
538f3161b27SJose E. Roman 
539f3161b27SJose E. Roman    Input Parameters:
540f3161b27SJose E. Roman +  pc - the preconditioner context
541f3161b27SJose E. Roman -  nonsym - PETSC_TRUE indicates the non-symmetric ARMS is used;
542f3161b27SJose E. Roman             PETSC_FALSE indicates the symmetric ARMS is used
543f3161b27SJose E. Roman 
544f3161b27SJose E. Roman    Options Database Keys:
545f3161b27SJose E. Roman .  -pc_parms_nonsymmetric_perm - sets the use of nonsymmetric permutation
546f3161b27SJose E. Roman 
547f3161b27SJose E. Roman    Level: intermediate
548f3161b27SJose E. Roman 
549f3161b27SJose E. Roman    Notes:
550f3161b27SJose E. Roman    See the pARMS function parms_PCSetPermType for more information.
551f3161b27SJose E. Roman 
552f3161b27SJose E. Roman .seealso: PCPARMS
553f3161b27SJose E. Roman @*/
554f3161b27SJose E. Roman PetscErrorCode PCPARMSSetNonsymPerm(PC pc,PetscBool nonsym)
555f3161b27SJose E. Roman {
556f3161b27SJose E. Roman   PetscErrorCode ierr;
557f3161b27SJose E. Roman 
558f3161b27SJose E. Roman   PetscFunctionBegin;
559f3161b27SJose E. Roman   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
560f3161b27SJose E. Roman   ierr = PetscTryMethod(pc,"PCPARMSSetNonsymPerm_C",(PC,PetscBool),(pc,nonsym));CHKERRQ(ierr);
561f3161b27SJose E. Roman   PetscFunctionReturn(0);
562f3161b27SJose E. Roman }
563f3161b27SJose E. Roman 
564f7a08781SBarry Smith static PetscErrorCode PCPARMSSetFill_PARMS(PC pc,PetscInt lfil0,PetscInt lfil1,PetscInt lfil2)
565f3161b27SJose E. Roman {
566f3161b27SJose E. Roman   PC_PARMS *parms = (PC_PARMS*)pc->data;
567f3161b27SJose E. Roman 
568f3161b27SJose E. Roman   PetscFunctionBegin;
569f3161b27SJose E. Roman   if (lfil0 != parms->lfil[0] || lfil0 != parms->lfil[1] || lfil0 != parms->lfil[2] || lfil0 != parms->lfil[3]) {
570f3161b27SJose E. Roman     parms->lfil[1]  = parms->lfil[2] = parms->lfil[3] = parms->lfil[0] = lfil0;
571f3161b27SJose E. Roman     pc->setupcalled = 0;
572f3161b27SJose E. Roman   }
573f3161b27SJose E. Roman   if (lfil1 != parms->lfil[4]) {
574f3161b27SJose E. Roman     parms->lfil[4]  = lfil1;
575f3161b27SJose E. Roman     pc->setupcalled = 0;
576f3161b27SJose E. Roman   }
577f3161b27SJose E. Roman   if (lfil2 != parms->lfil[5] || lfil2 != parms->lfil[6]) {
578f3161b27SJose E. Roman     parms->lfil[5]  = parms->lfil[6] = lfil2;
579f3161b27SJose E. Roman     pc->setupcalled = 0;
580f3161b27SJose E. Roman   }
581f3161b27SJose E. Roman   PetscFunctionReturn(0);
582f3161b27SJose E. Roman }
583f3161b27SJose E. Roman 
5845de0dacdSJose E. Roman /*@
585f3161b27SJose E. Roman    PCPARMSSetFill - Sets the fill-in parameters for ILUT, ILUK and ARMS preconditioners.
586f3161b27SJose E. Roman    Consider the original matrix A = [B F; E C] and the approximate version
587f3161b27SJose E. Roman    M = [LB 0; E/UB I]*[UB LB\F; 0 S].
588f3161b27SJose E. Roman 
589f3161b27SJose E. Roman    Collective on PC
590f3161b27SJose E. Roman 
591f3161b27SJose E. Roman    Input Parameters:
592f3161b27SJose E. Roman +  pc - the preconditioner context
593f3161b27SJose E. Roman .  fil0 - the level of fill-in kept in LB, UB, E/UB and LB\F
594f3161b27SJose E. Roman .  fil1 - the level of fill-in kept in S
595f3161b27SJose E. Roman -  fil2 - the level of fill-in kept in the L and U parts of the LU factorization of S
596f3161b27SJose E. Roman 
597f3161b27SJose E. Roman    Options Database Keys:
598f3161b27SJose E. Roman +  -pc_parms_lfil_ilu_arms - set the amount of fill-in for ilut, iluk and arms
599f3161b27SJose E. Roman .  -pc_parms_lfil_schur - set the amount of fill-in for schur
600f3161b27SJose E. Roman -  -pc_parms_lfil_ilut_L_U - set the amount of fill-in for ILUT L and U
601f3161b27SJose E. Roman 
602f3161b27SJose E. Roman    Level: intermediate
603f3161b27SJose E. Roman 
604f3161b27SJose E. Roman    Notes:
605f3161b27SJose E. Roman    See the pARMS function parms_PCSetFill for more information.
606f3161b27SJose E. Roman 
607f3161b27SJose E. Roman .seealso: PCPARMS
608f3161b27SJose E. Roman @*/
609f3161b27SJose E. Roman PetscErrorCode PCPARMSSetFill(PC pc,PetscInt lfil0,PetscInt lfil1,PetscInt lfil2)
610f3161b27SJose E. Roman {
611f3161b27SJose E. Roman   PetscErrorCode ierr;
612f3161b27SJose E. Roman 
613f3161b27SJose E. Roman   PetscFunctionBegin;
614f3161b27SJose E. Roman   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
615f3161b27SJose E. Roman   ierr = PetscTryMethod(pc,"PCPARMSSetFill_C",(PC,PetscInt,PetscInt,PetscInt),(pc,lfil0,lfil1,lfil2));CHKERRQ(ierr);
616f3161b27SJose E. Roman   PetscFunctionReturn(0);
617f3161b27SJose E. Roman }
618f3161b27SJose E. Roman 
619f3161b27SJose E. Roman /*MC
620f3161b27SJose E. Roman    PCPARMS - Allows the use of the parallel Algebraic Recursive Multilevel Solvers
621f3161b27SJose E. Roman       available in the package pARMS
622f3161b27SJose E. Roman 
623f3161b27SJose E. Roman    Options Database Keys:
624f3161b27SJose E. Roman +  -pc_parms_global - one of ras, schur, bj
625f3161b27SJose E. Roman .  -pc_parms_local - one of ilu0, iluk, ilut, arms
626f3161b27SJose E. Roman .  -pc_parms_solve_tol - set the tolerance for local solve
627f3161b27SJose E. Roman .  -pc_parms_levels - set the number of levels
628f3161b27SJose E. Roman .  -pc_parms_nonsymmetric_perm - set the use of nonsymmetric permutation
629f3161b27SJose E. Roman .  -pc_parms_blocksize - set the block size
630f3161b27SJose E. Roman .  -pc_parms_ind_tol - set the tolerance for independent sets
631f3161b27SJose E. Roman .  -pc_parms_max_dim - set the inner krylov dimension
632f3161b27SJose E. Roman .  -pc_parms_max_it - set the maximum number of inner iterations
6334b62eef3SJose E. Roman .  -pc_parms_inter_nonsymmetric_perm - set the use of nonsymmetric permutation for interlevel blocks
634f3161b27SJose E. Roman .  -pc_parms_inter_column_perm - set the use of column permutation for interlevel blocks
635f3161b27SJose E. Roman .  -pc_parms_inter_row_scaling - set the use of row scaling for interlevel blocks
636f3161b27SJose E. Roman .  -pc_parms_inter_column_scaling - set the use of column scaling for interlevel blocks
6374b62eef3SJose E. Roman .  -pc_parms_last_nonsymmetric_perm - set the use of nonsymmetric permutation for last level blocks
638f3161b27SJose E. Roman .  -pc_parms_last_column_perm - set the use of column permutation for last level blocks
639f3161b27SJose E. Roman .  -pc_parms_last_row_scaling - set the use of row scaling for last level blocks
640f3161b27SJose E. Roman .  -pc_parms_last_column_scaling - set the use of column scaling for last level blocks
641f3161b27SJose E. Roman .  -pc_parms_lfil_ilu_arms - set the amount of fill-in for ilut, iluk and arms
642f3161b27SJose E. Roman .  -pc_parms_lfil_schur - set the amount of fill-in for schur
643f3161b27SJose E. Roman .  -pc_parms_lfil_ilut_L_U - set the amount of fill-in for ILUT L and U
644f3161b27SJose E. Roman .  -pc_parms_droptol_factors - set the drop tolerance for L, U, L^{-1}F and EU^{-1}
645f3161b27SJose E. Roman .  -pc_parms_droptol_schur_compl - set the drop tolerance for schur complement at each level
646f3161b27SJose E. Roman -  -pc_parms_droptol_last_schur - set the drop tolerance for ILUT in last level schur complement
647f3161b27SJose E. Roman 
648f3161b27SJose E. Roman    IMPORTANT:
649f3161b27SJose E. Roman    Unless configured appropriately, this preconditioner performs an inexact solve
650f3161b27SJose E. Roman    as part of the preconditioner application. Therefore, it must be used in combination
651*f6a5184aSRichard Tran Mills    with flexible variants of iterative solvers, such as KSPFGMRES or KSPGCR.
652f3161b27SJose E. Roman 
653f3161b27SJose E. Roman    Level: intermediate
654f3161b27SJose E. Roman 
655f3161b27SJose E. Roman .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC
656f3161b27SJose E. Roman M*/
657f3161b27SJose E. Roman 
6588cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PARMS(PC pc)
659f3161b27SJose E. Roman {
660f3161b27SJose E. Roman   PC_PARMS       *parms;
661f3161b27SJose E. Roman   PetscErrorCode ierr;
662f3161b27SJose E. Roman 
663f3161b27SJose E. Roman   PetscFunctionBegin;
664b00a9115SJed Brown   ierr = PetscNewLog(pc,&parms);CHKERRQ(ierr);
6652fa5cd67SKarl Rupp 
666f3161b27SJose E. Roman   parms->map        = 0;
667f3161b27SJose E. Roman   parms->A          = 0;
668f3161b27SJose E. Roman   parms->pc         = 0;
669abd6c125SJose E. Roman   parms->global     = PC_PARMS_GLOBAL_RAS;
670f3161b27SJose E. Roman   parms->local      = PC_PARMS_LOCAL_ARMS;
671f3161b27SJose E. Roman   parms->levels     = 10;
672f3161b27SJose E. Roman   parms->nonsymperm = PETSC_TRUE;
673f3161b27SJose E. Roman   parms->blocksize  = 250;
674abd6c125SJose E. Roman   parms->maxdim     = 0;
675abd6c125SJose E. Roman   parms->maxits     = 0;
6764b62eef3SJose E. Roman   parms->meth[0]    = PETSC_FALSE;
6774b62eef3SJose E. Roman   parms->meth[1]    = PETSC_FALSE;
6784b62eef3SJose E. Roman   parms->meth[2]    = PETSC_FALSE;
6794b62eef3SJose E. Roman   parms->meth[3]    = PETSC_FALSE;
6804b62eef3SJose E. Roman   parms->meth[4]    = PETSC_FALSE;
6814b62eef3SJose E. Roman   parms->meth[5]    = PETSC_FALSE;
6824b62eef3SJose E. Roman   parms->meth[6]    = PETSC_FALSE;
6834b62eef3SJose E. Roman   parms->meth[7]    = PETSC_FALSE;
684f3161b27SJose E. Roman   parms->solvetol   = 0.01;
685f3161b27SJose E. Roman   parms->indtol     = 0.4;
686f3161b27SJose E. Roman   parms->lfil[0]    = parms->lfil[1] = parms->lfil[2] = parms->lfil[3] = 20;
687f3161b27SJose E. Roman   parms->lfil[4]    = parms->lfil[5] = parms->lfil[6] = 20;
688f3161b27SJose E. Roman   parms->droptol[0] = parms->droptol[1] = parms->droptol[2] = parms->droptol[3] = 0.00001;
689f3161b27SJose E. Roman   parms->droptol[4] = 0.001;
690f3161b27SJose E. Roman   parms->droptol[5] = parms->droptol[6] = 0.001;
6912fa5cd67SKarl Rupp 
692f3161b27SJose E. Roman   pc->data                = parms;
693f3161b27SJose E. Roman   pc->ops->destroy        = PCDestroy_PARMS;
694f3161b27SJose E. Roman   pc->ops->setfromoptions = PCSetFromOptions_PARMS;
695f3161b27SJose E. Roman   pc->ops->setup          = PCSetUp_PARMS;
696f3161b27SJose E. Roman   pc->ops->apply          = PCApply_PARMS;
697f3161b27SJose E. Roman   pc->ops->view           = PCView_PARMS;
6982fa5cd67SKarl Rupp 
699bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetGlobal_C",PCPARMSSetGlobal_PARMS);CHKERRQ(ierr);
700bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetLocal_C",PCPARMSSetLocal_PARMS);CHKERRQ(ierr);
701bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetSolveTolerances_C",PCPARMSSetSolveTolerances_PARMS);CHKERRQ(ierr);
702bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetSolveRestart_C",PCPARMSSetSolveRestart_PARMS);CHKERRQ(ierr);
703bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetNonsymPerm_C",PCPARMSSetNonsymPerm_PARMS);CHKERRQ(ierr);
704bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetFill_C",PCPARMSSetFill_PARMS);CHKERRQ(ierr);
705f3161b27SJose E. Roman   PetscFunctionReturn(0);
706f3161b27SJose E. Roman }
707