Actual source code: icc.c
1: #define PETSCKSP_DLL
3: #include ../src/ksp/pc/impls/factor/icc/icc.h
7: static PetscErrorCode PCSetup_ICC(PC pc)
8: {
9: PC_ICC *icc = (PC_ICC*)pc->data;
10: IS perm,cperm;
12: MatInfo info;
15: MatGetOrdering(pc->pmat, ((PC_Factor*)icc)->ordering,&perm,&cperm);
17: if (!pc->setupcalled) {
18: MatGetFactor(pc->pmat,MAT_SOLVER_PETSC,MAT_FACTOR_ICC,& ((PC_Factor*)icc)->fact);
19: MatICCFactorSymbolic(((PC_Factor*)icc)->fact,pc->pmat,perm,&((PC_Factor*)icc)->info);
20: } else if (pc->flag != SAME_NONZERO_PATTERN) {
21: MatDestroy(((PC_Factor*)icc)->fact);
22: MatGetFactor(pc->pmat,MAT_SOLVER_PETSC,MAT_FACTOR_ICC,&((PC_Factor*)icc)->fact);
23: MatICCFactorSymbolic(((PC_Factor*)icc)->fact,pc->pmat,perm,&((PC_Factor*)icc)->info);
24: }
25: MatGetInfo(((PC_Factor*)icc)->fact,MAT_LOCAL,&info);
26: icc->actualfill = info.fill_ratio_needed;
28: ISDestroy(cperm);
29: ISDestroy(perm);
30: MatCholeskyFactorNumeric(((PC_Factor*)icc)->fact,pc->pmat,&((PC_Factor*)icc)->info);
31: return(0);
32: }
36: static PetscErrorCode PCDestroy_ICC(PC pc)
37: {
38: PC_ICC *icc = (PC_ICC*)pc->data;
42: if (((PC_Factor*)icc)->fact) {MatDestroy(((PC_Factor*)icc)->fact);}
43: PetscStrfree(((PC_Factor*)icc)->ordering);
44: PetscFree(icc);
45: return(0);
46: }
50: static PetscErrorCode PCApply_ICC(PC pc,Vec x,Vec y)
51: {
52: PC_ICC *icc = (PC_ICC*)pc->data;
56: MatSolve(((PC_Factor*)icc)->fact,x,y);
57: return(0);
58: }
62: static PetscErrorCode PCApplySymmetricLeft_ICC(PC pc,Vec x,Vec y)
63: {
65: PC_ICC *icc = (PC_ICC*)pc->data;
68: MatForwardSolve(((PC_Factor*)icc)->fact,x,y);
69: return(0);
70: }
74: static PetscErrorCode PCApplySymmetricRight_ICC(PC pc,Vec x,Vec y)
75: {
77: PC_ICC *icc = (PC_ICC*)pc->data;
80: MatBackwardSolve(((PC_Factor*)icc)->fact,x,y);
81: return(0);
82: }
86: static PetscErrorCode PCSetFromOptions_ICC(PC pc)
87: {
88: PC_ICC *icc = (PC_ICC*)pc->data;
89: char tname[256];
90: PetscTruth flg;
92: PetscFList ordlist;
95: if (!MatOrderingRegisterAllCalled) {MatOrderingRegisterAll(PETSC_NULL);}
96: PetscOptionsHead("ICC Options");
97: PetscOptionsReal("-pc_factor_levels","levels of fill","PCFactorSetLevels",((PC_Factor*)icc)->info.levels,&((PC_Factor*)icc)->info.levels,&flg);
98: PetscOptionsReal("-pc_factor_fill","Expected fill in factorization","PCFactorSetFill",((PC_Factor*)icc)->info.fill,&((PC_Factor*)icc)->info.fill,&flg);
99: MatGetOrderingList(&ordlist);
100: PetscOptionsList("-pc_factor_mat_ordering_type","Reorder to reduce nonzeros in ICC","PCFactorSetMatOrderingType",ordlist,((PC_Factor*)icc)->ordering,tname,256,&flg);
101: if (flg) {
102: PCFactorSetMatOrderingType(pc,tname);
103: }
104: PetscOptionsName("-pc_factor_shift_nonzero","Shift added to diagonal","PCFactorSetShiftNonzero",&flg);
105: if (flg) {
106: PCFactorSetShiftNonzero(pc,(PetscReal)PETSC_DECIDE);
107: }
108: PetscOptionsReal("-pc_factor_shift_nonzero","Shift added to diagonal","PCFactorSetShiftNonzero",((PC_Factor*)icc)->info.shiftnz,&((PC_Factor*)icc)->info.shiftnz,0);
109: flg = (((PC_Factor*)icc)->info.shiftpd > 0.0) ? PETSC_TRUE : PETSC_FALSE;
110: PetscOptionsTruth("-pc_factor_shift_positive_definite","Manteuffel shift applied to diagonal","PCFactorSetShiftPd",flg,&flg,PETSC_NULL);
111: PCFactorSetShiftPd(pc,flg);
112: PetscOptionsReal("-pc_factor_zeropivot","Pivot is considered zero if less than","PCFactorSetZeroPivot",((PC_Factor*)icc)->info.zeropivot,&((PC_Factor*)icc)->info.zeropivot,0);
113:
114: PetscOptionsTail();
115: return(0);
116: }
120: static PetscErrorCode PCView_ICC(PC pc,PetscViewer viewer)
121: {
122: PC_ICC *icc = (PC_ICC*)pc->data;
124: PetscTruth isstring,iascii;
127: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
128: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
129: if (iascii) {
130: if (((PC_Factor*)icc)->info.levels == 1) {
131: PetscViewerASCIIPrintf(viewer," ICC: %D level of fill\n",(PetscInt)((PC_Factor*)icc)->info.levels);
132: } else {
133: PetscViewerASCIIPrintf(viewer," ICC: %D levels of fill\n",(PetscInt)((PC_Factor*)icc)->info.levels);
134: }
135: PetscViewerASCIIPrintf(viewer," ICC: factor fill ratio allocated %G, ordering used %s\n",((PC_Factor*)icc)->info.fill,((PC_Factor*)icc)->ordering);
136: if (((PC_Factor*)icc)->info.shiftpd) {PetscViewerASCIIPrintf(viewer," ICC: using Manteuffel shift\n");}
137: if (((PC_Factor*)icc)->info.shiftnz) {PetscViewerASCIIPrintf(viewer," ICC: using diagonal shift to prevent zero pivot\n");}
138: if (((PC_Factor*)icc)->fact) {
139: PetscViewerASCIIPrintf(viewer," ICC: factor fill ratio needed %G\n",icc->actualfill);
140: PetscViewerASCIIPrintf(viewer," Factored matrix follows\n");
141: PetscViewerASCIIPushTab(viewer);
142: PetscViewerASCIIPushTab(viewer);
143: PetscViewerASCIIPushTab(viewer);
144: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
145: MatView(((PC_Factor*)icc)->fact,viewer);
146: PetscViewerPopFormat(viewer);
147: PetscViewerASCIIPopTab(viewer);
148: PetscViewerASCIIPopTab(viewer);
149: PetscViewerASCIIPopTab(viewer);
150: }
151: } else if (isstring) {
152: PetscViewerStringSPrintf(viewer," lvls=%D",(PetscInt)((PC_Factor*)icc)->info.levels);
153: } else {
154: SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for PCICC",((PetscObject)viewer)->type_name);
155: }
156: return(0);
157: }
159: /*MC
160: PCICC - Incomplete Cholesky factorization preconditioners.
162: Options Database Keys:
163: + -pc_factor_levels <k> - number of levels of fill for ICC(k)
164: . -pc_factor_in_place - only for ICC(0) with natural ordering, reuses the space of the matrix for
165: its factorization (overwrites original matrix)
166: . -pc_factor_fill <nfill> - expected amount of fill in factored matrix compared to original matrix, nfill > 1
167: . -pc_factor_mat_ordering_type <natural,nd,1wd,rcm,qmd> - set the row/column ordering of the factored matrix
168: . -pc_factor_shift_nonzero <shift> - Sets shift amount or PETSC_DECIDE for the default
169: - -pc_factor_shift_positive_definite [PETSC_TRUE/PETSC_FALSE] - Activate/Deactivate PCFactorSetShiftPd(); the value
170: is optional with PETSC_TRUE being the default
172: Level: beginner
174: Concepts: incomplete Cholesky factorization
176: Notes: Only implemented for some matrix formats. Not implemented in parallel (for parallel use you
177: must use MATMPIROWBS, see MatCreateMPIRowbs(), this supports only ICC(0) and this is not recommended
178: unless you really want a parallel ICC).
180: For BAIJ matrices this implements a point block ICC.
182: The Manteuffel shift is only implemented for matrices with block size 1
184: By default, the Manteuffel is applied (for matrices with block size 1). Call PCFactorSetShiftPd(pc,PETSC_FALSE);
185: to turn off the shift.
187: References:
188: Review article: APPROXIMATE AND INCOMPLETE FACTORIZATIONS, TONY F. CHAN AND HENK A. VAN DER VORST
189: http://igitur-archive.library.uu.nl/math/2001-0621-115821/proc.pdf chapter in Parallel Numerical
190: Algorithms, edited by D. Keyes, A. Semah, V. Venkatakrishnan, ICASE/LaRC Interdisciplinary Series in
191: Science and Engineering, Kluwer, pp. 167--202.
194: .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, PCSOR, MatOrderingType,
195: PCFactorSetZeroPivot(), PCFactorSetShiftNonzero(), PCFactorSetShiftPd(),
196: PCFactorSetFill(), PCFactorSetMatOrderingType(), PCFactorSetReuseOrdering(),
197: PCFactorSetLevels(),PCFactorSetShiftNonzero(),PCFactorSetShiftPd(),
199: M*/
204: PetscErrorCode PCCreate_ICC(PC pc)
205: {
207: PC_ICC *icc;
210: PetscNewLog(pc,PC_ICC,&icc);
212: ((PC_Factor*)icc)->fact = 0;
213: PetscStrallocpy(MATORDERING_NATURAL,&((PC_Factor*)icc)->ordering);
214: MatFactorInfoInitialize(&((PC_Factor*)icc)->info);
215: ((PC_Factor*)icc)->info.levels = 0;
216: ((PC_Factor*)icc)->info.fill = 1.0;
217: icc->implctx = 0;
219: ((PC_Factor*)icc)->info.dtcol = PETSC_DEFAULT;
220: ((PC_Factor*)icc)->info.shiftnz = 0.0;
221: ((PC_Factor*)icc)->info.shiftpd = 1.0; /* true */
222: ((PC_Factor*)icc)->info.zeropivot = 1.e-12;
223: pc->data = (void*)icc;
225: pc->ops->apply = PCApply_ICC;
226: pc->ops->setup = PCSetup_ICC;
227: pc->ops->destroy = PCDestroy_ICC;
228: pc->ops->setfromoptions = PCSetFromOptions_ICC;
229: pc->ops->view = PCView_ICC;
230: pc->ops->getfactoredmatrix = PCFactorGetMatrix_Factor;
231: pc->ops->applysymmetricleft = PCApplySymmetricLeft_ICC;
232: pc->ops->applysymmetricright = PCApplySymmetricRight_ICC;
234: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorGetMatSolverPackage_C","PCFactorGetMatSolverPackage_Factor",
235: PCFactorGetMatSolverPackage_Factor);
236: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetZeroPivot_C","PCFactorSetZeroPivot_Factor",
237: PCFactorSetZeroPivot_Factor);
238: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftNonzero_C","PCFactorSetShiftNonzero_Factor",
239: PCFactorSetShiftNonzero_Factor);
240: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftPd_C","PCFactorSetShiftPd_Factor",
241: PCFactorSetShiftPd_Factor);
243: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetLevels_C","PCFactorSetLevels_Factor",
244: PCFactorSetLevels_Factor);
245: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetFill_C","PCFactorSetFill_Factor",
246: PCFactorSetFill_Factor);
247: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetMatOrderingType_C","PCFactorSetMatOrderingType_Factor",
248: PCFactorSetMatOrderingType_Factor);
249: return(0);
250: }