Actual source code: parms.c
1: #define PETSCKSP_DLL
3: /*
4: Provides an interface to pARMS.
5: Requires pARMS 3.2 or later.
6: */
8: #include <petsc/private/pcimpl.h>
10: #if defined(PETSC_USE_COMPLEX)
11: #define DBL_CMPLX
12: #else
13: #define DBL
14: #endif
15: #define USE_MPI
16: #define REAL double
17: #define HAS_BLAS
18: #define FORTRAN_UNDERSCORE
19: #include "parms_sys.h"
20: #undef FLOAT
21: #define FLOAT PetscScalar
22: #include <parms.h>
24: /*
25: Private context (data structure) for the preconditioner.
26: */
27: typedef struct {
28: parms_Map map;
29: parms_Mat A;
30: parms_PC pc;
31: PCPARMSGlobalType global;
32: PCPARMSLocalType local;
33: PetscInt levels, blocksize, maxdim, maxits, lfil[7];
34: PetscBool nonsymperm, meth[8];
35: PetscReal solvetol, indtol, droptol[7];
36: PetscScalar *lvec0, *lvec1;
37: } PC_PARMS;
39: static PetscErrorCode PCSetUp_PARMS(PC pc)
40: {
41: Mat pmat;
42: PC_PARMS *parms = (PC_PARMS *)pc->data;
43: const PetscInt *mapptr0;
44: PetscInt n, lsize, low, high, i, pos, ncols, length;
45: int *maptmp, *mapptr, *ia, *ja, *ja1, *im;
46: PetscScalar *aa, *aa1;
47: const PetscInt *cols;
48: PetscInt meth[8];
49: const PetscScalar *values;
50: MatInfo matinfo;
51: PetscMPIInt rank, npro;
53: /* Get preconditioner matrix from PETSc and setup pARMS structs */
54: PCGetOperators(pc, NULL, &pmat);
55: MPI_Comm_size(PetscObjectComm((PetscObject)pmat), &npro);
56: MPI_Comm_rank(PetscObjectComm((PetscObject)pmat), &rank);
58: MatGetSize(pmat, &n, NULL);
59: PetscMalloc1(npro + 1, &mapptr);
60: PetscMalloc1(n, &maptmp);
61: MatGetOwnershipRanges(pmat, &mapptr0);
62: low = mapptr0[rank];
63: high = mapptr0[rank + 1];
64: lsize = high - low;
66: for (i = 0; i < npro + 1; i++) mapptr[i] = mapptr0[i] + 1;
67: for (i = 0; i < n; i++) maptmp[i] = i + 1;
69: /* if created, destroy the previous map */
70: if (parms->map) {
71: parms_MapFree(&parms->map);
72: parms->map = NULL;
73: }
75: /* create pARMS map object */
76: parms_MapCreateFromPtr(&parms->map, (int)n, maptmp, mapptr, PetscObjectComm((PetscObject)pmat), 1, NONINTERLACED);
78: /* if created, destroy the previous pARMS matrix */
79: if (parms->A) {
80: parms_MatFree(&parms->A);
81: parms->A = NULL;
82: }
84: /* create pARMS mat object */
85: parms_MatCreate(&parms->A, parms->map);
87: /* setup and copy csr data structure for pARMS */
88: PetscMalloc1(lsize + 1, &ia);
89: ia[0] = 1;
90: MatGetInfo(pmat, MAT_LOCAL, &matinfo);
91: length = matinfo.nz_used;
92: PetscMalloc1(length, &ja);
93: PetscMalloc1(length, &aa);
95: for (i = low; i < high; i++) {
96: pos = ia[i - low] - 1;
97: MatGetRow(pmat, i, &ncols, &cols, &values);
98: ia[i - low + 1] = ia[i - low] + ncols;
100: if (ia[i - low + 1] >= length) {
101: length += ncols;
102: PetscMalloc1(length, &ja1);
103: PetscArraycpy(ja1, ja, ia[i - low] - 1);
104: PetscFree(ja);
105: ja = ja1;
106: PetscMalloc1(length, &aa1);
107: PetscArraycpy(aa1, aa, ia[i - low] - 1);
108: PetscFree(aa);
109: aa = aa1;
110: }
111: PetscArraycpy(&ja[pos], cols, ncols);
112: PetscArraycpy(&aa[pos], values, ncols);
113: MatRestoreRow(pmat, i, &ncols, &cols, &values);
114: }
116: /* csr info is for local matrix so initialize im[] locally */
117: PetscMalloc1(lsize, &im);
118: PetscArraycpy(im, &maptmp[mapptr[rank] - 1], lsize);
120: /* 1-based indexing */
121: for (i = 0; i < ia[lsize] - 1; i++) ja[i] = ja[i] + 1;
123: /* Now copy csr matrix to parms_mat object */
124: parms_MatSetValues(parms->A, (int)lsize, im, ia, ja, aa, INSERT);
126: /* free memory */
127: PetscFree(maptmp);
128: PetscFree(mapptr);
129: PetscFree(aa);
130: PetscFree(ja);
131: PetscFree(ia);
132: PetscFree(im);
134: /* setup parms matrix */
135: parms_MatSetup(parms->A);
137: /* if created, destroy the previous pARMS pc */
138: if (parms->pc) {
139: parms_PCFree(&parms->pc);
140: parms->pc = NULL;
141: }
143: /* Now create pARMS preconditioner object based on A */
144: parms_PCCreate(&parms->pc, parms->A);
146: /* Transfer options from PC to pARMS */
147: switch (parms->global) {
148: case 0:
149: parms_PCSetType(parms->pc, PCRAS);
150: break;
151: case 1:
152: parms_PCSetType(parms->pc, PCSCHUR);
153: break;
154: case 2:
155: parms_PCSetType(parms->pc, PCBJ);
156: break;
157: }
158: switch (parms->local) {
159: case 0:
160: parms_PCSetILUType(parms->pc, PCILU0);
161: break;
162: case 1:
163: parms_PCSetILUType(parms->pc, PCILUK);
164: break;
165: case 2:
166: parms_PCSetILUType(parms->pc, PCILUT);
167: break;
168: case 3:
169: parms_PCSetILUType(parms->pc, PCARMS);
170: break;
171: }
172: parms_PCSetInnerEps(parms->pc, parms->solvetol);
173: parms_PCSetNlevels(parms->pc, parms->levels);
174: parms_PCSetPermType(parms->pc, parms->nonsymperm ? 1 : 0);
175: parms_PCSetBsize(parms->pc, parms->blocksize);
176: parms_PCSetTolInd(parms->pc, parms->indtol);
177: parms_PCSetInnerKSize(parms->pc, parms->maxdim);
178: parms_PCSetInnerMaxits(parms->pc, parms->maxits);
179: for (i = 0; i < 8; i++) meth[i] = parms->meth[i] ? 1 : 0;
180: parms_PCSetPermScalOptions(parms->pc, &meth[0], 1);
181: parms_PCSetPermScalOptions(parms->pc, &meth[4], 0);
182: parms_PCSetFill(parms->pc, parms->lfil);
183: parms_PCSetTol(parms->pc, parms->droptol);
185: parms_PCSetup(parms->pc);
187: /* Allocate two auxiliary vector of length lsize */
188: if (parms->lvec0) PetscFree(parms->lvec0);
189: PetscMalloc1(lsize, &parms->lvec0);
190: if (parms->lvec1) PetscFree(parms->lvec1);
191: PetscMalloc1(lsize, &parms->lvec1);
192: return 0;
193: }
195: static PetscErrorCode PCView_PARMS(PC pc, PetscViewer viewer)
196: {
197: PetscBool iascii;
198: PC_PARMS *parms = (PC_PARMS *)pc->data;
199: char *str;
200: double fill_fact;
202: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);
203: if (iascii) {
204: parms_PCGetName(parms->pc, &str);
205: PetscViewerASCIIPrintf(viewer, " global preconditioner: %s\n", str);
206: parms_PCILUGetName(parms->pc, &str);
207: PetscViewerASCIIPrintf(viewer, " local preconditioner: %s\n", str);
208: parms_PCGetRatio(parms->pc, &fill_fact);
209: PetscViewerASCIIPrintf(viewer, " non-zero elements/original non-zero entries: %-4.2f\n", fill_fact);
210: PetscViewerASCIIPrintf(viewer, " Tolerance for local solve: %g\n", parms->solvetol);
211: PetscViewerASCIIPrintf(viewer, " Number of levels: %d\n", parms->levels);
212: if (parms->nonsymperm) PetscViewerASCIIPrintf(viewer, " Using nonsymmetric permutation\n");
213: PetscViewerASCIIPrintf(viewer, " Block size: %d\n", parms->blocksize);
214: PetscViewerASCIIPrintf(viewer, " Tolerance for independent sets: %g\n", parms->indtol);
215: PetscViewerASCIIPrintf(viewer, " Inner Krylov dimension: %d\n", parms->maxdim);
216: PetscViewerASCIIPrintf(viewer, " Maximum number of inner iterations: %d\n", parms->maxits);
217: if (parms->meth[0]) PetscViewerASCIIPrintf(viewer, " Using nonsymmetric permutation for interlevel blocks\n");
218: if (parms->meth[1]) PetscViewerASCIIPrintf(viewer, " Using column permutation for interlevel blocks\n");
219: if (parms->meth[2]) PetscViewerASCIIPrintf(viewer, " Using row scaling for interlevel blocks\n");
220: if (parms->meth[3]) PetscViewerASCIIPrintf(viewer, " Using column scaling for interlevel blocks\n");
221: if (parms->meth[4]) PetscViewerASCIIPrintf(viewer, " Using nonsymmetric permutation for last level blocks\n");
222: if (parms->meth[5]) PetscViewerASCIIPrintf(viewer, " Using column permutation for last level blocks\n");
223: if (parms->meth[6]) PetscViewerASCIIPrintf(viewer, " Using row scaling for last level blocks\n");
224: if (parms->meth[7]) PetscViewerASCIIPrintf(viewer, " Using column scaling for last level blocks\n");
225: PetscViewerASCIIPrintf(viewer, " amount of fill-in for ilut, iluk and arms: %d\n", parms->lfil[0]);
226: PetscViewerASCIIPrintf(viewer, " amount of fill-in for schur: %d\n", parms->lfil[4]);
227: PetscViewerASCIIPrintf(viewer, " amount of fill-in for ILUT L and U: %d\n", parms->lfil[5]);
228: PetscViewerASCIIPrintf(viewer, " drop tolerance for L, U, L^{-1}F and EU^{-1}: %g\n", parms->droptol[0]);
229: PetscViewerASCIIPrintf(viewer, " drop tolerance for schur complement at each level: %g\n", parms->droptol[4]);
230: PetscViewerASCIIPrintf(viewer, " drop tolerance for ILUT in last level schur complement: %g\n", parms->droptol[5]);
231: }
232: return 0;
233: }
235: static PetscErrorCode PCDestroy_PARMS(PC pc)
236: {
237: PC_PARMS *parms = (PC_PARMS *)pc->data;
239: if (parms->map) parms_MapFree(&parms->map);
240: if (parms->A) parms_MatFree(&parms->A);
241: if (parms->pc) parms_PCFree(&parms->pc);
242: if (parms->lvec0) PetscFree(parms->lvec0);
243: if (parms->lvec1) PetscFree(parms->lvec1);
244: PetscFree(pc->data);
246: PetscObjectChangeTypeName((PetscObject)pc, 0);
247: PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetGlobal_C", NULL);
248: PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetLocal_C", NULL);
249: PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetSolveTolerances_C", NULL);
250: PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetSolveRestart_C", NULL);
251: PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetNonsymPerm_C", NULL);
252: PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetFill_C", NULL);
253: return 0;
254: }
256: static PetscErrorCode PCSetFromOptions_PARMS(PC pc, PetscOptionItems *PetscOptionsObject)
257: {
258: PC_PARMS *parms = (PC_PARMS *)pc->data;
259: PetscBool flag;
260: PCPARMSGlobalType global;
261: PCPARMSLocalType local;
263: PetscOptionsHeadBegin(PetscOptionsObject, "PARMS Options");
264: PetscOptionsEnum("-pc_parms_global", "Global preconditioner", "PCPARMSSetGlobal", PCPARMSGlobalTypes, (PetscEnum)parms->global, (PetscEnum *)&global, &flag);
265: if (flag) PCPARMSSetGlobal(pc, global);
266: PetscOptionsEnum("-pc_parms_local", "Local preconditioner", "PCPARMSSetLocal", PCPARMSLocalTypes, (PetscEnum)parms->local, (PetscEnum *)&local, &flag);
267: if (flag) PCPARMSSetLocal(pc, local);
268: PetscOptionsReal("-pc_parms_solve_tol", "Tolerance for local solve", "PCPARMSSetSolveTolerances", parms->solvetol, &parms->solvetol, NULL);
269: PetscOptionsInt("-pc_parms_levels", "Number of levels", "None", parms->levels, &parms->levels, NULL);
270: PetscOptionsBool("-pc_parms_nonsymmetric_perm", "Use nonsymmetric permutation", "PCPARMSSetNonsymPerm", parms->nonsymperm, &parms->nonsymperm, NULL);
271: PetscOptionsInt("-pc_parms_blocksize", "Block size", "None", parms->blocksize, &parms->blocksize, NULL);
272: PetscOptionsReal("-pc_parms_ind_tol", "Tolerance for independent sets", "None", parms->indtol, &parms->indtol, NULL);
273: PetscOptionsInt("-pc_parms_max_dim", "Inner Krylov dimension", "PCPARMSSetSolveRestart", parms->maxdim, &parms->maxdim, NULL);
274: PetscOptionsInt("-pc_parms_max_it", "Maximum number of inner iterations", "PCPARMSSetSolveTolerances", parms->maxits, &parms->maxits, NULL);
275: PetscOptionsBool("-pc_parms_inter_nonsymmetric_perm", "nonsymmetric permutation for interlevel blocks", "None", parms->meth[0], &parms->meth[0], NULL);
276: PetscOptionsBool("-pc_parms_inter_column_perm", "column permutation for interlevel blocks", "None", parms->meth[1], &parms->meth[1], NULL);
277: PetscOptionsBool("-pc_parms_inter_row_scaling", "row scaling for interlevel blocks", "None", parms->meth[2], &parms->meth[2], NULL);
278: PetscOptionsBool("-pc_parms_inter_column_scaling", "column scaling for interlevel blocks", "None", parms->meth[3], &parms->meth[3], NULL);
279: PetscOptionsBool("-pc_parms_last_nonsymmetric_perm", "nonsymmetric permutation for last level blocks", "None", parms->meth[4], &parms->meth[4], NULL);
280: PetscOptionsBool("-pc_parms_last_column_perm", "column permutation for last level blocks", "None", parms->meth[5], &parms->meth[5], NULL);
281: PetscOptionsBool("-pc_parms_last_row_scaling", "row scaling for last level blocks", "None", parms->meth[6], &parms->meth[6], NULL);
282: PetscOptionsBool("-pc_parms_last_column_scaling", "column scaling for last level blocks", "None", parms->meth[7], &parms->meth[7], NULL);
283: PetscOptionsInt("-pc_parms_lfil_ilu_arms", "amount of fill-in for ilut, iluk and arms", "PCPARMSSetFill", parms->lfil[0], &parms->lfil[0], &flag);
284: if (flag) parms->lfil[1] = parms->lfil[2] = parms->lfil[3] = parms->lfil[0];
285: PetscOptionsInt("-pc_parms_lfil_schur", "amount of fill-in for schur", "PCPARMSSetFill", parms->lfil[4], &parms->lfil[4], NULL);
286: PetscOptionsInt("-pc_parms_lfil_ilut_L_U", "amount of fill-in for ILUT L and U", "PCPARMSSetFill", parms->lfil[5], &parms->lfil[5], &flag);
287: if (flag) parms->lfil[6] = parms->lfil[5];
288: PetscOptionsReal("-pc_parms_droptol_factors", "drop tolerance for L, U, L^{-1}F and EU^{-1}", "None", parms->droptol[0], &parms->droptol[0], NULL);
289: PetscOptionsReal("-pc_parms_droptol_schur_compl", "drop tolerance for schur complement at each level", "None", parms->droptol[4], &parms->droptol[4], &flag);
290: if (flag) parms->droptol[1] = parms->droptol[2] = parms->droptol[3] = parms->droptol[0];
291: PetscOptionsReal("-pc_parms_droptol_last_schur", "drop tolerance for ILUT in last level schur complement", "None", parms->droptol[5], &parms->droptol[5], &flag);
292: if (flag) parms->droptol[6] = parms->droptol[5];
293: PetscOptionsHeadEnd();
294: return 0;
295: }
297: static PetscErrorCode PCApply_PARMS(PC pc, Vec b, Vec x)
298: {
299: PC_PARMS *parms = (PC_PARMS *)pc->data;
300: const PetscScalar *b1;
301: PetscScalar *x1;
303: VecGetArrayRead(b, &b1);
304: VecGetArray(x, &x1);
305: parms_VecPermAux((PetscScalar *)b1, parms->lvec0, parms->map);
306: parms_PCApply(parms->pc, parms->lvec0, parms->lvec1);
307: parms_VecInvPermAux(parms->lvec1, x1, parms->map);
308: VecRestoreArrayRead(b, &b1);
309: VecRestoreArray(x, &x1);
310: return 0;
311: }
313: static PetscErrorCode PCPARMSSetGlobal_PARMS(PC pc, PCPARMSGlobalType type)
314: {
315: PC_PARMS *parms = (PC_PARMS *)pc->data;
317: if (type != parms->global) {
318: parms->global = type;
319: pc->setupcalled = 0;
320: }
321: return 0;
322: }
324: /*@
325: PCPARMSSetGlobal - Sets the global preconditioner to be used in `PCPARMS`.
327: Collective
329: Input Parameters:
330: + pc - the preconditioner context
331: - type - the global preconditioner type, one of
332: .vb
333: PC_PARMS_GLOBAL_RAS - Restricted additive Schwarz
334: PC_PARMS_GLOBAL_SCHUR - Schur complement
335: PC_PARMS_GLOBAL_BJ - Block Jacobi
336: .ve
338: Options Database Key:
339: . -pc_parms_global [ras,schur,bj] - Sets global preconditioner
341: Level: intermediate
343: Note:
344: See the pARMS function `parms_PCSetType()` for more information.
346: .seealso: `PCPARMS`, `PCPARMSSetLocal()`
347: @*/
348: PetscErrorCode PCPARMSSetGlobal(PC pc, PCPARMSGlobalType type)
349: {
352: PetscTryMethod(pc, "PCPARMSSetGlobal_C", (PC, PCPARMSGlobalType), (pc, type));
353: return 0;
354: }
356: static PetscErrorCode PCPARMSSetLocal_PARMS(PC pc, PCPARMSLocalType type)
357: {
358: PC_PARMS *parms = (PC_PARMS *)pc->data;
360: if (type != parms->local) {
361: parms->local = type;
362: pc->setupcalled = 0;
363: }
364: return 0;
365: }
367: /*@
368: PCPARMSSetLocal - Sets the local preconditioner to be used in `PCPARMS`.
370: Collective
372: Input Parameters:
373: + pc - the preconditioner context
374: - type - the local preconditioner type, one of
375: .vb
376: PC_PARMS_LOCAL_ILU0 - ILU0 preconditioner
377: PC_PARMS_LOCAL_ILUK - ILU(k) preconditioner
378: PC_PARMS_LOCAL_ILUT - ILUT preconditioner
379: PC_PARMS_LOCAL_ARMS - ARMS preconditioner
380: .ve
382: Options Database Keys:
383: -pc_parms_local [ilu0,iluk,ilut,arms] - Sets local preconditioner
385: Level: intermediate
387: Notes:
388: For the ARMS preconditioner, one can use either the symmetric ARMS or the non-symmetric
389: variant (ARMS-ddPQ) by setting the permutation type with PCPARMSSetNonsymPerm().
391: See the pARMS function `parms_PCILUSetType()` for more information.
393: .seealso: `PCPARMS`, `PCPARMSSetGlobal()`, `PCPARMSSetNonsymPerm()`
395: @*/
396: PetscErrorCode PCPARMSSetLocal(PC pc, PCPARMSLocalType type)
397: {
400: PetscTryMethod(pc, "PCPARMSSetLocal_C", (PC, PCPARMSLocalType), (pc, type));
401: return 0;
402: }
404: static PetscErrorCode PCPARMSSetSolveTolerances_PARMS(PC pc, PetscReal tol, PetscInt maxits)
405: {
406: PC_PARMS *parms = (PC_PARMS *)pc->data;
408: if (tol != parms->solvetol) {
409: parms->solvetol = tol;
410: pc->setupcalled = 0;
411: }
412: if (maxits != parms->maxits) {
413: parms->maxits = maxits;
414: pc->setupcalled = 0;
415: }
416: return 0;
417: }
419: /*@
420: PCPARMSSetSolveTolerances - Sets the convergence tolerance and the maximum iterations for the
421: inner GMRES solver, when the Schur global preconditioner is used.
423: Collective
425: Input Parameters:
426: + pc - the preconditioner context
427: . tol - the convergence tolerance
428: - maxits - the maximum number of iterations to use
430: Options Database Keys:
431: + -pc_parms_solve_tol - set the tolerance for local solve
432: - -pc_parms_max_it - set the maximum number of inner iterations
434: Level: intermediate
436: Note:
437: See the pARMS functions `parms_PCSetInnerEps()` and `parms_PCSetInnerMaxits()` for more information.
439: .seealso: `PCPARMS`, `PCPARMSSetSolveRestart()`
440: @*/
441: PetscErrorCode PCPARMSSetSolveTolerances(PC pc, PetscReal tol, PetscInt maxits)
442: {
444: PetscTryMethod(pc, "PCPARMSSetSolveTolerances_C", (PC, PetscReal, PetscInt), (pc, tol, maxits));
445: return 0;
446: }
448: static PetscErrorCode PCPARMSSetSolveRestart_PARMS(PC pc, PetscInt restart)
449: {
450: PC_PARMS *parms = (PC_PARMS *)pc->data;
452: if (restart != parms->maxdim) {
453: parms->maxdim = restart;
454: pc->setupcalled = 0;
455: }
456: return 0;
457: }
459: /*@
460: PCPARMSSetSolveRestart - Sets the number of iterations at which the
461: inner GMRES solver restarts.
463: Collective
465: Input Parameters:
466: + pc - the preconditioner context
467: - restart - maximum dimension of the Krylov subspace
469: Options Database Key:
470: . -pc_parms_max_dim - sets the inner Krylov dimension
472: Level: intermediate
474: Note:
475: See the pARMS function parms_PCSetInnerKSize for more information.
477: .seealso: `PCPARMS`, `PCPARMSSetSolveTolerances()`
478: @*/
479: PetscErrorCode PCPARMSSetSolveRestart(PC pc, PetscInt restart)
480: {
482: PetscTryMethod(pc, "PCPARMSSetSolveRestart_C", (PC, PetscInt), (pc, restart));
483: return 0;
484: }
486: static PetscErrorCode PCPARMSSetNonsymPerm_PARMS(PC pc, PetscBool nonsym)
487: {
488: PC_PARMS *parms = (PC_PARMS *)pc->data;
490: if ((nonsym && !parms->nonsymperm) || (!nonsym && parms->nonsymperm)) {
491: parms->nonsymperm = nonsym;
492: pc->setupcalled = 0;
493: }
494: return 0;
495: }
497: /*@
498: PCPARMSSetNonsymPerm - Sets the type of permutation for the ARMS preconditioner: the standard
499: symmetric ARMS or the non-symmetric ARMS (ARMS-ddPQ).
501: Collective
503: Input Parameters:
504: + pc - the preconditioner context
505: - nonsym - `PETSC_TRUE` indicates the non-symmetric ARMS is used;
506: `PETSC_FALSE` indicates the symmetric ARMS is used
508: Options Database Key:
509: . -pc_parms_nonsymmetric_perm - sets the use of nonsymmetric permutation
511: Level: intermediate
513: Note:
514: See the pARMS function `parms_PCSetPermType()` for more information.
516: .seealso: `PCPARMS`
517: @*/
518: PetscErrorCode PCPARMSSetNonsymPerm(PC pc, PetscBool nonsym)
519: {
521: PetscTryMethod(pc, "PCPARMSSetNonsymPerm_C", (PC, PetscBool), (pc, nonsym));
522: return 0;
523: }
525: static PetscErrorCode PCPARMSSetFill_PARMS(PC pc, PetscInt lfil0, PetscInt lfil1, PetscInt lfil2)
526: {
527: PC_PARMS *parms = (PC_PARMS *)pc->data;
529: if (lfil0 != parms->lfil[0] || lfil0 != parms->lfil[1] || lfil0 != parms->lfil[2] || lfil0 != parms->lfil[3]) {
530: parms->lfil[1] = parms->lfil[2] = parms->lfil[3] = parms->lfil[0] = lfil0;
531: pc->setupcalled = 0;
532: }
533: if (lfil1 != parms->lfil[4]) {
534: parms->lfil[4] = lfil1;
535: pc->setupcalled = 0;
536: }
537: if (lfil2 != parms->lfil[5] || lfil2 != parms->lfil[6]) {
538: parms->lfil[5] = parms->lfil[6] = lfil2;
539: pc->setupcalled = 0;
540: }
541: return 0;
542: }
544: /*@
545: PCPARMSSetFill - Sets the fill-in parameters for ILUT, ILUK and ARMS preconditioners.
546: Consider the original matrix A = [B F; E C] and the approximate version
547: M = [LB 0; E/UB I]*[UB LB\F; 0 S].
549: Collective
551: Input Parameters:
552: + pc - the preconditioner context
553: . fil0 - the level of fill-in kept in LB, UB, E/UB and LB\F
554: . fil1 - the level of fill-in kept in S
555: - fil2 - the level of fill-in kept in the L and U parts of the LU factorization of S
557: Options Database Keys:
558: + -pc_parms_lfil_ilu_arms - set the amount of fill-in for ilut, iluk and arms
559: . -pc_parms_lfil_schur - set the amount of fill-in for schur
560: - -pc_parms_lfil_ilut_L_U - set the amount of fill-in for ILUT L and U
562: Level: intermediate
564: Note:
565: See the pARMS function `parms_PCSetFill()` for more information.
567: .seealso: `PCPARMS`
568: @*/
569: PetscErrorCode PCPARMSSetFill(PC pc, PetscInt lfil0, PetscInt lfil1, PetscInt lfil2)
570: {
572: PetscTryMethod(pc, "PCPARMSSetFill_C", (PC, PetscInt, PetscInt, PetscInt), (pc, lfil0, lfil1, lfil2));
573: return 0;
574: }
576: /*MC
577: PCPARMS - Allows the use of the parallel Algebraic Recursive Multilevel Solvers
578: available in the package pARMS
580: Options Database Keys:
581: + -pc_parms_global - one of ras, schur, bj
582: . -pc_parms_local - one of ilu0, iluk, ilut, arms
583: . -pc_parms_solve_tol - set the tolerance for local solve
584: . -pc_parms_levels - set the number of levels
585: . -pc_parms_nonsymmetric_perm - set the use of nonsymmetric permutation
586: . -pc_parms_blocksize - set the block size
587: . -pc_parms_ind_tol - set the tolerance for independent sets
588: . -pc_parms_max_dim - set the inner krylov dimension
589: . -pc_parms_max_it - set the maximum number of inner iterations
590: . -pc_parms_inter_nonsymmetric_perm - set the use of nonsymmetric permutation for interlevel blocks
591: . -pc_parms_inter_column_perm - set the use of column permutation for interlevel blocks
592: . -pc_parms_inter_row_scaling - set the use of row scaling for interlevel blocks
593: . -pc_parms_inter_column_scaling - set the use of column scaling for interlevel blocks
594: . -pc_parms_last_nonsymmetric_perm - set the use of nonsymmetric permutation for last level blocks
595: . -pc_parms_last_column_perm - set the use of column permutation for last level blocks
596: . -pc_parms_last_row_scaling - set the use of row scaling for last level blocks
597: . -pc_parms_last_column_scaling - set the use of column scaling for last level blocks
598: . -pc_parms_lfil_ilu_arms - set the amount of fill-in for ilut, iluk and arms
599: . -pc_parms_lfil_schur - set the amount of fill-in for schur
600: . -pc_parms_lfil_ilut_L_U - set the amount of fill-in for ILUT L and U
601: . -pc_parms_droptol_factors - set the drop tolerance for L, U, L^{-1}F and EU^{-1}
602: . -pc_parms_droptol_schur_compl - set the drop tolerance for schur complement at each level
603: - -pc_parms_droptol_last_schur - set the drop tolerance for ILUT in last level schur complement
605: Note:
606: Unless configured appropriately, this preconditioner performs an inexact solve
607: as part of the preconditioner application. Therefore, it must be used in combination
608: with flexible variants of iterative solvers, such as `KSPFGMRES` or `KSPGCR`.
610: Level: intermediate
612: .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`, `PCMG`, `PCGAMG`, `PCHYPRE`, `PCPARMSSetGlobal()`,
613: `PCPARMSSetLocal()`, `PCPARMSSetSolveTolerances()`, `PCPARMSSetSolveRestart()`, `PCPARMSSetNonsymPerm()`,
614: `PCPARMSSetFill()`
615: M*/
617: PETSC_EXTERN PetscErrorCode PCCreate_PARMS(PC pc)
618: {
619: PC_PARMS *parms;
621: PetscNew(&parms);
623: parms->map = 0;
624: parms->A = 0;
625: parms->pc = 0;
626: parms->global = PC_PARMS_GLOBAL_RAS;
627: parms->local = PC_PARMS_LOCAL_ARMS;
628: parms->levels = 10;
629: parms->nonsymperm = PETSC_TRUE;
630: parms->blocksize = 250;
631: parms->maxdim = 0;
632: parms->maxits = 0;
633: parms->meth[0] = PETSC_FALSE;
634: parms->meth[1] = PETSC_FALSE;
635: parms->meth[2] = PETSC_FALSE;
636: parms->meth[3] = PETSC_FALSE;
637: parms->meth[4] = PETSC_FALSE;
638: parms->meth[5] = PETSC_FALSE;
639: parms->meth[6] = PETSC_FALSE;
640: parms->meth[7] = PETSC_FALSE;
641: parms->solvetol = 0.01;
642: parms->indtol = 0.4;
643: parms->lfil[0] = parms->lfil[1] = parms->lfil[2] = parms->lfil[3] = 20;
644: parms->lfil[4] = parms->lfil[5] = parms->lfil[6] = 20;
645: parms->droptol[0] = parms->droptol[1] = parms->droptol[2] = parms->droptol[3] = 0.00001;
646: parms->droptol[4] = 0.001;
647: parms->droptol[5] = parms->droptol[6] = 0.001;
649: pc->data = parms;
650: pc->ops->destroy = PCDestroy_PARMS;
651: pc->ops->setfromoptions = PCSetFromOptions_PARMS;
652: pc->ops->setup = PCSetUp_PARMS;
653: pc->ops->apply = PCApply_PARMS;
654: pc->ops->view = PCView_PARMS;
656: PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetGlobal_C", PCPARMSSetGlobal_PARMS);
657: PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetLocal_C", PCPARMSSetLocal_PARMS);
658: PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetSolveTolerances_C", PCPARMSSetSolveTolerances_PARMS);
659: PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetSolveRestart_C", PCPARMSSetSolveRestart_PARMS);
660: PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetNonsymPerm_C", PCPARMSSetNonsymPerm_PARMS);
661: PetscObjectComposeFunction((PetscObject)pc, "PCPARMSSetFill_C", PCPARMSSetFill_PARMS);
662: return 0;
663: }