Actual source code: icc.c
1: #define PETSCKSP_DLL
3: /*
4: Defines a Cholesky factorization preconditioner for any Mat implementation.
5: Presently only provided for MPIRowbs format (i.e. BlockSolve).
6: */
8: #include src/ksp/pc/impls/factor/icc/icc.h
13: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetZeroPivot_ICC(PC pc,PetscReal z)
14: {
15: PC_ICC *icc;
18: icc = (PC_ICC*)pc->data;
19: icc->info.zeropivot = z;
20: return(0);
21: }
27: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetShiftNonzero_ICC(PC pc,PetscReal shift)
28: {
29: PC_ICC *dir;
32: dir = (PC_ICC*)pc->data;
33: if (shift == (PetscReal) PETSC_DECIDE) {
34: dir->info.shiftnz = 1.e-12;
35: } else {
36: dir->info.shiftnz = shift;
37: }
38: return(0);
39: }
45: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetShiftPd_ICC(PC pc,PetscTruth shift)
46: {
47: PC_ICC *dir;
48:
50: dir = (PC_ICC*)pc->data;
51: if (shift) {
52: dir->info.shift_fraction = 0.0;
53: dir->info.shiftpd = 1.0;
54: } else {
55: dir->info.shiftpd = 0.0;
56: }
57: return(0);
58: }
64: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetMatOrdering_ICC(PC pc,MatOrderingType ordering)
65: {
66: PC_ICC *dir = (PC_ICC*)pc->data;
68:
70: PetscStrfree(dir->ordering);
71: PetscStrallocpy(ordering,&dir->ordering);
72: return(0);
73: }
79: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetFill_ICC(PC pc,PetscReal fill)
80: {
81: PC_ICC *dir;
84: dir = (PC_ICC*)pc->data;
85: dir->info.fill = fill;
86: return(0);
87: }
93: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetLevels_ICC(PC pc,PetscInt levels)
94: {
95: PC_ICC *icc;
98: icc = (PC_ICC*)pc->data;
99: icc->info.levels = levels;
100: return(0);
101: }
106: static PetscErrorCode PCSetup_ICC(PC pc)
107: {
108: PC_ICC *icc = (PC_ICC*)pc->data;
109: IS perm,cperm;
113: MatGetOrdering(pc->pmat,icc->ordering,&perm,&cperm);
115: if (!pc->setupcalled) {
116: MatICCFactorSymbolic(pc->pmat,perm,&icc->info,&icc->fact);
117: } else if (pc->flag != SAME_NONZERO_PATTERN) {
118: MatDestroy(icc->fact);
119: MatICCFactorSymbolic(pc->pmat,perm,&icc->info,&icc->fact);
120: }
121: ISDestroy(cperm);
122: ISDestroy(perm);
123: MatCholeskyFactorNumeric(pc->pmat,&icc->info,&icc->fact);
124: return(0);
125: }
129: static PetscErrorCode PCDestroy_ICC(PC pc)
130: {
131: PC_ICC *icc = (PC_ICC*)pc->data;
135: if (icc->fact) {MatDestroy(icc->fact);}
136: PetscStrfree(icc->ordering);
137: PetscFree(icc);
138: return(0);
139: }
143: static PetscErrorCode PCApply_ICC(PC pc,Vec x,Vec y)
144: {
145: PC_ICC *icc = (PC_ICC*)pc->data;
149: MatSolve(icc->fact,x,y);
150: return(0);
151: }
155: static PetscErrorCode PCApplySymmetricLeft_ICC(PC pc,Vec x,Vec y)
156: {
158: PC_ICC *icc = (PC_ICC*)pc->data;
161: MatForwardSolve(icc->fact,x,y);
162: return(0);
163: }
167: static PetscErrorCode PCApplySymmetricRight_ICC(PC pc,Vec x,Vec y)
168: {
170: PC_ICC *icc = (PC_ICC*)pc->data;
173: MatBackwardSolve(icc->fact,x,y);
174: return(0);
175: }
179: static PetscErrorCode PCGetFactoredMatrix_ICC(PC pc,Mat *mat)
180: {
181: PC_ICC *icc = (PC_ICC*)pc->data;
184: *mat = icc->fact;
185: return(0);
186: }
190: static PetscErrorCode PCSetFromOptions_ICC(PC pc)
191: {
192: PC_ICC *icc = (PC_ICC*)pc->data;
193: char tname[256];
194: PetscTruth flg;
196: PetscFList ordlist;
199: MatOrderingRegisterAll(PETSC_NULL);
200: PetscOptionsHead("ICC Options");
201: PetscOptionsReal("-pc_factor_levels","levels of fill","PCFactorSetLevels",icc->info.levels,&icc->info.levels,&flg);
202: PetscOptionsReal("-pc_factor_fill","Expected fill in factorization","PCFactorSetFill",icc->info.fill,&icc->info.fill,&flg);
203: MatGetOrderingList(&ordlist);
204: PetscOptionsList("-pc_factor_mat_ordering_type","Reorder to reduce nonzeros in ICC","PCFactorSetMatOrdering",ordlist,icc->ordering,tname,256,&flg);
205: if (flg) {
206: PCFactorSetMatOrdering(pc,tname);
207: }
208: PetscOptionsName("-pc_factor_shift_nonzero","Shift added to diagonal","PCFactorSetShiftNonzero",&flg);
209: if (flg) {
210: PCFactorSetShiftNonzero(pc,(PetscReal)PETSC_DECIDE);
211: }
212: PetscOptionsReal("-pc_factor_shift_nonzero","Shift added to diagonal","PCFactorSetShiftNonzero",icc->info.shiftnz,&icc->info.shiftnz,0);
213: PetscOptionsName("-pc_factor_shift_positive_definite","Manteuffel shift applied to diagonal","PCFactorSetShift",&flg);
214: if (flg) {
215: PCFactorSetShiftPd(pc,PETSC_TRUE);
216: } else {
217: PCFactorSetShiftPd(pc,PETSC_FALSE);
218: }
219: PetscOptionsReal("-pc_factor_zeropivot","Pivot is considered zero if less than","PCFactorSetZeroPivot",icc->info.zeropivot,&icc->info.zeropivot,0);
220:
221: PetscOptionsTail();
222: return(0);
223: }
227: static PetscErrorCode PCView_ICC(PC pc,PetscViewer viewer)
228: {
229: PC_ICC *icc = (PC_ICC*)pc->data;
231: PetscTruth isstring,iascii;
234: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
235: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
236: if (iascii) {
237: if (icc->info.levels == 1) {
238: PetscViewerASCIIPrintf(viewer," ICC: %D level of fill\n",(PetscInt)icc->info.levels);
239: } else {
240: PetscViewerASCIIPrintf(viewer," ICC: %D levels of fill\n",(PetscInt)icc->info.levels);
241: }
242: PetscViewerASCIIPrintf(viewer," ICC: max fill ratio allocated %G\n",icc->info.fill);
243: if (icc->info.shiftpd) {PetscViewerASCIIPrintf(viewer," ICC: using Manteuffel shift\n");}
244: } else if (isstring) {
245: PetscViewerStringSPrintf(viewer," lvls=%D",(PetscInt)icc->info.levels);
246: } else {
247: SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for PCICC",((PetscObject)viewer)->type_name);
248: }
249: return(0);
250: }
252: /*MC
253: PCICC - Incomplete Cholesky factorization preconditioners.
255: Options Database Keys:
256: + -pc_factor_levels <k> - number of levels of fill for ICC(k)
257: . -pc_factor_in_place - only for ICC(0) with natural ordering, reuses the space of the matrix for
258: its factorization (overwrites original matrix)
259: . -pc_factor_fill <nfill> - expected amount of fill in factored matrix compared to original matrix, nfill > 1
260: . -pc_factor_mat_ordering_type <natural,nd,1wd,rcm,qmd> - set the row/column ordering of the factored matrix
261: . -pc_factor_shift_nonzero <shift> - Sets shift amount or PETSC_DECIDE for the default
262: - -pc_factor_shift_positive_definite [PETSC_TRUE/PETSC_FALSE] - Activate/Deactivate PCFactorSetShiftPd(); the value
263: is optional with PETSC_TRUE being the default
265: Level: beginner
267: Concepts: incomplete Cholesky factorization
269: Notes: Only implemented for some matrix formats. Not implemented in parallel
271: For BAIJ matrices this implements a point block ICC.
273: The Manteuffel shift is only implemented for matrices with block size 1
275: By default, the Manteuffel is applied (for matrices with block size 1). Call PCFactorSetShiftPd(pc,PETSC_FALSE);
276: to turn off the shift.
279: .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, PCSOR, MatOrderingType,
280: PCFactorSetZeroPivot(), PCFactorSetShiftNonzero(), PCFactorSetShiftPd(),
281: PCFactorSetFill(), PCFactorSetMatOrdering(), PCFactorSetReuseOrdering(),
282: PCFactorSetLevels(),PCFactorSetShiftNonzero(),PCFactorSetShiftPd(),
284: M*/
289: PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_ICC(PC pc)
290: {
292: PC_ICC *icc;
295: PetscNew(PC_ICC,&icc);
296: PetscLogObjectMemory(pc,sizeof(PC_ICC));
298: icc->fact = 0;
299: PetscStrallocpy(MATORDERING_NATURAL,&icc->ordering);
300: MatFactorInfoInitialize(&icc->info);
301: icc->info.levels = 0;
302: icc->info.fill = 1.0;
303: icc->implctx = 0;
305: icc->info.dtcol = PETSC_DEFAULT;
306: icc->info.shiftnz = 0.0;
307: icc->info.shiftpd = 1.0; /* true */
308: icc->info.shift_fraction = 0.0;
309: icc->info.zeropivot = 1.e-12;
310: pc->data = (void*)icc;
312: pc->ops->apply = PCApply_ICC;
313: pc->ops->setup = PCSetup_ICC;
314: pc->ops->destroy = PCDestroy_ICC;
315: pc->ops->setfromoptions = PCSetFromOptions_ICC;
316: pc->ops->view = PCView_ICC;
317: pc->ops->getfactoredmatrix = PCGetFactoredMatrix_ICC;
318: pc->ops->applysymmetricleft = PCApplySymmetricLeft_ICC;
319: pc->ops->applysymmetricright = PCApplySymmetricRight_ICC;
321: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetZeroPivot_C","PCFactorSetZeroPivot_ICC",
322: PCFactorSetZeroPivot_ICC);
323: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftNonzero_C","PCFactorSetShiftNonzero_ICC",
324: PCFactorSetShiftNonzero_ICC);
325: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftPd_C","PCFactorSetShiftPd_ICC",
326: PCFactorSetShiftPd_ICC);
328: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetLevels_C","PCFactorSetLevels_ICC",
329: PCFactorSetLevels_ICC);
330: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetFill_C","PCFactorSetFill_ICC",
331: PCFactorSetFill_ICC);
332: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetMatOrdering_C","PCFactorSetMatOrdering_ICC",
333: PCFactorSetMatOrdering_ICC);
334: return(0);
335: }