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: parms_PCSetType(parms->pc, PCRAS); break;
149: case 1: parms_PCSetType(parms->pc, PCSCHUR); break;
150: case 2: parms_PCSetType(parms->pc, PCBJ); break;
151: }
152: switch (parms->local) {
153: case 0: parms_PCSetILUType(parms->pc, PCILU0); break;
154: case 1: parms_PCSetILUType(parms->pc, PCILUK); break;
155: case 2: parms_PCSetILUType(parms->pc, PCILUT); break;
156: case 3: parms_PCSetILUType(parms->pc, PCARMS); break;
157: }
158: parms_PCSetInnerEps(parms->pc, parms->solvetol);
159: parms_PCSetNlevels(parms->pc, parms->levels);
160: parms_PCSetPermType(parms->pc, parms->nonsymperm ? 1 : 0);
161: parms_PCSetBsize(parms->pc, parms->blocksize);
162: parms_PCSetTolInd(parms->pc, parms->indtol);
163: parms_PCSetInnerKSize(parms->pc, parms->maxdim);
164: parms_PCSetInnerMaxits(parms->pc, parms->maxits);
165: for (i=0; i<8; i++) meth[i] = parms->meth[i] ? 1 : 0;
166: parms_PCSetPermScalOptions(parms->pc, &meth[0], 1);
167: parms_PCSetPermScalOptions(parms->pc, &meth[4], 0);
168: parms_PCSetFill(parms->pc, parms->lfil);
169: parms_PCSetTol(parms->pc, parms->droptol);
171: parms_PCSetup(parms->pc);
173: /* Allocate two auxiliary vector of length lsize */
174: if (parms->lvec0) PetscFree(parms->lvec0);
175: PetscMalloc1(lsize, &parms->lvec0);
176: if (parms->lvec1) PetscFree(parms->lvec1);
177: PetscMalloc1(lsize, &parms->lvec1);
178: return 0;
179: }
181: static PetscErrorCode PCView_PARMS(PC pc,PetscViewer viewer)
182: {
183: PetscBool iascii;
184: PC_PARMS *parms = (PC_PARMS*)pc->data;
185: char *str;
186: double fill_fact;
188: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
189: if (iascii) {
190: parms_PCGetName(parms->pc,&str);
191: PetscViewerASCIIPrintf(viewer," global preconditioner: %s\n",str);
192: parms_PCILUGetName(parms->pc,&str);
193: PetscViewerASCIIPrintf(viewer," local preconditioner: %s\n",str);
194: parms_PCGetRatio(parms->pc,&fill_fact);
195: PetscViewerASCIIPrintf(viewer," non-zero elements/original non-zero entries: %-4.2f\n",fill_fact);
196: PetscViewerASCIIPrintf(viewer," Tolerance for local solve: %g\n",parms->solvetol);
197: PetscViewerASCIIPrintf(viewer," Number of levels: %d\n",parms->levels);
198: if (parms->nonsymperm) {
199: PetscViewerASCIIPrintf(viewer," Using nonsymmetric permutation\n");
200: }
201: PetscViewerASCIIPrintf(viewer," Block size: %d\n",parms->blocksize);
202: PetscViewerASCIIPrintf(viewer," Tolerance for independent sets: %g\n",parms->indtol);
203: PetscViewerASCIIPrintf(viewer," Inner Krylov dimension: %d\n",parms->maxdim);
204: PetscViewerASCIIPrintf(viewer," Maximum number of inner iterations: %d\n",parms->maxits);
205: if (parms->meth[0]) {
206: PetscViewerASCIIPrintf(viewer," Using nonsymmetric permutation for interlevel blocks\n");
207: }
208: if (parms->meth[1]) {
209: PetscViewerASCIIPrintf(viewer," Using column permutation for interlevel blocks\n");
210: }
211: if (parms->meth[2]) {
212: PetscViewerASCIIPrintf(viewer," Using row scaling for interlevel blocks\n");
213: }
214: if (parms->meth[3]) {
215: PetscViewerASCIIPrintf(viewer," Using column scaling for interlevel blocks\n");
216: }
217: if (parms->meth[4]) {
218: PetscViewerASCIIPrintf(viewer," Using nonsymmetric permutation for last level blocks\n");
219: }
220: if (parms->meth[5]) {
221: PetscViewerASCIIPrintf(viewer," Using column permutation for last level blocks\n");
222: }
223: if (parms->meth[6]) {
224: PetscViewerASCIIPrintf(viewer," Using row scaling for last level blocks\n");
225: }
226: if (parms->meth[7]) {
227: PetscViewerASCIIPrintf(viewer," Using column scaling for last level blocks\n");
228: }
229: PetscViewerASCIIPrintf(viewer," amount of fill-in for ilut, iluk and arms: %d\n",parms->lfil[0]);
230: PetscViewerASCIIPrintf(viewer," amount of fill-in for schur: %d\n",parms->lfil[4]);
231: PetscViewerASCIIPrintf(viewer," amount of fill-in for ILUT L and U: %d\n",parms->lfil[5]);
232: PetscViewerASCIIPrintf(viewer," drop tolerance for L, U, L^{-1}F and EU^{-1}: %g\n",parms->droptol[0]);
233: PetscViewerASCIIPrintf(viewer," drop tolerance for schur complement at each level: %g\n",parms->droptol[4]);
234: PetscViewerASCIIPrintf(viewer," drop tolerance for ILUT in last level schur complement: %g\n",parms->droptol[5]);
235: }
236: return 0;
237: }
239: static PetscErrorCode PCDestroy_PARMS(PC pc)
240: {
241: PC_PARMS *parms = (PC_PARMS*)pc->data;
243: if (parms->map) parms_MapFree(&parms->map);
244: if (parms->A) parms_MatFree(&parms->A);
245: if (parms->pc) parms_PCFree(&parms->pc);
246: if (parms->lvec0) {
247: PetscFree(parms->lvec0);
248: }
249: if (parms->lvec1) {
250: PetscFree(parms->lvec1);
251: }
252: PetscFree(pc->data);
254: PetscObjectChangeTypeName((PetscObject)pc,0);
255: PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetGlobal_C",NULL);
256: PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetLocal_C",NULL);
257: PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetSolveTolerances_C",NULL);
258: PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetSolveRestart_C",NULL);
259: PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetNonsymPerm_C",NULL);
260: PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetFill_C",NULL);
261: return 0;
262: }
264: static PetscErrorCode PCSetFromOptions_PARMS(PetscOptionItems *PetscOptionsObject,PC pc)
265: {
266: PC_PARMS *parms = (PC_PARMS*)pc->data;
267: PetscBool flag;
268: PCPARMSGlobalType global;
269: PCPARMSLocalType local;
271: PetscOptionsHead(PetscOptionsObject,"PARMS Options");
272: PetscOptionsEnum("-pc_parms_global","Global preconditioner","PCPARMSSetGlobal",PCPARMSGlobalTypes,(PetscEnum)parms->global,(PetscEnum*)&global,&flag);
273: if (flag) PCPARMSSetGlobal(pc,global);
274: PetscOptionsEnum("-pc_parms_local","Local preconditioner","PCPARMSSetLocal",PCPARMSLocalTypes,(PetscEnum)parms->local,(PetscEnum*)&local,&flag);
275: if (flag) PCPARMSSetLocal(pc,local);
276: PetscOptionsReal("-pc_parms_solve_tol","Tolerance for local solve","PCPARMSSetSolveTolerances",parms->solvetol,&parms->solvetol,NULL);
277: PetscOptionsInt("-pc_parms_levels","Number of levels","None",parms->levels,&parms->levels,NULL);
278: PetscOptionsBool("-pc_parms_nonsymmetric_perm","Use nonsymmetric permutation","PCPARMSSetNonsymPerm",parms->nonsymperm,&parms->nonsymperm,NULL);
279: PetscOptionsInt("-pc_parms_blocksize","Block size","None",parms->blocksize,&parms->blocksize,NULL);
280: PetscOptionsReal("-pc_parms_ind_tol","Tolerance for independent sets","None",parms->indtol,&parms->indtol,NULL);
281: PetscOptionsInt("-pc_parms_max_dim","Inner Krylov dimension","PCPARMSSetSolveRestart",parms->maxdim,&parms->maxdim,NULL);
282: PetscOptionsInt("-pc_parms_max_it","Maximum number of inner iterations","PCPARMSSetSolveTolerances",parms->maxits,&parms->maxits,NULL);
283: PetscOptionsBool("-pc_parms_inter_nonsymmetric_perm","nonsymmetric permutation for interlevel blocks","None",parms->meth[0],&parms->meth[0],NULL);
284: PetscOptionsBool("-pc_parms_inter_column_perm","column permutation for interlevel blocks","None",parms->meth[1],&parms->meth[1],NULL);
285: PetscOptionsBool("-pc_parms_inter_row_scaling","row scaling for interlevel blocks","None",parms->meth[2],&parms->meth[2],NULL);
286: PetscOptionsBool("-pc_parms_inter_column_scaling","column scaling for interlevel blocks","None",parms->meth[3],&parms->meth[3],NULL);
287: PetscOptionsBool("-pc_parms_last_nonsymmetric_perm","nonsymmetric permutation for last level blocks","None",parms->meth[4],&parms->meth[4],NULL);
288: PetscOptionsBool("-pc_parms_last_column_perm","column permutation for last level blocks","None",parms->meth[5],&parms->meth[5],NULL);
289: PetscOptionsBool("-pc_parms_last_row_scaling","row scaling for last level blocks","None",parms->meth[6],&parms->meth[6],NULL);
290: PetscOptionsBool("-pc_parms_last_column_scaling","column scaling for last level blocks","None",parms->meth[7],&parms->meth[7],NULL);
291: PetscOptionsInt("-pc_parms_lfil_ilu_arms","amount of fill-in for ilut, iluk and arms","PCPARMSSetFill",parms->lfil[0],&parms->lfil[0],&flag);
292: if (flag) parms->lfil[1] = parms->lfil[2] = parms->lfil[3] = parms->lfil[0];
293: PetscOptionsInt("-pc_parms_lfil_schur","amount of fill-in for schur","PCPARMSSetFill",parms->lfil[4],&parms->lfil[4],NULL);
294: PetscOptionsInt("-pc_parms_lfil_ilut_L_U","amount of fill-in for ILUT L and U","PCPARMSSetFill",parms->lfil[5],&parms->lfil[5],&flag);
295: if (flag) parms->lfil[6] = parms->lfil[5];
296: PetscOptionsReal("-pc_parms_droptol_factors","drop tolerance for L, U, L^{-1}F and EU^{-1}","None",parms->droptol[0],&parms->droptol[0],NULL);
297: PetscOptionsReal("-pc_parms_droptol_schur_compl","drop tolerance for schur complement at each level","None",parms->droptol[4],&parms->droptol[4],&flag);
298: if (flag) parms->droptol[1] = parms->droptol[2] = parms->droptol[3] = parms->droptol[0];
299: PetscOptionsReal("-pc_parms_droptol_last_schur","drop tolerance for ILUT in last level schur complement","None",parms->droptol[5],&parms->droptol[5],&flag);
300: if (flag) parms->droptol[6] = parms->droptol[5];
301: PetscOptionsTail();
302: return 0;
303: }
305: static PetscErrorCode PCApply_PARMS(PC pc,Vec b,Vec x)
306: {
307: PC_PARMS *parms = (PC_PARMS*)pc->data;
308: const PetscScalar *b1;
309: PetscScalar *x1;
311: VecGetArrayRead(b,&b1);
312: VecGetArray(x,&x1);
313: parms_VecPermAux((PetscScalar*)b1,parms->lvec0,parms->map);
314: parms_PCApply(parms->pc,parms->lvec0,parms->lvec1);
315: parms_VecInvPermAux(parms->lvec1,x1,parms->map);
316: VecRestoreArrayRead(b,&b1);
317: VecRestoreArray(x,&x1);
318: return 0;
319: }
321: static PetscErrorCode PCPARMSSetGlobal_PARMS(PC pc,PCPARMSGlobalType type)
322: {
323: PC_PARMS *parms = (PC_PARMS*)pc->data;
325: if (type != parms->global) {
326: parms->global = type;
327: pc->setupcalled = 0;
328: }
329: return 0;
330: }
332: /*@
333: PCPARMSSetGlobal - Sets the global preconditioner to be used in PARMS.
335: Collective on PC
337: Input Parameters:
338: + pc - the preconditioner context
339: - type - the global preconditioner type, one of
340: .vb
341: PC_PARMS_GLOBAL_RAS - Restricted additive Schwarz
342: PC_PARMS_GLOBAL_SCHUR - Schur complement
343: PC_PARMS_GLOBAL_BJ - Block Jacobi
344: .ve
346: Options Database Keys:
347: -pc_parms_global [ras,schur,bj] - Sets global preconditioner
349: Level: intermediate
351: Notes:
352: See the pARMS function parms_PCSetType for more information.
354: .seealso: PCPARMS, PCPARMSSetLocal()
355: @*/
356: PetscErrorCode PCPARMSSetGlobal(PC pc,PCPARMSGlobalType type)
357: {
360: PetscTryMethod(pc,"PCPARMSSetGlobal_C",(PC,PCPARMSGlobalType),(pc,type));
361: return 0;
362: }
364: static PetscErrorCode PCPARMSSetLocal_PARMS(PC pc,PCPARMSLocalType type)
365: {
366: PC_PARMS *parms = (PC_PARMS*)pc->data;
368: if (type != parms->local) {
369: parms->local = type;
370: pc->setupcalled = 0;
371: }
372: return 0;
373: }
375: /*@
376: PCPARMSSetLocal - Sets the local preconditioner to be used in PARMS.
378: Collective on PC
380: Input Parameters:
381: + pc - the preconditioner context
382: - type - the local preconditioner type, one of
383: .vb
384: PC_PARMS_LOCAL_ILU0 - ILU0 preconditioner
385: PC_PARMS_LOCAL_ILUK - ILU(k) preconditioner
386: PC_PARMS_LOCAL_ILUT - ILUT preconditioner
387: PC_PARMS_LOCAL_ARMS - ARMS preconditioner
388: .ve
390: Options Database Keys:
391: -pc_parms_local [ilu0,iluk,ilut,arms] - Sets local preconditioner
393: Level: intermediate
395: Notes:
396: For the ARMS preconditioner, one can use either the symmetric ARMS or the non-symmetric
397: variant (ARMS-ddPQ) by setting the permutation type with PCPARMSSetNonsymPerm().
399: See the pARMS function parms_PCILUSetType for more information.
401: .seealso: PCPARMS, PCPARMSSetGlobal(), PCPARMSSetNonsymPerm()
403: @*/
404: PetscErrorCode PCPARMSSetLocal(PC pc,PCPARMSLocalType type)
405: {
408: PetscTryMethod(pc,"PCPARMSSetLocal_C",(PC,PCPARMSLocalType),(pc,type));
409: return 0;
410: }
412: static PetscErrorCode PCPARMSSetSolveTolerances_PARMS(PC pc,PetscReal tol,PetscInt maxits)
413: {
414: PC_PARMS *parms = (PC_PARMS*)pc->data;
416: if (tol != parms->solvetol) {
417: parms->solvetol = tol;
418: pc->setupcalled = 0;
419: }
420: if (maxits != parms->maxits) {
421: parms->maxits = maxits;
422: pc->setupcalled = 0;
423: }
424: return 0;
425: }
427: /*@
428: PCPARMSSetSolveTolerances - Sets the convergence tolerance and the maximum iterations for the
429: inner GMRES solver, when the Schur global preconditioner is used.
431: Collective on PC
433: Input Parameters:
434: + pc - the preconditioner context
435: . tol - the convergence tolerance
436: - maxits - the maximum number of iterations to use
438: Options Database Keys:
439: + -pc_parms_solve_tol - set the tolerance for local solve
440: - -pc_parms_max_it - set the maximum number of inner iterations
442: Level: intermediate
444: Notes:
445: See the pARMS functions parms_PCSetInnerEps and parms_PCSetInnerMaxits for more information.
447: .seealso: PCPARMS, PCPARMSSetSolveRestart()
448: @*/
449: PetscErrorCode PCPARMSSetSolveTolerances(PC pc,PetscReal tol,PetscInt maxits)
450: {
452: PetscTryMethod(pc,"PCPARMSSetSolveTolerances_C",(PC,PetscReal,PetscInt),(pc,tol,maxits));
453: return 0;
454: }
456: static PetscErrorCode PCPARMSSetSolveRestart_PARMS(PC pc,PetscInt restart)
457: {
458: PC_PARMS *parms = (PC_PARMS*)pc->data;
460: if (restart != parms->maxdim) {
461: parms->maxdim = restart;
462: pc->setupcalled = 0;
463: }
464: return 0;
465: }
467: /*@
468: PCPARMSSetSolveRestart - Sets the number of iterations at which the
469: inner GMRES solver restarts.
471: Collective on PC
473: Input Parameters:
474: + pc - the preconditioner context
475: - restart - maximum dimension of the Krylov subspace
477: Options Database Keys:
478: . -pc_parms_max_dim - sets the inner Krylov dimension
480: Level: intermediate
482: Notes:
483: See the pARMS function parms_PCSetInnerKSize for more information.
485: .seealso: PCPARMS, PCPARMSSetSolveTolerances()
486: @*/
487: PetscErrorCode PCPARMSSetSolveRestart(PC pc,PetscInt restart)
488: {
490: PetscTryMethod(pc,"PCPARMSSetSolveRestart_C",(PC,PetscInt),(pc,restart));
491: return 0;
492: }
494: static PetscErrorCode PCPARMSSetNonsymPerm_PARMS(PC pc,PetscBool nonsym)
495: {
496: PC_PARMS *parms = (PC_PARMS*)pc->data;
498: if ((nonsym && !parms->nonsymperm) || (!nonsym && parms->nonsymperm)) {
499: parms->nonsymperm = nonsym;
500: pc->setupcalled = 0;
501: }
502: return 0;
503: }
505: /*@
506: PCPARMSSetNonsymPerm - Sets the type of permutation for the ARMS preconditioner: the standard
507: symmetric ARMS or the non-symmetric ARMS (ARMS-ddPQ).
509: Collective on PC
511: Input Parameters:
512: + pc - the preconditioner context
513: - nonsym - PETSC_TRUE indicates the non-symmetric ARMS is used;
514: PETSC_FALSE indicates the symmetric ARMS is used
516: Options Database Keys:
517: . -pc_parms_nonsymmetric_perm - sets the use of nonsymmetric permutation
519: Level: intermediate
521: Notes:
522: See the pARMS function parms_PCSetPermType for more information.
524: .seealso: PCPARMS
525: @*/
526: PetscErrorCode PCPARMSSetNonsymPerm(PC pc,PetscBool nonsym)
527: {
529: PetscTryMethod(pc,"PCPARMSSetNonsymPerm_C",(PC,PetscBool),(pc,nonsym));
530: return 0;
531: }
533: static PetscErrorCode PCPARMSSetFill_PARMS(PC pc,PetscInt lfil0,PetscInt lfil1,PetscInt lfil2)
534: {
535: PC_PARMS *parms = (PC_PARMS*)pc->data;
537: if (lfil0 != parms->lfil[0] || lfil0 != parms->lfil[1] || lfil0 != parms->lfil[2] || lfil0 != parms->lfil[3]) {
538: parms->lfil[1] = parms->lfil[2] = parms->lfil[3] = parms->lfil[0] = lfil0;
539: pc->setupcalled = 0;
540: }
541: if (lfil1 != parms->lfil[4]) {
542: parms->lfil[4] = lfil1;
543: pc->setupcalled = 0;
544: }
545: if (lfil2 != parms->lfil[5] || lfil2 != parms->lfil[6]) {
546: parms->lfil[5] = parms->lfil[6] = lfil2;
547: pc->setupcalled = 0;
548: }
549: return 0;
550: }
552: /*@
553: PCPARMSSetFill - Sets the fill-in parameters for ILUT, ILUK and ARMS preconditioners.
554: Consider the original matrix A = [B F; E C] and the approximate version
555: M = [LB 0; E/UB I]*[UB LB\F; 0 S].
557: Collective on PC
559: Input Parameters:
560: + pc - the preconditioner context
561: . fil0 - the level of fill-in kept in LB, UB, E/UB and LB\F
562: . fil1 - the level of fill-in kept in S
563: - fil2 - the level of fill-in kept in the L and U parts of the LU factorization of S
565: Options Database Keys:
566: + -pc_parms_lfil_ilu_arms - set the amount of fill-in for ilut, iluk and arms
567: . -pc_parms_lfil_schur - set the amount of fill-in for schur
568: - -pc_parms_lfil_ilut_L_U - set the amount of fill-in for ILUT L and U
570: Level: intermediate
572: Notes:
573: See the pARMS function parms_PCSetFill for more information.
575: .seealso: PCPARMS
576: @*/
577: PetscErrorCode PCPARMSSetFill(PC pc,PetscInt lfil0,PetscInt lfil1,PetscInt lfil2)
578: {
580: PetscTryMethod(pc,"PCPARMSSetFill_C",(PC,PetscInt,PetscInt,PetscInt),(pc,lfil0,lfil1,lfil2));
581: return 0;
582: }
584: /*MC
585: PCPARMS - Allows the use of the parallel Algebraic Recursive Multilevel Solvers
586: available in the package pARMS
588: Options Database Keys:
589: + -pc_parms_global - one of ras, schur, bj
590: . -pc_parms_local - one of ilu0, iluk, ilut, arms
591: . -pc_parms_solve_tol - set the tolerance for local solve
592: . -pc_parms_levels - set the number of levels
593: . -pc_parms_nonsymmetric_perm - set the use of nonsymmetric permutation
594: . -pc_parms_blocksize - set the block size
595: . -pc_parms_ind_tol - set the tolerance for independent sets
596: . -pc_parms_max_dim - set the inner krylov dimension
597: . -pc_parms_max_it - set the maximum number of inner iterations
598: . -pc_parms_inter_nonsymmetric_perm - set the use of nonsymmetric permutation for interlevel blocks
599: . -pc_parms_inter_column_perm - set the use of column permutation for interlevel blocks
600: . -pc_parms_inter_row_scaling - set the use of row scaling for interlevel blocks
601: . -pc_parms_inter_column_scaling - set the use of column scaling for interlevel blocks
602: . -pc_parms_last_nonsymmetric_perm - set the use of nonsymmetric permutation for last level blocks
603: . -pc_parms_last_column_perm - set the use of column permutation for last level blocks
604: . -pc_parms_last_row_scaling - set the use of row scaling for last level blocks
605: . -pc_parms_last_column_scaling - set the use of column scaling for last level blocks
606: . -pc_parms_lfil_ilu_arms - set the amount of fill-in for ilut, iluk and arms
607: . -pc_parms_lfil_schur - set the amount of fill-in for schur
608: . -pc_parms_lfil_ilut_L_U - set the amount of fill-in for ILUT L and U
609: . -pc_parms_droptol_factors - set the drop tolerance for L, U, L^{-1}F and EU^{-1}
610: . -pc_parms_droptol_schur_compl - set the drop tolerance for schur complement at each level
611: - -pc_parms_droptol_last_schur - set the drop tolerance for ILUT in last level schur complement
613: IMPORTANT:
614: Unless configured appropriately, this preconditioner performs an inexact solve
615: as part of the preconditioner application. Therefore, it must be used in combination
616: with flexible variants of iterative solvers, such as KSPFGMRES or KSPGCR.
618: Level: intermediate
620: .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC
621: M*/
623: PETSC_EXTERN PetscErrorCode PCCreate_PARMS(PC pc)
624: {
625: PC_PARMS *parms;
627: PetscNewLog(pc,&parms);
629: parms->map = 0;
630: parms->A = 0;
631: parms->pc = 0;
632: parms->global = PC_PARMS_GLOBAL_RAS;
633: parms->local = PC_PARMS_LOCAL_ARMS;
634: parms->levels = 10;
635: parms->nonsymperm = PETSC_TRUE;
636: parms->blocksize = 250;
637: parms->maxdim = 0;
638: parms->maxits = 0;
639: parms->meth[0] = PETSC_FALSE;
640: parms->meth[1] = PETSC_FALSE;
641: parms->meth[2] = PETSC_FALSE;
642: parms->meth[3] = PETSC_FALSE;
643: parms->meth[4] = PETSC_FALSE;
644: parms->meth[5] = PETSC_FALSE;
645: parms->meth[6] = PETSC_FALSE;
646: parms->meth[7] = PETSC_FALSE;
647: parms->solvetol = 0.01;
648: parms->indtol = 0.4;
649: parms->lfil[0] = parms->lfil[1] = parms->lfil[2] = parms->lfil[3] = 20;
650: parms->lfil[4] = parms->lfil[5] = parms->lfil[6] = 20;
651: parms->droptol[0] = parms->droptol[1] = parms->droptol[2] = parms->droptol[3] = 0.00001;
652: parms->droptol[4] = 0.001;
653: parms->droptol[5] = parms->droptol[6] = 0.001;
655: pc->data = parms;
656: pc->ops->destroy = PCDestroy_PARMS;
657: pc->ops->setfromoptions = PCSetFromOptions_PARMS;
658: pc->ops->setup = PCSetUp_PARMS;
659: pc->ops->apply = PCApply_PARMS;
660: pc->ops->view = PCView_PARMS;
662: PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetGlobal_C",PCPARMSSetGlobal_PARMS);
663: PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetLocal_C",PCPARMSSetLocal_PARMS);
664: PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetSolveTolerances_C",PCPARMSSetSolveTolerances_PARMS);
665: PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetSolveRestart_C",PCPARMSSetSolveRestart_PARMS);
666: PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetNonsymPerm_C",PCPARMSSetNonsymPerm_PARMS);
667: PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetFill_C",PCPARMSSetFill_PARMS);
668: return 0;
669: }