Date: 2022-03-04T17:38:54+00:00

Actual source code: icc.c

      2: #include <../src/ksp/pc/impls/factor/icc/icc.h>

      4: static PetscErrorCode PCSetUp_ICC(PC pc)
      5: {
      6:   PC_ICC                 *icc = (PC_ICC*)pc->data;
      7:   IS                     perm = NULL,cperm = NULL;
      8:   PetscErrorCode         ierr;
      9:   MatInfo                info;
     10:   MatSolverType          stype;
     11:   MatFactorError         err;
     12:   PetscBool              canuseordering;

     15:   pc->failedreason = PC_NOERROR;

     17:   MatSetErrorIfFailure(pc->pmat,pc->erroriffailure);
     18:   if (!pc->setupcalled) {
     19:     if (!((PC_Factor*)icc)->fact) {
     20:       MatGetFactor(pc->pmat,((PC_Factor*)icc)->solvertype,MAT_FACTOR_ICC,&((PC_Factor*)icc)->fact);
     21:     }
     22:     MatFactorGetCanUseOrdering(((PC_Factor*)icc)->fact,&canuseordering);
     23:     if (canuseordering) {
     24:       PCFactorSetDefaultOrdering_Factor(pc);
     25:       MatGetOrdering(pc->pmat, ((PC_Factor*)icc)->ordering,&perm,&cperm);
     26:     }
     27:     MatICCFactorSymbolic(((PC_Factor*)icc)->fact,pc->pmat,perm,&((PC_Factor*)icc)->info);
     28:   } else if (pc->flag != SAME_NONZERO_PATTERN) {
     29:     PetscBool canuseordering;
     30:     MatDestroy(&((PC_Factor*)icc)->fact);
     31:     MatGetFactor(pc->pmat,((PC_Factor*)icc)->solvertype,MAT_FACTOR_ICC,&((PC_Factor*)icc)->fact);
     32:     MatFactorGetCanUseOrdering(((PC_Factor*)icc)->fact,&canuseordering);
     33:     if (canuseordering) {
     34:       PCFactorSetDefaultOrdering_Factor(pc);
     35:       MatGetOrdering(pc->pmat, ((PC_Factor*)icc)->ordering,&perm,&cperm);
     36:     }
     37:     MatICCFactorSymbolic(((PC_Factor*)icc)->fact,pc->pmat,perm,&((PC_Factor*)icc)->info);
     38:   }
     39:   MatGetInfo(((PC_Factor*)icc)->fact,MAT_LOCAL,&info);
     40:   icc->hdr.actualfill = info.fill_ratio_needed;

     42:   ISDestroy(&cperm);
     43:   ISDestroy(&perm);

     45:   MatFactorGetError(((PC_Factor*)icc)->fact,&err);
     46:   if (err) { /* FactorSymbolic() fails */
     47:     pc->failedreason = (PCFailedReason)err;
     48:     return(0);
     49:   }

     51:   MatCholeskyFactorNumeric(((PC_Factor*)icc)->fact,pc->pmat,&((PC_Factor*)icc)->info);
     52:   MatFactorGetError(((PC_Factor*)icc)->fact,&err);
     53:   if (err) { /* FactorNumeric() fails */
     54:     pc->failedreason = (PCFailedReason)err;
     55:   }

     57:   PCFactorGetMatSolverType(pc,&stype);
     58:   if (!stype) {
     59:     MatSolverType solverpackage;
     60:     MatFactorGetSolverType(((PC_Factor*)icc)->fact,&solverpackage);
     61:     PCFactorSetMatSolverType(pc,solverpackage);
     62:   }
     63:   return(0);
     64: }

     66: static PetscErrorCode PCReset_ICC(PC pc)
     67: {
     68:   PC_ICC         *icc = (PC_ICC*)pc->data;

     72:   MatDestroy(&((PC_Factor*)icc)->fact);
     73:   return(0);
     74: }

     76: static PetscErrorCode PCDestroy_ICC(PC pc)
     77: {
     78:   PC_ICC         *icc = (PC_ICC*)pc->data;

     82:   PCReset_ICC(pc);
     83:   PetscFree(((PC_Factor*)icc)->ordering);
     84:   PetscFree(((PC_Factor*)icc)->solvertype);
     85:   PetscFree(pc->data);
     86:   return(0);
     87: }

     89: static PetscErrorCode PCApply_ICC(PC pc,Vec x,Vec y)
     90: {
     91:   PC_ICC         *icc = (PC_ICC*)pc->data;

     95:   MatSolve(((PC_Factor*)icc)->fact,x,y);
     96:   return(0);
     97: }

     99: static PetscErrorCode PCMatApply_ICC(PC pc,Mat X,Mat Y)
    100: {
    101:   PC_ICC         *icc = (PC_ICC*)pc->data;

    105:   MatMatSolve(((PC_Factor*)icc)->fact,X,Y);
    106:   return(0);
    107: }

    109: static PetscErrorCode PCApplySymmetricLeft_ICC(PC pc,Vec x,Vec y)
    110: {
    112:   PC_ICC         *icc = (PC_ICC*)pc->data;

    115:   MatForwardSolve(((PC_Factor*)icc)->fact,x,y);
    116:   return(0);
    117: }

    119: static PetscErrorCode PCApplySymmetricRight_ICC(PC pc,Vec x,Vec y)
    120: {
    122:   PC_ICC         *icc = (PC_ICC*)pc->data;

    125:   MatBackwardSolve(((PC_Factor*)icc)->fact,x,y);
    126:   return(0);
    127: }

    129: static PetscErrorCode PCSetFromOptions_ICC(PetscOptionItems *PetscOptionsObject,PC pc)
    130: {
    131:   PC_ICC         *icc = (PC_ICC*)pc->data;
    132:   PetscBool      flg;
    134:   /* PetscReal      dt[3];*/

    137:   PetscOptionsHead(PetscOptionsObject,"ICC Options");
    138:   PCSetFromOptions_Factor(PetscOptionsObject,pc);

    140:   PetscOptionsReal("-pc_factor_levels","levels of fill","PCFactorSetLevels",((PC_Factor*)icc)->info.levels,&((PC_Factor*)icc)->info.levels,&flg);
    141:   /*dt[0] = ((PC_Factor*)icc)->info.dt;
    142:   dt[1] = ((PC_Factor*)icc)->info.dtcol;
    143:   dt[2] = ((PC_Factor*)icc)->info.dtcount;
    144:   PetscInt       dtmax = 3;
    145:   PetscOptionsRealArray("-pc_factor_drop_tolerance","<dt,dtcol,maxrowcount>","PCFactorSetDropTolerance",dt,&dtmax,&flg);
    146:   if (flg) {
    147:     PCFactorSetDropTolerance(pc,dt[0],dt[1],(PetscInt)dt[2]);
    148:   }
    149:   */
    150:   PetscOptionsTail();
    151:   return(0);
    152: }

    154: extern PetscErrorCode  PCFactorSetDropTolerance_ILU(PC,PetscReal,PetscReal,PetscInt);

    156: /*MC
    157:      PCICC - Incomplete Cholesky factorization preconditioners.

    159:    Options Database Keys:
    160: +  -pc_factor_levels <k> - number of levels of fill for ICC(k)
    161: .  -pc_factor_in_place - only for ICC(0) with natural ordering, reuses the space of the matrix for
    162:                       its factorization (overwrites original matrix)
    163: .  -pc_factor_fill <nfill> - expected amount of fill in factored matrix compared to original matrix, nfill > 1
    164: -  -pc_factor_mat_ordering_type <natural,nd,1wd,rcm,qmd> - set the row/column ordering of the factored matrix

    166:    Level: beginner

    168:    Notes:
    169:     Only implemented for some matrix formats. Not implemented in parallel.

    171:           For BAIJ matrices this implements a point block ICC.

    173:           The Manteuffel shift is only implemented for matrices with block size 1

    175:           By default, the Manteuffel is applied (for matrices with block size 1). Call PCFactorSetShiftType(pc,MAT_SHIFT_POSITIVE_DEFINITE);
    176:           to turn off the shift.

    178:    References:
    179: .  1. - TONY F. CHAN AND HENK A. VAN DER VORST, Review article: APPROXIMATE AND INCOMPLETE FACTORIZATIONS,
    180:       Chapter in Parallel Numerical Algorithms, edited by D. Keyes, A. Semah, V. Venkatakrishnan, ICASE/LaRC Interdisciplinary Series in
    181:       Science and Engineering, Kluwer.

    183: .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC, PCSOR, MatOrderingType,
    184:            PCFactorSetZeroPivot(), PCFactorSetShiftType(), PCFactorSetShiftAmount(),
    185:            PCFactorSetFill(), PCFactorSetMatOrderingType(), PCFactorSetReuseOrdering(),
    186:            PCFactorSetLevels()

    188: M*/

    190: PETSC_EXTERN PetscErrorCode PCCreate_ICC(PC pc)
    191: {
    193:   PC_ICC         *icc;

    196:   PetscNewLog(pc,&icc);
    197:   pc->data = (void*)icc;
    198:   PCFactorInitialize(pc, MAT_FACTOR_ICC);

    200:   ((PC_Factor*)icc)->info.fill      = 1.0;
    201:   ((PC_Factor*)icc)->info.dtcol     = PETSC_DEFAULT;
    202:   ((PC_Factor*)icc)->info.shifttype = (PetscReal) MAT_SHIFT_POSITIVE_DEFINITE;

    204:   pc->ops->apply               = PCApply_ICC;
    205:   pc->ops->matapply            = PCMatApply_ICC;
    206:   pc->ops->applytranspose      = PCApply_ICC;
    207:   pc->ops->setup               = PCSetUp_ICC;
    208:   pc->ops->reset               = PCReset_ICC;
    209:   pc->ops->destroy             = PCDestroy_ICC;
    210:   pc->ops->setfromoptions      = PCSetFromOptions_ICC;
    211:   pc->ops->view                = PCView_Factor;
    212:   pc->ops->applysymmetricleft  = PCApplySymmetricLeft_ICC;
    213:   pc->ops->applysymmetricright = PCApplySymmetricRight_ICC;
    214:   return(0);
    215: }