1 /* 2 Defines a ILU factorization preconditioner for any Mat implementation 3 */ 4 #include "src/ksp/pc/pcimpl.h" /*I "petscpc.h" I*/ 5 #include "src/ksp/pc/impls/factor/ilu/ilu.h" 6 #include "src/mat/matimpl.h" 7 8 /* ------------------------------------------------------------------------------------------*/ 9 10 EXTERN_C_BEGIN 11 #undef __FUNCT__ 12 #define __FUNCT__ "PCILUReorderForNonzeroDiagonal_ILU" 13 PetscErrorCode PCILUReorderForNonzeroDiagonal_ILU(PC pc,PetscReal z) 14 { 15 PC_ILU *ilu = (PC_ILU*)pc->data; 16 17 PetscFunctionBegin; 18 ilu->nonzerosalongdiagonal = PETSC_TRUE; 19 if (z == PETSC_DECIDE) { 20 ilu->nonzerosalongdiagonaltol = 1.e-10; 21 } else { 22 ilu->nonzerosalongdiagonaltol = z; 23 } 24 PetscFunctionReturn(0); 25 } 26 EXTERN_C_END 27 28 EXTERN_C_BEGIN 29 #undef __FUNCT__ 30 #define __FUNCT__ "PCILUSetSetZeroPivot_ILU" 31 PetscErrorCode PCILUSetZeroPivot_ILU(PC pc,PetscReal z) 32 { 33 PC_ILU *lu; 34 35 PetscFunctionBegin; 36 lu = (PC_ILU*)pc->data; 37 lu->info.zeropivot = z; 38 PetscFunctionReturn(0); 39 } 40 EXTERN_C_END 41 42 #undef __FUNCT__ 43 #define __FUNCT__ "PCDestroy_ILU_Internal" 44 PetscErrorCode PCDestroy_ILU_Internal(PC pc) 45 { 46 PC_ILU *ilu = (PC_ILU*)pc->data; 47 PetscErrorCode ierr; 48 49 PetscFunctionBegin; 50 if (!ilu->inplace && ilu->fact) {ierr = MatDestroy(ilu->fact);CHKERRQ(ierr);} 51 if (ilu->row && ilu->col && ilu->row != ilu->col) {ierr = ISDestroy(ilu->row);CHKERRQ(ierr);} 52 if (ilu->col) {ierr = ISDestroy(ilu->col);CHKERRQ(ierr);} 53 PetscFunctionReturn(0); 54 } 55 56 EXTERN_C_BEGIN 57 #undef __FUNCT__ 58 #define __FUNCT__ "PCILUSetDamping_ILU" 59 PetscErrorCode PCILUSetDamping_ILU(PC pc,PetscReal damping) 60 { 61 PC_ILU *dir; 62 63 PetscFunctionBegin; 64 dir = (PC_ILU*)pc->data; 65 if (damping == (PetscReal) PETSC_DECIDE) { 66 dir->info.damping = 1.e-12; 67 } else { 68 dir->info.damping = damping; 69 } 70 PetscFunctionReturn(0); 71 } 72 EXTERN_C_END 73 74 EXTERN_C_BEGIN 75 #undef __FUNCT__ 76 #define __FUNCT__ "PCILUSetShift_ILU" 77 PetscErrorCode PCILUSetShift_ILU(PC pc,PetscTruth shift) 78 { 79 PC_ILU *dir; 80 81 PetscFunctionBegin; 82 dir = (PC_ILU*)pc->data; 83 dir->info.shift = shift; 84 if (shift) dir->info.shift_fraction = 0.0; 85 PetscFunctionReturn(0); 86 } 87 EXTERN_C_END 88 89 EXTERN_C_BEGIN 90 #undef __FUNCT__ 91 #define __FUNCT__ "PCILUSetUseDropTolerance_ILU" 92 PetscErrorCode PCILUSetUseDropTolerance_ILU(PC pc,PetscReal dt,PetscReal dtcol,PetscInt dtcount) 93 { 94 PC_ILU *ilu; 95 PetscErrorCode ierr; 96 97 PetscFunctionBegin; 98 ilu = (PC_ILU*)pc->data; 99 if (pc->setupcalled && (!ilu->usedt || ilu->info.dt != dt || ilu->info.dtcol != dtcol || ilu->info.dtcount != dtcount)) { 100 pc->setupcalled = 0; 101 ierr = PCDestroy_ILU_Internal(pc);CHKERRQ(ierr); 102 } 103 ilu->usedt = PETSC_TRUE; 104 ilu->info.dt = dt; 105 ilu->info.dtcol = dtcol; 106 ilu->info.dtcount = dtcount; 107 ilu->info.fill = PETSC_DEFAULT; 108 PetscFunctionReturn(0); 109 } 110 EXTERN_C_END 111 112 EXTERN_C_BEGIN 113 #undef __FUNCT__ 114 #define __FUNCT__ "PCILUSetFill_ILU" 115 PetscErrorCode PCILUSetFill_ILU(PC pc,PetscReal fill) 116 { 117 PC_ILU *dir; 118 119 PetscFunctionBegin; 120 dir = (PC_ILU*)pc->data; 121 dir->info.fill = fill; 122 PetscFunctionReturn(0); 123 } 124 EXTERN_C_END 125 126 EXTERN_C_BEGIN 127 #undef __FUNCT__ 128 #define __FUNCT__ "PCILUSetMatOrdering_ILU" 129 PetscErrorCode PCILUSetMatOrdering_ILU(PC pc,MatOrderingType ordering) 130 { 131 PC_ILU *dir = (PC_ILU*)pc->data; 132 PetscErrorCode ierr; 133 PetscTruth flg; 134 135 PetscFunctionBegin; 136 if (!pc->setupcalled) { 137 ierr = PetscStrfree(dir->ordering);CHKERRQ(ierr); 138 ierr = PetscStrallocpy(ordering,&dir->ordering);CHKERRQ(ierr); 139 } else { 140 ierr = PetscStrcmp(dir->ordering,ordering,&flg);CHKERRQ(ierr); 141 if (!flg) { 142 pc->setupcalled = 0; 143 ierr = PetscStrfree(dir->ordering);CHKERRQ(ierr); 144 ierr = PetscStrallocpy(ordering,&dir->ordering);CHKERRQ(ierr); 145 /* free the data structures, then create them again */ 146 ierr = PCDestroy_ILU_Internal(pc);CHKERRQ(ierr); 147 } 148 } 149 PetscFunctionReturn(0); 150 } 151 EXTERN_C_END 152 153 EXTERN_C_BEGIN 154 #undef __FUNCT__ 155 #define __FUNCT__ "PCILUSetReuseOrdering_ILU" 156 PetscErrorCode PCILUSetReuseOrdering_ILU(PC pc,PetscTruth flag) 157 { 158 PC_ILU *ilu; 159 160 PetscFunctionBegin; 161 ilu = (PC_ILU*)pc->data; 162 ilu->reuseordering = flag; 163 PetscFunctionReturn(0); 164 } 165 EXTERN_C_END 166 167 EXTERN_C_BEGIN 168 #undef __FUNCT__ 169 #define __FUNCT__ "PCILUDTSetReuseFill_ILUDT" 170 PetscErrorCode PCILUDTSetReuseFill_ILUDT(PC pc,PetscTruth flag) 171 { 172 PC_ILU *ilu; 173 174 PetscFunctionBegin; 175 ilu = (PC_ILU*)pc->data; 176 ilu->reusefill = flag; 177 if (flag) SETERRQ(PETSC_ERR_SUP,"Not yet supported"); 178 PetscFunctionReturn(0); 179 } 180 EXTERN_C_END 181 182 EXTERN_C_BEGIN 183 #undef __FUNCT__ 184 #define __FUNCT__ "PCILUSetLevels_ILU" 185 PetscErrorCode PCILUSetLevels_ILU(PC pc,PetscInt levels) 186 { 187 PC_ILU *ilu; 188 PetscErrorCode ierr; 189 190 PetscFunctionBegin; 191 ilu = (PC_ILU*)pc->data; 192 193 if (!pc->setupcalled) { 194 ilu->info.levels = levels; 195 } else if (ilu->usedt || ilu->info.levels != levels) { 196 ilu->info.levels = levels; 197 pc->setupcalled = 0; 198 ilu->usedt = PETSC_FALSE; 199 ierr = PCDestroy_ILU_Internal(pc);CHKERRQ(ierr); 200 } 201 PetscFunctionReturn(0); 202 } 203 EXTERN_C_END 204 205 EXTERN_C_BEGIN 206 #undef __FUNCT__ 207 #define __FUNCT__ "PCILUSetUseInPlace_ILU" 208 PetscErrorCode PCILUSetUseInPlace_ILU(PC pc) 209 { 210 PC_ILU *dir; 211 212 PetscFunctionBegin; 213 dir = (PC_ILU*)pc->data; 214 dir->inplace = PETSC_TRUE; 215 PetscFunctionReturn(0); 216 } 217 EXTERN_C_END 218 219 EXTERN_C_BEGIN 220 #undef __FUNCT__ 221 #define __FUNCT__ "PCILUSetAllowDiagonalFill" 222 PetscErrorCode PCILUSetAllowDiagonalFill_ILU(PC pc) 223 { 224 PC_ILU *dir; 225 226 PetscFunctionBegin; 227 dir = (PC_ILU*)pc->data; 228 dir->info.diagonal_fill = 1; 229 PetscFunctionReturn(0); 230 } 231 EXTERN_C_END 232 233 #undef __FUNCT__ 234 #define __FUNCT__ "PCILUSetZeroPivot" 235 /*@ 236 PCILUSetZeroPivot - Sets the size at which smaller pivots are declared to be zero 237 238 Collective on PC 239 240 Input Parameters: 241 + pc - the preconditioner context 242 - zero - all pivots smaller than this will be considered zero 243 244 Options Database Key: 245 . -pc_ilu_zeropivot <zero> - Sets the zero pivot size 246 247 Level: intermediate 248 249 .keywords: PC, set, factorization, direct, fill 250 251 .seealso: PCILUSetFill(), PCLUSetDamp(), PCLUSetZeroPivot() 252 @*/ 253 PetscErrorCode PCILUSetZeroPivot(PC pc,PetscReal zero) 254 { 255 PetscErrorCode ierr,(*f)(PC,PetscReal); 256 257 PetscFunctionBegin; 258 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 259 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCILUSetZeroPivot_C",(void (**)(void))&f);CHKERRQ(ierr); 260 if (f) { 261 ierr = (*f)(pc,zero);CHKERRQ(ierr); 262 } 263 PetscFunctionReturn(0); 264 } 265 266 #undef __FUNCT__ 267 #define __FUNCT__ "PCILUSetDamping" 268 /*@ 269 PCILUSetDamping - adds this quantity to the diagonal of the matrix during the 270 ILU numerical factorization 271 272 Collective on PC 273 274 Input Parameters: 275 + pc - the preconditioner context 276 - damping - amount of damping 277 278 Options Database Key: 279 . -pc_ilu_damping <damping> - Sets damping amount or PETSC_DECIDE for the default 280 281 Note: If 0.0 is given, then no damping is used. If a diagonal element is classified as a zero 282 pivot, then the damping is doubled until this is alleviated. 283 284 Level: intermediate 285 286 .keywords: PC, set, factorization, direct, fill 287 288 .seealso: PCILUSetFill(), PCLUSetDamping(), PCILUSetShift() 289 @*/ 290 PetscErrorCode PCILUSetDamping(PC pc,PetscReal damping) 291 { 292 PetscErrorCode ierr,(*f)(PC,PetscReal); 293 294 PetscFunctionBegin; 295 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 296 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCILUSetDamping_C",(void (**)(void))&f);CHKERRQ(ierr); 297 if (f) { 298 ierr = (*f)(pc,damping);CHKERRQ(ierr); 299 } 300 PetscFunctionReturn(0); 301 } 302 303 #undef __FUNCT__ 304 #define __FUNCT__ "PCILUSetShift" 305 /*@ 306 PCILUSetShift - specify whether to use Manteuffel shifting of ILU. 307 If an ILU factorisation breaks down because of nonpositive pivots, 308 adding sufficient identity to the diagonal will remedy this. 309 Setting this causes a bisection method to find the minimum shift that 310 will lead to a well-defined ILU. 311 312 Input parameters: 313 + pc - the preconditioner context 314 - shifting - PETSC_TRUE to set shift else PETSC_FALSE 315 316 Options Database Key: 317 . -pc_ilu_shift [1/0] - Activate/Deactivate PCILUSetShift(); the value 318 is optional with 1 being the default 319 320 Level: intermediate 321 322 .keywords: PC, indefinite, factorization, incomplete, ILU 323 324 .seealso: PCILUSetDamping() 325 @*/ 326 PetscErrorCode PCILUSetShift(PC pc,PetscTruth shifting) 327 { 328 PetscErrorCode ierr,(*f)(PC,PetscTruth); 329 330 PetscFunctionBegin; 331 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 332 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCILUSetShift_C",(void (**)(void))&f);CHKERRQ(ierr); 333 if (f) { 334 ierr = (*f)(pc,shifting);CHKERRQ(ierr); 335 } 336 PetscFunctionReturn(0); 337 } 338 339 340 #undef __FUNCT__ 341 #define __FUNCT__ "PCILUSetUseDropTolerance" 342 /*@ 343 PCILUSetUseDropTolerance - The preconditioner will use an ILU 344 based on a drop tolerance. 345 346 Collective on PC 347 348 Input Parameters: 349 + pc - the preconditioner context 350 . dt - the drop tolerance, try from 1.e-10 to .1 351 . dtcol - tolerance for column pivot, good values [0.1 to 0.01] 352 - maxrowcount - the max number of nonzeros allowed in a row, best value 353 depends on the number of nonzeros in row of original matrix 354 355 Options Database Key: 356 . -pc_ilu_use_drop_tolerance <dt,dtcol,maxrowcount> - Sets drop tolerance 357 358 Level: intermediate 359 360 Notes: 361 This uses the iludt() code of Saad's SPARSKIT package 362 363 .keywords: PC, levels, reordering, factorization, incomplete, ILU 364 @*/ 365 PetscErrorCode PCILUSetUseDropTolerance(PC pc,PetscReal dt,PetscReal dtcol,PetscInt maxrowcount) 366 { 367 PetscErrorCode ierr,(*f)(PC,PetscReal,PetscReal,PetscInt); 368 369 PetscFunctionBegin; 370 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 371 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCILUSetUseDropTolerance_C",(void (**)(void))&f);CHKERRQ(ierr); 372 if (f) { 373 ierr = (*f)(pc,dt,dtcol,maxrowcount);CHKERRQ(ierr); 374 } 375 PetscFunctionReturn(0); 376 } 377 378 #undef __FUNCT__ 379 #define __FUNCT__ "PCILUSetFill" 380 /*@ 381 PCILUSetFill - Indicate the amount of fill you expect in the factored matrix, 382 where fill = number nonzeros in factor/number nonzeros in original matrix. 383 384 Collective on PC 385 386 Input Parameters: 387 + pc - the preconditioner context 388 - fill - amount of expected fill 389 390 Options Database Key: 391 $ -pc_ilu_fill <fill> 392 393 Note: 394 For sparse matrix factorizations it is difficult to predict how much 395 fill to expect. By running with the option -log_info PETSc will print the 396 actual amount of fill used; allowing you to set the value accurately for 397 future runs. But default PETSc uses a value of 1.0 398 399 Level: intermediate 400 401 .keywords: PC, set, factorization, direct, fill 402 403 .seealso: PCLUSetFill() 404 @*/ 405 PetscErrorCode PCILUSetFill(PC pc,PetscReal fill) 406 { 407 PetscErrorCode ierr,(*f)(PC,PetscReal); 408 409 PetscFunctionBegin; 410 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 411 if (fill < 1.0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Fill factor cannot be less than 1.0"); 412 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCILUSetFill_C",(void (**)(void))&f);CHKERRQ(ierr); 413 if (f) { 414 ierr = (*f)(pc,fill);CHKERRQ(ierr); 415 } 416 PetscFunctionReturn(0); 417 } 418 419 #undef __FUNCT__ 420 #define __FUNCT__ "PCILUSetMatOrdering" 421 /*@C 422 PCILUSetMatOrdering - Sets the ordering routine (to reduce fill) to 423 be used in the ILU factorization. 424 425 Collective on PC 426 427 Input Parameters: 428 + pc - the preconditioner context 429 - ordering - the matrix ordering name, for example, MATORDERING_ND or MATORDERING_RCM 430 431 Options Database Key: 432 . -pc_ilu_mat_ordering_type <nd,rcm,...> - Sets ordering routine 433 434 Level: intermediate 435 436 Notes: natural ordering is used by default 437 438 .seealso: PCLUSetMatOrdering() 439 440 .keywords: PC, ILU, set, matrix, reordering 441 442 @*/ 443 PetscErrorCode PCILUSetMatOrdering(PC pc,MatOrderingType ordering) 444 { 445 PetscErrorCode ierr,(*f)(PC,MatOrderingType); 446 447 PetscFunctionBegin; 448 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 449 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCILUSetMatOrdering_C",(void (**)(void))&f);CHKERRQ(ierr); 450 if (f) { 451 ierr = (*f)(pc,ordering);CHKERRQ(ierr); 452 } 453 PetscFunctionReturn(0); 454 } 455 456 #undef __FUNCT__ 457 #define __FUNCT__ "PCILUSetReuseOrdering" 458 /*@ 459 PCILUSetReuseOrdering - When similar matrices are factored, this 460 causes the ordering computed in the first factor to be used for all 461 following factors; applies to both fill and drop tolerance ILUs. 462 463 Collective on PC 464 465 Input Parameters: 466 + pc - the preconditioner context 467 - flag - PETSC_TRUE to reuse else PETSC_FALSE 468 469 Options Database Key: 470 . -pc_ilu_reuse_ordering - Activate PCILUSetReuseOrdering() 471 472 Level: intermediate 473 474 .keywords: PC, levels, reordering, factorization, incomplete, ILU 475 476 .seealso: PCILUDTSetReuseFill(), PCLUSetReuseOrdering(), PCLUSetReuseFill() 477 @*/ 478 PetscErrorCode PCILUSetReuseOrdering(PC pc,PetscTruth flag) 479 { 480 PetscErrorCode ierr,(*f)(PC,PetscTruth); 481 482 PetscFunctionBegin; 483 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 484 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCILUSetReuseOrdering_C",(void (**)(void))&f);CHKERRQ(ierr); 485 if (f) { 486 ierr = (*f)(pc,flag);CHKERRQ(ierr); 487 } 488 PetscFunctionReturn(0); 489 } 490 491 #undef __FUNCT__ 492 #define __FUNCT__ "PCILUDTSetReuseFill" 493 /*@ 494 PCILUDTSetReuseFill - When matrices with same nonzero structure are ILUDT factored, 495 this causes later ones to use the fill computed in the initial factorization. 496 497 Collective on PC 498 499 Input Parameters: 500 + pc - the preconditioner context 501 - flag - PETSC_TRUE to reuse else PETSC_FALSE 502 503 Options Database Key: 504 . -pc_iludt_reuse_fill - Activates PCILUDTSetReuseFill() 505 506 Level: intermediate 507 508 .keywords: PC, levels, reordering, factorization, incomplete, ILU 509 510 .seealso: PCILUSetReuseOrdering(), PCLUSetReuseOrdering(), PCLUSetReuseFill() 511 @*/ 512 PetscErrorCode PCILUDTSetReuseFill(PC pc,PetscTruth flag) 513 { 514 PetscErrorCode ierr,(*f)(PC,PetscTruth); 515 516 PetscFunctionBegin; 517 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 518 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCILUDTSetReuseFill_C",(void (**)(void))&f);CHKERRQ(ierr); 519 if (f) { 520 ierr = (*f)(pc,flag);CHKERRQ(ierr); 521 } 522 PetscFunctionReturn(0); 523 } 524 525 #undef __FUNCT__ 526 #define __FUNCT__ "PCILUSetLevels" 527 /*@ 528 PCILUSetLevels - Sets the number of levels of fill to use. 529 530 Collective on PC 531 532 Input Parameters: 533 + pc - the preconditioner context 534 - levels - number of levels of fill 535 536 Options Database Key: 537 . -pc_ilu_levels <levels> - Sets fill level 538 539 Level: intermediate 540 541 .keywords: PC, levels, fill, factorization, incomplete, ILU 542 @*/ 543 PetscErrorCode PCILUSetLevels(PC pc,PetscInt levels) 544 { 545 PetscErrorCode ierr,(*f)(PC,PetscInt); 546 547 PetscFunctionBegin; 548 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 549 if (levels < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"negative levels"); 550 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCILUSetLevels_C",(void (**)(void))&f);CHKERRQ(ierr); 551 if (f) { 552 ierr = (*f)(pc,levels);CHKERRQ(ierr); 553 } 554 PetscFunctionReturn(0); 555 } 556 557 #undef __FUNCT__ 558 #define __FUNCT__ "PCILUSetAllowDiagonalFill" 559 /*@ 560 PCILUSetAllowDiagonalFill - Causes all diagonal matrix entries to be 561 treated as level 0 fill even if there is no non-zero location. 562 563 Collective on PC 564 565 Input Parameters: 566 + pc - the preconditioner context 567 568 Options Database Key: 569 . -pc_ilu_diagonal_fill 570 571 Notes: 572 Does not apply with 0 fill. 573 574 Level: intermediate 575 576 .keywords: PC, levels, fill, factorization, incomplete, ILU 577 @*/ 578 PetscErrorCode PCILUSetAllowDiagonalFill(PC pc) 579 { 580 PetscErrorCode ierr,(*f)(PC); 581 582 PetscFunctionBegin; 583 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 584 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCILUSetAllowDiagonalFill_C",(void (**)(void))&f);CHKERRQ(ierr); 585 if (f) { 586 ierr = (*f)(pc);CHKERRQ(ierr); 587 } 588 PetscFunctionReturn(0); 589 } 590 591 #undef __FUNCT__ 592 #define __FUNCT__ "PCILUSetUseInPlace" 593 /*@ 594 PCILUSetUseInPlace - Tells the system to do an in-place incomplete factorization. 595 Collective on PC 596 597 Input Parameters: 598 . pc - the preconditioner context 599 600 Options Database Key: 601 . -pc_ilu_in_place - Activates in-place factorization 602 603 Notes: 604 PCILUSetUseInPlace() is intended for use with matrix-free variants of 605 Krylov methods, or when a different matrices are employed for the linear 606 system and preconditioner, or with ASM preconditioning. Do NOT use 607 this option if the linear system 608 matrix also serves as the preconditioning matrix, since the factored 609 matrix would then overwrite the original matrix. 610 611 Only works well with ILU(0). 612 613 Level: intermediate 614 615 .keywords: PC, set, factorization, inplace, in-place, ILU 616 617 .seealso: PCLUSetUseInPlace() 618 @*/ 619 PetscErrorCode PCILUSetUseInPlace(PC pc) 620 { 621 PetscErrorCode ierr,(*f)(PC); 622 623 PetscFunctionBegin; 624 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 625 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCILUSetUseInPlace_C",(void (**)(void))&f);CHKERRQ(ierr); 626 if (f) { 627 ierr = (*f)(pc);CHKERRQ(ierr); 628 } 629 PetscFunctionReturn(0); 630 } 631 632 #undef __FUNCT__ 633 #define __FUNCT__ "PCILUReorderForNonzeroDiagonal" 634 /*@ 635 PCILUReorderForNonzeroDiagonal - reorders rows/columns of matrix to remove zeros from diagonal 636 637 Collective on PC 638 639 Input Parameters: 640 + pc - the preconditioner context 641 - tol - diagonal entries smaller than this in absolute value are considered zero 642 643 Options Database Key: 644 . -pc_lu_nonzeros_along_diagonal 645 646 Level: intermediate 647 648 .keywords: PC, set, factorization, direct, fill 649 650 .seealso: PCILUSetFill(), PCILUSetDamp(), PCIILUSetZeroPivot(), MatReorderForNonzeroDiagonal() 651 @*/ 652 PetscErrorCode PCILUReorderForNonzeroDiagonal(PC pc,PetscReal rtol) 653 { 654 PetscErrorCode ierr,(*f)(PC,PetscReal); 655 656 PetscFunctionBegin; 657 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 658 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCILUReorderForNonzeroDiagonal_C",(void (**)(void))&f);CHKERRQ(ierr); 659 if (f) { 660 ierr = (*f)(pc,rtol);CHKERRQ(ierr); 661 } 662 PetscFunctionReturn(0); 663 } 664 665 #undef __FUNCT__ 666 #define __FUNCT__ "PCILUSetPivotInBlocks" 667 /*@ 668 PCILUSetPivotInBlocks - Determines if pivoting is done while factoring each block 669 with BAIJ or SBAIJ matrices 670 671 Collective on PC 672 673 Input Parameters: 674 + pc - the preconditioner context 675 - pivot - PETSC_TRUE or PETSC_FALSE 676 677 Options Database Key: 678 . -pc_ilu_pivot_in_blocks <true,false> 679 680 Level: intermediate 681 682 .seealso: PCIILUSetMatOrdering(), PCILUSetPivoting() 683 @*/ 684 PetscErrorCode PCILUSetPivotInBlocks(PC pc,PetscTruth pivot) 685 { 686 PetscErrorCode ierr,(*f)(PC,PetscTruth); 687 688 PetscFunctionBegin; 689 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCILUSetPivotInBlocks_C",(void (**)(void))&f);CHKERRQ(ierr); 690 if (f) { 691 ierr = (*f)(pc,pivot);CHKERRQ(ierr); 692 } 693 PetscFunctionReturn(0); 694 } 695 696 /* ------------------------------------------------------------------------------------------*/ 697 698 EXTERN_C_BEGIN 699 #undef __FUNCT__ 700 #define __FUNCT__ "PCILUSetPivotInBlocks_ILU" 701 PetscErrorCode PCILUSetPivotInBlocks_ILU(PC pc,PetscTruth pivot) 702 { 703 PC_ILU *dir = (PC_ILU*)pc->data; 704 705 PetscFunctionBegin; 706 dir->info.pivotinblocks = pivot ? 1.0 : 0.0; 707 PetscFunctionReturn(0); 708 } 709 EXTERN_C_END 710 711 #undef __FUNCT__ 712 #define __FUNCT__ "PCSetFromOptions_ILU" 713 static PetscErrorCode PCSetFromOptions_ILU(PC pc) 714 { 715 PetscErrorCode ierr; 716 PetscInt dtmax = 3,itmp; 717 PetscTruth flg,set; 718 PetscReal dt[3]; 719 char tname[256]; 720 PC_ILU *ilu = (PC_ILU*)pc->data; 721 PetscFList ordlist; 722 PetscReal tol; 723 724 PetscFunctionBegin; 725 ierr = MatOrderingRegisterAll(PETSC_NULL);CHKERRQ(ierr); 726 ierr = PetscOptionsHead("ILU Options");CHKERRQ(ierr); 727 ierr = PetscOptionsInt("-pc_ilu_levels","levels of fill","PCILUSetLevels",(PetscInt)ilu->info.levels,&itmp,&flg);CHKERRQ(ierr); 728 if (flg) ilu->info.levels = itmp; 729 ierr = PetscOptionsName("-pc_ilu_in_place","do factorization in place","PCILUSetUseInPlace",&ilu->inplace);CHKERRQ(ierr); 730 ierr = PetscOptionsName("-pc_ilu_diagonal_fill","Allow fill into empty diagonal entry","PCILUSetAllowDiagonalFill",&flg);CHKERRQ(ierr); 731 ilu->info.diagonal_fill = (double) flg; 732 ierr = PetscOptionsName("-pc_iludt_reuse_fill","Reuse fill from previous ILUdt","PCILUDTSetReuseFill",&ilu->reusefill);CHKERRQ(ierr); 733 ierr = PetscOptionsName("-pc_ilu_reuse_ordering","Reuse previous reordering","PCILUSetReuseOrdering",&ilu->reuseordering);CHKERRQ(ierr); 734 ierr = PetscOptionsName("-pc_ilu_damping","Damping added to diagonal","PCILUSetDamping",&flg);CHKERRQ(ierr); 735 if (flg) { 736 ierr = PCILUSetDamping(pc,(PetscReal) PETSC_DECIDE);CHKERRQ(ierr); 737 } 738 ierr = PetscOptionsReal("-pc_ilu_damping","Damping added to diagonal","PCILUSetDamping",ilu->info.damping,&ilu->info.damping,0);CHKERRQ(ierr); 739 ierr = PetscOptionsName("-pc_ilu_shift","Manteuffel shift applied to diagonal","PCILUSetShift",&flg);CHKERRQ(ierr); 740 if (flg) { 741 ierr = PetscOptionsInt("-pc_ilu_shift","Manteuffel shift applied to diagonal","PCILUSetShift",(PetscInt)ilu->info.shift,&itmp,&flg); CHKERRQ(ierr); 742 if (flg && !itmp) { 743 ierr = PCILUSetShift(pc,PETSC_FALSE);CHKERRQ(ierr); 744 } else { 745 ierr = PCILUSetShift(pc,PETSC_TRUE);CHKERRQ(ierr); 746 } 747 } 748 ierr = PetscOptionsReal("-pc_ilu_zeropivot","Pivot is considered zero if less than","PCILUSetSetZeroPivot",ilu->info.zeropivot,&ilu->info.zeropivot,0);CHKERRQ(ierr); 749 750 dt[0] = ilu->info.dt; 751 dt[1] = ilu->info.dtcol; 752 dt[2] = ilu->info.dtcount; 753 ierr = PetscOptionsRealArray("-pc_ilu_use_drop_tolerance","<dt,dtcol,maxrowcount>","PCILUSetUseDropTolerance",dt,&dtmax,&flg);CHKERRQ(ierr); 754 if (flg) { 755 ierr = PCILUSetUseDropTolerance(pc,dt[0],dt[1],(PetscInt)dt[2]);CHKERRQ(ierr); 756 } 757 ierr = PetscOptionsReal("-pc_ilu_fill","Expected fill in factorization","PCILUSetFill",ilu->info.fill,&ilu->info.fill,&flg);CHKERRQ(ierr); 758 ierr = PetscOptionsName("-pc_ilu_nonzeros_along_diagonal","Reorder to remove zeros from diagonal","PCILUReorderForNonzeroDiagonal",&flg);CHKERRQ(ierr); 759 if (flg) { 760 tol = PETSC_DECIDE; 761 ierr = PetscOptionsReal("-pc_ilu_nonzeros_along_diagonal","Reorder to remove zeros from diagonal","PCILUReorderForNonzeroDiagonal",ilu->nonzerosalongdiagonaltol,&tol,0);CHKERRQ(ierr); 762 ierr = PCILUReorderForNonzeroDiagonal(pc,tol);CHKERRQ(ierr); 763 } 764 765 ierr = MatGetOrderingList(&ordlist);CHKERRQ(ierr); 766 ierr = PetscOptionsList("-pc_ilu_mat_ordering_type","Reorder to reduce nonzeros in ILU","PCILUSetMatOrdering",ordlist,ilu->ordering,tname,256,&flg);CHKERRQ(ierr); 767 if (flg) { 768 ierr = PCILUSetMatOrdering(pc,tname);CHKERRQ(ierr); 769 } 770 flg = ilu->info.pivotinblocks ? PETSC_TRUE : PETSC_FALSE; 771 ierr = PetscOptionsLogical("-pc_ilu_pivot_in_blocks","Pivot inside matrix blocks for BAIJ and SBAIJ","PCILUSetPivotInBlocks",flg,&flg,&set);CHKERRQ(ierr); 772 if (set) { 773 ierr = PCILUSetPivotInBlocks(pc,flg);CHKERRQ(ierr); 774 } 775 ierr = PetscOptionsTail();CHKERRQ(ierr); 776 PetscFunctionReturn(0); 777 } 778 779 #undef __FUNCT__ 780 #define __FUNCT__ "PCView_ILU" 781 static PetscErrorCode PCView_ILU(PC pc,PetscViewer viewer) 782 { 783 PC_ILU *ilu = (PC_ILU*)pc->data; 784 PetscErrorCode ierr; 785 PetscTruth isstring,iascii; 786 787 PetscFunctionBegin; 788 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);CHKERRQ(ierr); 789 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 790 if (iascii) { 791 if (ilu->usedt) { 792 ierr = PetscViewerASCIIPrintf(viewer," ILU: drop tolerance %g\n",ilu->info.dt);CHKERRQ(ierr); 793 ierr = PetscViewerASCIIPrintf(viewer," ILU: max nonzeros per row %D\n",(PetscInt)ilu->info.dtcount);CHKERRQ(ierr); 794 ierr = PetscViewerASCIIPrintf(viewer," ILU: column permutation tolerance %g\n",ilu->info.dtcol);CHKERRQ(ierr); 795 } else if (ilu->info.levels == 1) { 796 ierr = PetscViewerASCIIPrintf(viewer," ILU: %D level of fill\n",(PetscInt)ilu->info.levels);CHKERRQ(ierr); 797 } else { 798 ierr = PetscViewerASCIIPrintf(viewer," ILU: %D levels of fill\n",(PetscInt)ilu->info.levels);CHKERRQ(ierr); 799 } 800 ierr = PetscViewerASCIIPrintf(viewer," ILU: max fill ratio allocated %g\n",ilu->info.fill);CHKERRQ(ierr); 801 ierr = PetscViewerASCIIPrintf(viewer," ILU: tolerance for zero pivot %g\n",ilu->info.zeropivot);CHKERRQ(ierr); 802 if (ilu->info.shift) {ierr = PetscViewerASCIIPrintf(viewer," ILU: using Manteuffel shift\n");CHKERRQ(ierr);} 803 if (ilu->inplace) {ierr = PetscViewerASCIIPrintf(viewer," in-place factorization\n");CHKERRQ(ierr);} 804 else {ierr = PetscViewerASCIIPrintf(viewer," out-of-place factorization\n");CHKERRQ(ierr);} 805 ierr = PetscViewerASCIIPrintf(viewer," matrix ordering: %s\n",ilu->ordering);CHKERRQ(ierr); 806 if (ilu->reusefill) {ierr = PetscViewerASCIIPrintf(viewer," Reusing fill from past factorization\n");CHKERRQ(ierr);} 807 if (ilu->reuseordering) {ierr = PetscViewerASCIIPrintf(viewer," Reusing reordering from past factorization\n");CHKERRQ(ierr);} 808 if (ilu->fact) { 809 ierr = PetscViewerASCIIPrintf(viewer," Factored matrix follows\n");CHKERRQ(ierr); 810 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 811 ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr); 812 ierr = MatView(ilu->fact,viewer);CHKERRQ(ierr); 813 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 814 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 815 } 816 } else if (isstring) { 817 ierr = PetscViewerStringSPrintf(viewer," lvls=%D,order=%s",(PetscInt)ilu->info.levels,ilu->ordering);CHKERRQ(ierr);CHKERRQ(ierr); 818 } else { 819 SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for PCILU",((PetscObject)viewer)->type_name); 820 } 821 PetscFunctionReturn(0); 822 } 823 824 #undef __FUNCT__ 825 #define __FUNCT__ "PCSetUp_ILU" 826 static PetscErrorCode PCSetUp_ILU(PC pc) 827 { 828 PetscErrorCode ierr; 829 PC_ILU *ilu = (PC_ILU*)pc->data; 830 831 PetscFunctionBegin; 832 if (ilu->inplace) { 833 if (!pc->setupcalled) { 834 835 /* In-place factorization only makes sense with the natural ordering, 836 so we only need to get the ordering once, even if nonzero structure changes */ 837 ierr = MatGetOrdering(pc->pmat,ilu->ordering,&ilu->row,&ilu->col);CHKERRQ(ierr); 838 if (ilu->row) PetscLogObjectParent(pc,ilu->row); 839 if (ilu->col) PetscLogObjectParent(pc,ilu->col); 840 } 841 842 /* In place ILU only makes sense with fill factor of 1.0 because 843 cannot have levels of fill */ 844 ilu->info.fill = 1.0; 845 ilu->info.diagonal_fill = 0; 846 ierr = MatILUFactor(pc->pmat,ilu->row,ilu->col,&ilu->info);CHKERRQ(ierr); 847 ilu->fact = pc->pmat; 848 } else if (ilu->usedt) { 849 if (!pc->setupcalled) { 850 ierr = MatGetOrdering(pc->pmat,ilu->ordering,&ilu->row,&ilu->col);CHKERRQ(ierr); 851 if (ilu->row) PetscLogObjectParent(pc,ilu->row); 852 if (ilu->col) PetscLogObjectParent(pc,ilu->col); 853 ierr = MatILUDTFactor(pc->pmat,&ilu->info,ilu->row,ilu->col,&ilu->fact);CHKERRQ(ierr); 854 PetscLogObjectParent(pc,ilu->fact); 855 } else if (pc->flag != SAME_NONZERO_PATTERN) { 856 ierr = MatDestroy(ilu->fact);CHKERRQ(ierr); 857 if (!ilu->reuseordering) { 858 if (ilu->row) {ierr = ISDestroy(ilu->row);CHKERRQ(ierr);} 859 if (ilu->col) {ierr = ISDestroy(ilu->col);CHKERRQ(ierr);} 860 ierr = MatGetOrdering(pc->pmat,ilu->ordering,&ilu->row,&ilu->col);CHKERRQ(ierr); 861 if (ilu->row) PetscLogObjectParent(pc,ilu->row); 862 if (ilu->col) PetscLogObjectParent(pc,ilu->col); 863 } 864 ierr = MatILUDTFactor(pc->pmat,&ilu->info,ilu->row,ilu->col,&ilu->fact);CHKERRQ(ierr); 865 PetscLogObjectParent(pc,ilu->fact); 866 } else if (!ilu->reusefill) { 867 ierr = MatDestroy(ilu->fact);CHKERRQ(ierr); 868 ierr = MatILUDTFactor(pc->pmat,&ilu->info,ilu->row,ilu->col,&ilu->fact);CHKERRQ(ierr); 869 PetscLogObjectParent(pc,ilu->fact); 870 } else { 871 ierr = MatLUFactorNumeric(pc->pmat,&ilu->info,&ilu->fact);CHKERRQ(ierr); 872 } 873 } else { 874 if (!pc->setupcalled) { 875 /* first time in so compute reordering and symbolic factorization */ 876 ierr = MatGetOrdering(pc->pmat,ilu->ordering,&ilu->row,&ilu->col);CHKERRQ(ierr); 877 if (ilu->row) PetscLogObjectParent(pc,ilu->row); 878 if (ilu->col) PetscLogObjectParent(pc,ilu->col); 879 /* Remove zeros along diagonal? */ 880 if (ilu->nonzerosalongdiagonal) { 881 ierr = MatReorderForNonzeroDiagonal(pc->pmat,ilu->nonzerosalongdiagonaltol,ilu->row,ilu->col);CHKERRQ(ierr); 882 } 883 ierr = MatILUFactorSymbolic(pc->pmat,ilu->row,ilu->col,&ilu->info,&ilu->fact);CHKERRQ(ierr); 884 PetscLogObjectParent(pc,ilu->fact); 885 } else if (pc->flag != SAME_NONZERO_PATTERN) { 886 if (!ilu->reuseordering) { 887 /* compute a new ordering for the ILU */ 888 ierr = ISDestroy(ilu->row);CHKERRQ(ierr); 889 ierr = ISDestroy(ilu->col);CHKERRQ(ierr); 890 ierr = MatGetOrdering(pc->pmat,ilu->ordering,&ilu->row,&ilu->col);CHKERRQ(ierr); 891 if (ilu->row) PetscLogObjectParent(pc,ilu->row); 892 if (ilu->col) PetscLogObjectParent(pc,ilu->col); 893 /* Remove zeros along diagonal? */ 894 if (ilu->nonzerosalongdiagonal) { 895 ierr = MatReorderForNonzeroDiagonal(pc->pmat,ilu->nonzerosalongdiagonaltol,ilu->row,ilu->col);CHKERRQ(ierr); 896 } 897 } 898 ierr = MatDestroy(ilu->fact);CHKERRQ(ierr); 899 ierr = MatILUFactorSymbolic(pc->pmat,ilu->row,ilu->col,&ilu->info,&ilu->fact);CHKERRQ(ierr); 900 PetscLogObjectParent(pc,ilu->fact); 901 } 902 ierr = MatLUFactorNumeric(pc->pmat,&ilu->info,&ilu->fact);CHKERRQ(ierr); 903 } 904 PetscFunctionReturn(0); 905 } 906 907 #undef __FUNCT__ 908 #define __FUNCT__ "PCDestroy_ILU" 909 static PetscErrorCode PCDestroy_ILU(PC pc) 910 { 911 PC_ILU *ilu = (PC_ILU*)pc->data; 912 PetscErrorCode ierr; 913 914 PetscFunctionBegin; 915 ierr = PCDestroy_ILU_Internal(pc);CHKERRQ(ierr); 916 ierr = PetscStrfree(ilu->ordering);CHKERRQ(ierr); 917 ierr = PetscFree(ilu);CHKERRQ(ierr); 918 PetscFunctionReturn(0); 919 } 920 921 #undef __FUNCT__ 922 #define __FUNCT__ "PCApply_ILU" 923 static PetscErrorCode PCApply_ILU(PC pc,Vec x,Vec y) 924 { 925 PC_ILU *ilu = (PC_ILU*)pc->data; 926 PetscErrorCode ierr; 927 928 PetscFunctionBegin; 929 ierr = MatSolve(ilu->fact,x,y);CHKERRQ(ierr); 930 PetscFunctionReturn(0); 931 } 932 933 #undef __FUNCT__ 934 #define __FUNCT__ "PCApplyTranspose_ILU" 935 static PetscErrorCode PCApplyTranspose_ILU(PC pc,Vec x,Vec y) 936 { 937 PC_ILU *ilu = (PC_ILU*)pc->data; 938 PetscErrorCode ierr; 939 940 PetscFunctionBegin; 941 ierr = MatSolveTranspose(ilu->fact,x,y);CHKERRQ(ierr); 942 PetscFunctionReturn(0); 943 } 944 945 #undef __FUNCT__ 946 #define __FUNCT__ "PCGetFactoredMatrix_ILU" 947 static PetscErrorCode PCGetFactoredMatrix_ILU(PC pc,Mat *mat) 948 { 949 PC_ILU *ilu = (PC_ILU*)pc->data; 950 951 PetscFunctionBegin; 952 if (!ilu->fact) SETERRQ(PETSC_ERR_ORDER,"Matrix not yet factored; call after KSPSetUp() or PCSetUp()"); 953 *mat = ilu->fact; 954 PetscFunctionReturn(0); 955 } 956 957 /*MC 958 PCILU - Incomplete factorization preconditioners. 959 960 Options Database Keys: 961 + -pc_ilu_levels <k> - number of levels of fill for ILU(k) 962 . -pc_ilu_in_place - only for ILU(0) with natural ordering, reuses the space of the matrix for 963 its factorization (overwrites original matrix) 964 . -pc_ilu_diagonal_fill - fill in a zero diagonal even if levels of fill indicate it wouldn't be fill 965 . -pc_ilu_reuse_ordering - reuse ordering of factorized matrix from previous factorization 966 . -pc_ilu_damping - add damping to diagonal to prevent zero (or very small) pivots 967 . -pc_ilu_shift - apply Manteuffel shift to diagonal to force positive definite preconditioner 968 . -pc_ilu_zeropivot <tol> - set tolerance for what is considered a zero pivot 969 . -pc_ilu_use_drop_tolerance <dt,dtcol,maxrowcount> - use Saad's drop tolerance ILUdt 970 . -pc_ilu_fill <nfill> - expected amount of fill in factored matrix compared to original matrix, nfill > 1 971 . -pc_ilu_nonzeros_along_diagonal - reorder the matrix before factorization to remove zeros from the diagonal, 972 this decreases the chance of getting a zero pivot 973 . -pc_ilu_mat_ordering_type <natural,nd,1wd,rcm,qmd> - set the row/column ordering of the factored matrix 974 - -pc_ilu_pivot_in_blocks - for block ILU(k) factorization, i.e. with BAIJ matrices with block size larger 975 than 1 the diagonal blocks are factored with partial pivoting (this increases the 976 stability of the ILU factorization 977 978 Level: beginner 979 980 Concepts: incomplete factorization 981 982 Notes: Only implemented for some matrix formats. Not implemented in parallel 983 984 For BAIJ matrices this implements a point block ILU 985 986 .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, PCSOR, MatOrderingType, 987 PCILUSetSetZeroPivot(), PCILUSetDamping(), PCILUSetShift(), PCILUSetUseDropTolerance(), 988 PCILUSetFill(), PCILUSetMatOrdering(), PCILUSetReuseOrdering(), PCILUDTSetReuseFill(), 989 PCILUSetLevels(), PCILUSetUseInPlace(), PCILUSetAllowDiagonalFill(), PCILUSetPivotInBlocks(), 990 991 M*/ 992 993 EXTERN_C_BEGIN 994 #undef __FUNCT__ 995 #define __FUNCT__ "PCCreate_ILU" 996 PetscErrorCode PCCreate_ILU(PC pc) 997 { 998 PetscErrorCode ierr; 999 PC_ILU *ilu; 1000 1001 PetscFunctionBegin; 1002 ierr = PetscNew(PC_ILU,&ilu);CHKERRQ(ierr); 1003 PetscLogObjectMemory(pc,sizeof(PC_ILU)); 1004 1005 ilu->fact = 0; 1006 ierr = MatFactorInfoInitialize(&ilu->info);CHKERRQ(ierr); 1007 ilu->info.levels = 0; 1008 ilu->info.fill = 1.0; 1009 ilu->col = 0; 1010 ilu->row = 0; 1011 ilu->inplace = PETSC_FALSE; 1012 ierr = PetscStrallocpy(MATORDERING_NATURAL,&ilu->ordering);CHKERRQ(ierr); 1013 ilu->reuseordering = PETSC_FALSE; 1014 ilu->usedt = PETSC_FALSE; 1015 ilu->info.dt = PETSC_DEFAULT; 1016 ilu->info.dtcount = PETSC_DEFAULT; 1017 ilu->info.dtcol = PETSC_DEFAULT; 1018 ilu->info.damping = 0.0; 1019 ilu->info.shift = PETSC_FALSE; 1020 ilu->info.shift_fraction = 0.0; 1021 ilu->info.zeropivot = 1.e-12; 1022 ilu->info.pivotinblocks = 1.0; 1023 ilu->reusefill = PETSC_FALSE; 1024 ilu->info.diagonal_fill = 0; 1025 pc->data = (void*)ilu; 1026 1027 pc->ops->destroy = PCDestroy_ILU; 1028 pc->ops->apply = PCApply_ILU; 1029 pc->ops->applytranspose = PCApplyTranspose_ILU; 1030 pc->ops->setup = PCSetUp_ILU; 1031 pc->ops->setfromoptions = PCSetFromOptions_ILU; 1032 pc->ops->getfactoredmatrix = PCGetFactoredMatrix_ILU; 1033 pc->ops->view = PCView_ILU; 1034 pc->ops->applyrichardson = 0; 1035 1036 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCILUSetUseDropTolerance_C","PCILUSetUseDropTolerance_ILU", 1037 PCILUSetUseDropTolerance_ILU);CHKERRQ(ierr); 1038 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCILUSetFill_C","PCILUSetFill_ILU", 1039 PCILUSetFill_ILU);CHKERRQ(ierr); 1040 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCILUSetDamping_C","PCILUSetDamping_ILU", 1041 PCILUSetDamping_ILU);CHKERRQ(ierr); 1042 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCILUSetShift_C","PCILUSetShift_ILU", 1043 PCILUSetShift_ILU);CHKERRQ(ierr); 1044 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCILUSetMatOrdering_C","PCILUSetMatOrdering_ILU", 1045 PCILUSetMatOrdering_ILU);CHKERRQ(ierr); 1046 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCILUSetReuseOrdering_C","PCILUSetReuseOrdering_ILU", 1047 PCILUSetReuseOrdering_ILU);CHKERRQ(ierr); 1048 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCILUDTSetReuseFill_C","PCILUDTSetReuseFill_ILUDT", 1049 PCILUDTSetReuseFill_ILUDT);CHKERRQ(ierr); 1050 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCILUSetLevels_C","PCILUSetLevels_ILU", 1051 PCILUSetLevels_ILU);CHKERRQ(ierr); 1052 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCILUSetUseInPlace_C","PCILUSetUseInPlace_ILU", 1053 PCILUSetUseInPlace_ILU);CHKERRQ(ierr); 1054 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCILUSetAllowDiagonalFill_C","PCILUSetAllowDiagonalFill_ILU", 1055 PCILUSetAllowDiagonalFill_ILU);CHKERRQ(ierr); 1056 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCILUSetPivotInBlocks_C","PCILUSetPivotInBlocks_ILU", 1057 PCILUSetPivotInBlocks_ILU);CHKERRQ(ierr); 1058 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCILUSetZeroPivot_C","PCILUSetZeroPivot_ILU", 1059 PCILUSetZeroPivot_ILU);CHKERRQ(ierr); 1060 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCILUReorderForNonzeroDiagonal_C","PCILUReorderForNonzeroDiagonal_ILU", 1061 PCILUReorderForNonzeroDiagonal_ILU);CHKERRQ(ierr); 1062 PetscFunctionReturn(0); 1063 } 1064 EXTERN_C_END 1065