1 2 /* 3 Defines a ILU factorization preconditioner for any Mat implementation 4 */ 5 #include <../src/ksp/pc/impls/factor/ilu/ilu.h> /*I "petscpc.h" I*/ 6 7 /* ------------------------------------------------------------------------------------------*/ 8 #undef __FUNCT__ 9 #define __FUNCT__ "PCFactorSetReuseFill_ILU" 10 PetscErrorCode PCFactorSetReuseFill_ILU(PC pc,PetscBool flag) 11 { 12 PC_ILU *lu = (PC_ILU*)pc->data; 13 14 PetscFunctionBegin; 15 lu->reusefill = flag; 16 PetscFunctionReturn(0); 17 } 18 19 #undef __FUNCT__ 20 #define __FUNCT__ "PCFactorReorderForNonzeroDiagonal_ILU" 21 PetscErrorCode PCFactorReorderForNonzeroDiagonal_ILU(PC pc,PetscReal z) 22 { 23 PC_ILU *ilu = (PC_ILU*)pc->data; 24 25 PetscFunctionBegin; 26 ilu->nonzerosalongdiagonal = PETSC_TRUE; 27 if (z == PETSC_DECIDE) ilu->nonzerosalongdiagonaltol = 1.e-10; 28 else ilu->nonzerosalongdiagonaltol = z; 29 PetscFunctionReturn(0); 30 } 31 32 #undef __FUNCT__ 33 #define __FUNCT__ "PCReset_ILU" 34 PetscErrorCode PCReset_ILU(PC pc) 35 { 36 PC_ILU *ilu = (PC_ILU*)pc->data; 37 PetscErrorCode ierr; 38 39 PetscFunctionBegin; 40 if (!ilu->inplace) {ierr = MatDestroy(&((PC_Factor*)ilu)->fact);CHKERRQ(ierr);} 41 if (ilu->row && ilu->col && ilu->row != ilu->col) {ierr = ISDestroy(&ilu->row);CHKERRQ(ierr);} 42 ierr = ISDestroy(&ilu->col);CHKERRQ(ierr); 43 PetscFunctionReturn(0); 44 } 45 46 #undef __FUNCT__ 47 #define __FUNCT__ "PCFactorSetDropTolerance_ILU" 48 PetscErrorCode PCFactorSetDropTolerance_ILU(PC pc,PetscReal dt,PetscReal dtcol,PetscInt dtcount) 49 { 50 PC_ILU *ilu = (PC_ILU*)pc->data; 51 52 PetscFunctionBegin; 53 if (pc->setupcalled && (((PC_Factor*)ilu)->info.dt != dt || ((PC_Factor*)ilu)->info.dtcol != dtcol || ((PC_Factor*)ilu)->info.dtcount != dtcount)) { 54 SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot change drop tolerance after using PC"); 55 } 56 ((PC_Factor*)ilu)->info.dt = dt; 57 ((PC_Factor*)ilu)->info.dtcol = dtcol; 58 ((PC_Factor*)ilu)->info.dtcount = dtcount; 59 ((PC_Factor*)ilu)->info.usedt = 1.0; 60 PetscFunctionReturn(0); 61 } 62 63 #undef __FUNCT__ 64 #define __FUNCT__ "PCFactorSetReuseOrdering_ILU" 65 PetscErrorCode PCFactorSetReuseOrdering_ILU(PC pc,PetscBool flag) 66 { 67 PC_ILU *ilu = (PC_ILU*)pc->data; 68 69 PetscFunctionBegin; 70 ilu->reuseordering = flag; 71 PetscFunctionReturn(0); 72 } 73 74 #undef __FUNCT__ 75 #define __FUNCT__ "PCFactorSetUseInPlace_ILU" 76 PetscErrorCode PCFactorSetUseInPlace_ILU(PC pc) 77 { 78 PC_ILU *dir = (PC_ILU*)pc->data; 79 80 PetscFunctionBegin; 81 dir->inplace = PETSC_TRUE; 82 PetscFunctionReturn(0); 83 } 84 85 #undef __FUNCT__ 86 #define __FUNCT__ "PCSetFromOptions_ILU" 87 static PetscErrorCode PCSetFromOptions_ILU(PC pc) 88 { 89 PetscErrorCode ierr; 90 PetscInt itmp; 91 PetscBool flg; 92 PC_ILU *ilu = (PC_ILU*)pc->data; 93 PetscReal tol; 94 /* PetscReal dt[3]; */ 95 96 PetscFunctionBegin; 97 ierr = PetscOptionsHead("ILU Options");CHKERRQ(ierr); 98 ierr = PCSetFromOptions_Factor(pc);CHKERRQ(ierr); 99 100 ierr = PetscOptionsInt("-pc_factor_levels","levels of fill","PCFactorSetLevels",(PetscInt)((PC_Factor*)ilu)->info.levels,&itmp,&flg);CHKERRQ(ierr); 101 if (flg) ((PC_Factor*)ilu)->info.levels = itmp; 102 103 flg = PETSC_FALSE; 104 ierr = PetscOptionsBool("-pc_factor_diagonal_fill","Allow fill into empty diagonal entry","PCFactorSetAllowDiagonalFill",flg,&flg,NULL);CHKERRQ(ierr); 105 ((PC_Factor*)ilu)->info.diagonal_fill = (PetscReal) flg; 106 /* 107 dt[0] = ((PC_Factor*)ilu)->info.dt; 108 dt[1] = ((PC_Factor*)ilu)->info.dtcol; 109 dt[2] = ((PC_Factor*)ilu)->info.dtcount; 110 111 PetscInt dtmax = 3; 112 ierr = PetscOptionsRealArray("-pc_factor_drop_tolerance,","<dt,dtcol,maxrowcount>","PCFactorSetDropTolerance",dt,&dtmax,&flg);CHKERRQ(ierr); 113 if (flg) { 114 ierr = PCFactorSetDropTolerance(pc,dt[0],dt[1],(PetscInt)dt[2]);CHKERRQ(ierr); 115 } 116 */ 117 ierr = PetscOptionsName("-pc_factor_nonzeros_along_diagonal","Reorder to remove zeros from diagonal","PCFactorReorderForNonzeroDiagonal",&flg);CHKERRQ(ierr); 118 if (flg) { 119 tol = PETSC_DECIDE; 120 ierr = PetscOptionsReal("-pc_factor_nonzeros_along_diagonal","Reorder to remove zeros from diagonal","PCFactorReorderForNonzeroDiagonal",ilu->nonzerosalongdiagonaltol,&tol,0);CHKERRQ(ierr); 121 ierr = PCFactorReorderForNonzeroDiagonal(pc,tol);CHKERRQ(ierr); 122 } 123 124 ierr = PetscOptionsTail();CHKERRQ(ierr); 125 PetscFunctionReturn(0); 126 } 127 128 #undef __FUNCT__ 129 #define __FUNCT__ "PCView_ILU" 130 static PetscErrorCode PCView_ILU(PC pc,PetscViewer viewer) 131 { 132 PC_ILU *ilu = (PC_ILU*)pc->data; 133 PetscErrorCode ierr; 134 PetscBool iascii; 135 136 PetscFunctionBegin; 137 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 138 if (iascii) { 139 if (ilu->inplace) { 140 ierr = PetscViewerASCIIPrintf(viewer," ILU: in-place factorization\n");CHKERRQ(ierr); 141 } else { 142 ierr = PetscViewerASCIIPrintf(viewer," ILU: out-of-place factorization\n");CHKERRQ(ierr); 143 } 144 145 if (ilu->reusefill) {ierr = PetscViewerASCIIPrintf(viewer," ILU: Reusing fill from past factorization\n");CHKERRQ(ierr);} 146 if (ilu->reuseordering) {ierr = PetscViewerASCIIPrintf(viewer," ILU: Reusing reordering from past factorization\n");CHKERRQ(ierr);} 147 } 148 ierr = PCView_Factor(pc,viewer);CHKERRQ(ierr); 149 PetscFunctionReturn(0); 150 } 151 152 #undef __FUNCT__ 153 #define __FUNCT__ "PCSetUp_ILU" 154 static PetscErrorCode PCSetUp_ILU(PC pc) 155 { 156 PetscErrorCode ierr; 157 PC_ILU *ilu = (PC_ILU*)pc->data; 158 MatInfo info; 159 PetscBool flg; 160 161 PetscFunctionBegin; 162 /* ugly hack to change default, since it is not support by some matrix types */ 163 if (((PC_Factor*)ilu)->info.shifttype == (PetscReal)MAT_SHIFT_NONZERO) { 164 ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATSEQAIJ,&flg);CHKERRQ(ierr); 165 if (!flg) { 166 ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATMPIAIJ,&flg);CHKERRQ(ierr); 167 if (!flg) { 168 ((PC_Factor*)ilu)->info.shifttype = (PetscReal)MAT_SHIFT_INBLOCKS; 169 PetscInfo(pc,"Changing shift type from NONZERO to INBLOCKS because block matrices do not support NONZERO");CHKERRQ(ierr); 170 } 171 } 172 } 173 174 if (ilu->inplace) { 175 if (!pc->setupcalled) { 176 177 /* In-place factorization only makes sense with the natural ordering, 178 so we only need to get the ordering once, even if nonzero structure changes */ 179 ierr = MatGetOrdering(pc->pmat,((PC_Factor*)ilu)->ordering,&ilu->row,&ilu->col);CHKERRQ(ierr); 180 if (ilu->row) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->row);CHKERRQ(ierr);} 181 if (ilu->col) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->col);CHKERRQ(ierr);} 182 } 183 184 /* In place ILU only makes sense with fill factor of 1.0 because 185 cannot have levels of fill */ 186 ((PC_Factor*)ilu)->info.fill = 1.0; 187 ((PC_Factor*)ilu)->info.diagonal_fill = 0.0; 188 189 ierr = MatILUFactor(pc->pmat,ilu->row,ilu->col,&((PC_Factor*)ilu)->info);CHKERRQ(ierr);CHKERRQ(ierr); 190 ((PC_Factor*)ilu)->fact = pc->pmat; 191 } else { 192 if (!pc->setupcalled) { 193 /* first time in so compute reordering and symbolic factorization */ 194 ierr = MatGetOrdering(pc->pmat,((PC_Factor*)ilu)->ordering,&ilu->row,&ilu->col);CHKERRQ(ierr); 195 if (ilu->row) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->row);CHKERRQ(ierr);} 196 if (ilu->col) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->col);CHKERRQ(ierr);} 197 /* Remove zeros along diagonal? */ 198 if (ilu->nonzerosalongdiagonal) { 199 ierr = MatReorderForNonzeroDiagonal(pc->pmat,ilu->nonzerosalongdiagonaltol,ilu->row,ilu->col);CHKERRQ(ierr); 200 } 201 if (!((PC_Factor*)ilu)->fact) { 202 ierr = MatGetFactor(pc->pmat,((PC_Factor*)ilu)->solvertype,MAT_FACTOR_ILU,&((PC_Factor*)ilu)->fact);CHKERRQ(ierr); 203 } 204 ierr = MatILUFactorSymbolic(((PC_Factor*)ilu)->fact,pc->pmat,ilu->row,ilu->col,&((PC_Factor*)ilu)->info);CHKERRQ(ierr); 205 ierr = MatGetInfo(((PC_Factor*)ilu)->fact,MAT_LOCAL,&info);CHKERRQ(ierr); 206 207 ilu->actualfill = info.fill_ratio_needed; 208 209 ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)((PC_Factor*)ilu)->fact);CHKERRQ(ierr); 210 } else if (pc->flag != SAME_NONZERO_PATTERN) { 211 if (!ilu->reuseordering) { 212 /* compute a new ordering for the ILU */ 213 ierr = ISDestroy(&ilu->row);CHKERRQ(ierr); 214 ierr = ISDestroy(&ilu->col);CHKERRQ(ierr); 215 ierr = MatGetOrdering(pc->pmat,((PC_Factor*)ilu)->ordering,&ilu->row,&ilu->col);CHKERRQ(ierr); 216 if (ilu->row) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->row);CHKERRQ(ierr);} 217 if (ilu->col) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->col);CHKERRQ(ierr);} 218 /* Remove zeros along diagonal? */ 219 if (ilu->nonzerosalongdiagonal) { 220 ierr = MatReorderForNonzeroDiagonal(pc->pmat,ilu->nonzerosalongdiagonaltol,ilu->row,ilu->col);CHKERRQ(ierr); 221 } 222 } 223 ierr = MatDestroy(&((PC_Factor*)ilu)->fact);CHKERRQ(ierr); 224 ierr = MatGetFactor(pc->pmat,((PC_Factor*)ilu)->solvertype,MAT_FACTOR_ILU,&((PC_Factor*)ilu)->fact);CHKERRQ(ierr); 225 ierr = MatILUFactorSymbolic(((PC_Factor*)ilu)->fact,pc->pmat,ilu->row,ilu->col,&((PC_Factor*)ilu)->info);CHKERRQ(ierr); 226 ierr = MatGetInfo(((PC_Factor*)ilu)->fact,MAT_LOCAL,&info);CHKERRQ(ierr); 227 228 ilu->actualfill = info.fill_ratio_needed; 229 230 ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)((PC_Factor*)ilu)->fact);CHKERRQ(ierr); 231 } 232 ierr = MatLUFactorNumeric(((PC_Factor*)ilu)->fact,pc->pmat,&((PC_Factor*)ilu)->info);CHKERRQ(ierr); 233 } 234 PetscFunctionReturn(0); 235 } 236 237 #undef __FUNCT__ 238 #define __FUNCT__ "PCDestroy_ILU" 239 static PetscErrorCode PCDestroy_ILU(PC pc) 240 { 241 PC_ILU *ilu = (PC_ILU*)pc->data; 242 PetscErrorCode ierr; 243 244 PetscFunctionBegin; 245 ierr = PCReset_ILU(pc);CHKERRQ(ierr); 246 ierr = PetscFree(((PC_Factor*)ilu)->solvertype);CHKERRQ(ierr); 247 ierr = PetscFree(((PC_Factor*)ilu)->ordering);CHKERRQ(ierr); 248 ierr = PetscFree(pc->data);CHKERRQ(ierr); 249 PetscFunctionReturn(0); 250 } 251 252 #undef __FUNCT__ 253 #define __FUNCT__ "PCApply_ILU" 254 static PetscErrorCode PCApply_ILU(PC pc,Vec x,Vec y) 255 { 256 PC_ILU *ilu = (PC_ILU*)pc->data; 257 PetscErrorCode ierr; 258 259 PetscFunctionBegin; 260 ierr = MatSolve(((PC_Factor*)ilu)->fact,x,y);CHKERRQ(ierr); 261 PetscFunctionReturn(0); 262 } 263 264 #undef __FUNCT__ 265 #define __FUNCT__ "PCApplyTranspose_ILU" 266 static PetscErrorCode PCApplyTranspose_ILU(PC pc,Vec x,Vec y) 267 { 268 PC_ILU *ilu = (PC_ILU*)pc->data; 269 PetscErrorCode ierr; 270 271 PetscFunctionBegin; 272 ierr = MatSolveTranspose(((PC_Factor*)ilu)->fact,x,y);CHKERRQ(ierr); 273 PetscFunctionReturn(0); 274 } 275 276 #undef __FUNCT__ 277 #define __FUNCT__ "PCApplySymmetricLeft_ILU" 278 static PetscErrorCode PCApplySymmetricLeft_ILU(PC pc,Vec x,Vec y) 279 { 280 PetscErrorCode ierr; 281 PC_ILU *icc = (PC_ILU*)pc->data; 282 283 PetscFunctionBegin; 284 ierr = MatForwardSolve(((PC_Factor*)icc)->fact,x,y);CHKERRQ(ierr); 285 PetscFunctionReturn(0); 286 } 287 288 #undef __FUNCT__ 289 #define __FUNCT__ "PCApplySymmetricRight_ILU" 290 static PetscErrorCode PCApplySymmetricRight_ILU(PC pc,Vec x,Vec y) 291 { 292 PetscErrorCode ierr; 293 PC_ILU *icc = (PC_ILU*)pc->data; 294 295 PetscFunctionBegin; 296 ierr = MatBackwardSolve(((PC_Factor*)icc)->fact,x,y);CHKERRQ(ierr); 297 PetscFunctionReturn(0); 298 } 299 300 /*MC 301 PCILU - Incomplete factorization preconditioners. 302 303 Options Database Keys: 304 + -pc_factor_levels <k> - number of levels of fill for ILU(k) 305 . -pc_factor_in_place - only for ILU(0) with natural ordering, reuses the space of the matrix for 306 its factorization (overwrites original matrix) 307 . -pc_factor_diagonal_fill - fill in a zero diagonal even if levels of fill indicate it wouldn't be fill 308 . -pc_factor_reuse_ordering - reuse ordering of factorized matrix from previous factorization 309 . -pc_factor_fill <nfill> - expected amount of fill in factored matrix compared to original matrix, nfill > 1 310 . -pc_factor_nonzeros_along_diagonal - reorder the matrix before factorization to remove zeros from the diagonal, 311 this decreases the chance of getting a zero pivot 312 . -pc_factor_mat_ordering_type <natural,nd,1wd,rcm,qmd> - set the row/column ordering of the factored matrix 313 . -pc_factor_pivot_in_blocks - for block ILU(k) factorization, i.e. with BAIJ matrices with block size larger 314 than 1 the diagonal blocks are factored with partial pivoting (this increases the 315 stability of the ILU factorization 316 317 Level: beginner 318 319 Concepts: incomplete factorization 320 321 Notes: Only implemented for some matrix formats. (for parallel see PCHYPRE for hypre's ILU) 322 323 For BAIJ matrices this implements a point block ILU 324 325 The "symmetric" application of this preconditioner is not actually symmetric since L is not transpose(U) 326 even when the matrix is not symmetric since the U stores the diagonals of the factorization. 327 328 If you are using MATSEQAIJCUSPARSE matrices (or MATMPIAIJCUSPARESE matrices with block Jacobi), factorization 329 is never done on the GPU). 330 331 References: 332 T. Dupont, R. Kendall, and H. Rachford. An approximate factorization procedure for solving 333 self-adjoint elliptic difference equations. SIAM J. Numer. Anal., 5:559--573, 1968. 334 335 T.A. Oliphant. An implicit numerical method for solving two-dimensional time-dependent dif- 336 fusion problems. Quart. Appl. Math., 19:221--229, 1961. 337 338 Review article: APPROXIMATE AND INCOMPLETE FACTORIZATIONS, TONY F. CHAN AND HENK A. VAN DER VORST 339 http://igitur-archive.library.uu.nl/math/2001-0621-115821/proc.pdf chapter in Parallel Numerical 340 Algorithms, edited by D. Keyes, A. Semah, V. Venkatakrishnan, ICASE/LaRC Interdisciplinary Series in 341 Science and Engineering, Kluwer, pp. 167--202. 342 343 344 .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, PCSOR, MatOrderingType, 345 PCFactorSetZeroPivot(), PCFactorSetShiftSetType(), PCFactorSetAmount(), 346 PCFactorSetDropTolerance(),PCFactorSetFill(), PCFactorSetMatOrderingType(), PCFactorSetReuseOrdering(), 347 PCFactorSetLevels(), PCFactorSetUseInPlace(), PCFactorSetAllowDiagonalFill(), PCFactorSetPivotInBlocks() 348 349 M*/ 350 351 #undef __FUNCT__ 352 #define __FUNCT__ "PCCreate_ILU" 353 PETSC_EXTERN PetscErrorCode PCCreate_ILU(PC pc) 354 { 355 PetscErrorCode ierr; 356 PC_ILU *ilu; 357 358 PetscFunctionBegin; 359 ierr = PetscNewLog(pc,&ilu);CHKERRQ(ierr); 360 361 ((PC_Factor*)ilu)->fact = 0; 362 ierr = MatFactorInfoInitialize(&((PC_Factor*)ilu)->info);CHKERRQ(ierr); 363 ((PC_Factor*)ilu)->factortype = MAT_FACTOR_ILU; 364 ((PC_Factor*)ilu)->info.levels = 0.; 365 ((PC_Factor*)ilu)->info.fill = 1.0; 366 ilu->col = 0; 367 ilu->row = 0; 368 ilu->inplace = PETSC_FALSE; 369 ierr = PetscStrallocpy(MATSOLVERPETSC,&((PC_Factor*)ilu)->solvertype);CHKERRQ(ierr); 370 ierr = PetscStrallocpy(MATORDERINGNATURAL,(char**)&((PC_Factor*)ilu)->ordering);CHKERRQ(ierr); 371 ilu->reuseordering = PETSC_FALSE; 372 ((PC_Factor*)ilu)->info.dt = PETSC_DEFAULT; 373 ((PC_Factor*)ilu)->info.dtcount = PETSC_DEFAULT; 374 ((PC_Factor*)ilu)->info.dtcol = PETSC_DEFAULT; 375 ((PC_Factor*)ilu)->info.shifttype = (PetscReal)MAT_SHIFT_INBLOCKS; 376 ((PC_Factor*)ilu)->info.shiftamount = 100.0*PETSC_MACHINE_EPSILON; 377 ((PC_Factor*)ilu)->info.zeropivot = 100.0*PETSC_MACHINE_EPSILON; 378 ((PC_Factor*)ilu)->info.pivotinblocks = 1.0; 379 ilu->reusefill = PETSC_FALSE; 380 ((PC_Factor*)ilu)->info.diagonal_fill = 0.0; 381 pc->data = (void*)ilu; 382 383 pc->ops->reset = PCReset_ILU; 384 pc->ops->destroy = PCDestroy_ILU; 385 pc->ops->apply = PCApply_ILU; 386 pc->ops->applytranspose = PCApplyTranspose_ILU; 387 pc->ops->setup = PCSetUp_ILU; 388 pc->ops->setfromoptions = PCSetFromOptions_ILU; 389 pc->ops->getfactoredmatrix = PCFactorGetMatrix_Factor; 390 pc->ops->view = PCView_ILU; 391 pc->ops->applysymmetricleft = PCApplySymmetricLeft_ILU; 392 pc->ops->applysymmetricright = PCApplySymmetricRight_ILU; 393 pc->ops->applyrichardson = 0; 394 395 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCFactorSetZeroPivot_C",PCFactorSetZeroPivot_Factor);CHKERRQ(ierr); 396 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCFactorSetShiftType_C",PCFactorSetShiftType_Factor);CHKERRQ(ierr); 397 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCFactorSetShiftAmount_C",PCFactorSetShiftAmount_Factor);CHKERRQ(ierr); 398 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCFactorGetMatSolverPackage_C",PCFactorGetMatSolverPackage_Factor);CHKERRQ(ierr); 399 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCFactorSetMatSolverPackage_C",PCFactorSetMatSolverPackage_Factor);CHKERRQ(ierr); 400 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCFactorSetUpMatSolverPackage_C",PCFactorSetUpMatSolverPackage_Factor);CHKERRQ(ierr); 401 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCFactorSetDropTolerance_C",PCFactorSetDropTolerance_ILU);CHKERRQ(ierr); 402 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCFactorSetFill_C",PCFactorSetFill_Factor);CHKERRQ(ierr); 403 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCFactorSetMatOrderingType_C",PCFactorSetMatOrderingType_Factor);CHKERRQ(ierr); 404 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCFactorSetReuseOrdering_C",PCFactorSetReuseOrdering_ILU);CHKERRQ(ierr); 405 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCFactorSetReuseFill_C",PCFactorSetReuseFill_ILU);CHKERRQ(ierr); 406 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCFactorSetLevels_C",PCFactorSetLevels_Factor);CHKERRQ(ierr); 407 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCFactorGetLevels_C",PCFactorGetLevels_Factor);CHKERRQ(ierr); 408 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCFactorSetUseInPlace_C",PCFactorSetUseInPlace_ILU);CHKERRQ(ierr); 409 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCFactorSetAllowDiagonalFill_C",PCFactorSetAllowDiagonalFill_Factor);CHKERRQ(ierr); 410 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCFactorSetPivotInBlocks_C",PCFactorSetPivotInBlocks_Factor);CHKERRQ(ierr); 411 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCFactorReorderForNonzeroDiagonal_C",PCFactorReorderForNonzeroDiagonal_ILU);CHKERRQ(ierr); 412 PetscFunctionReturn(0); 413 } 414