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

Actual source code: qr.c

      2: /*
      3:    Defines a direct QR factorization preconditioner for any Mat implementation
      4:    Note: this need not be considered a preconditioner since it supplies
      5:          a direct solver.
      6: */
      7: #include <../src/ksp/pc/impls/factor/qr/qr.h>

      9: static PetscErrorCode PCSetUp_QR(PC pc)
     10: {
     11:   PetscErrorCode         ierr;
     12:   PC_QR                  *dir = (PC_QR*)pc->data;
     13:   MatSolverType          stype;
     14:   MatFactorError         err;

     17:   pc->failedreason = PC_NOERROR;
     18:   if (dir->hdr.reusefill && pc->setupcalled) ((PC_Factor*)dir)->info.fill = dir->hdr.actualfill;

     20:   MatSetErrorIfFailure(pc->pmat,pc->erroriffailure);
     21:   if (dir->hdr.inplace) {
     22:     MatFactorType ftype;

     24:     MatGetFactorType(pc->pmat, &ftype);
     25:     if (ftype == MAT_FACTOR_NONE) {
     26:       MatQRFactor(pc->pmat,dir->col,&((PC_Factor*)dir)->info);
     27:       MatFactorGetError(pc->pmat,&err);
     28:       if (err) { /* Factor() fails */
     29:         pc->failedreason = (PCFailedReason)err;
     30:         return(0);
     31:       }
     32:     }
     33:     ((PC_Factor*)dir)->fact = pc->pmat;
     34:   } else {
     35:     MatInfo info;

     37:     if (!pc->setupcalled) {
     38:       if (!((PC_Factor*)dir)->fact) {
     39:         MatGetFactor(pc->pmat,((PC_Factor*)dir)->solvertype,MAT_FACTOR_QR,&((PC_Factor*)dir)->fact);
     40:         PetscLogObjectParent((PetscObject)pc,(PetscObject)((PC_Factor*)dir)->fact);
     41:       }
     42:       MatQRFactorSymbolic(((PC_Factor*)dir)->fact,pc->pmat,dir->col,&((PC_Factor*)dir)->info);
     43:       MatGetInfo(((PC_Factor*)dir)->fact,MAT_LOCAL,&info);
     44:       dir->hdr.actualfill = info.fill_ratio_needed;
     45:     } else if (pc->flag != SAME_NONZERO_PATTERN) {
     46:       MatQRFactorSymbolic(((PC_Factor*)dir)->fact,pc->pmat,dir->col,&((PC_Factor*)dir)->info);
     47:       MatGetInfo(((PC_Factor*)dir)->fact,MAT_LOCAL,&info);
     48:       dir->hdr.actualfill = info.fill_ratio_needed;
     49:     } else {
     50:       MatFactorGetError(((PC_Factor*)dir)->fact,&err);
     51:     }
     52:     MatFactorGetError(((PC_Factor*)dir)->fact,&err);
     53:     if (err) { /* FactorSymbolic() fails */
     54:       pc->failedreason = (PCFailedReason)err;
     55:       return(0);
     56:     }

     58:     MatQRFactorNumeric(((PC_Factor*)dir)->fact,pc->pmat,&((PC_Factor*)dir)->info);
     59:     MatFactorGetError(((PC_Factor*)dir)->fact,&err);
     60:     if (err) { /* FactorNumeric() fails */
     61:       pc->failedreason = (PCFailedReason)err;
     62:     }
     63:   }

     65:   PCFactorGetMatSolverType(pc,&stype);
     66:   if (!stype) {
     67:     MatSolverType solverpackage;
     68:     MatFactorGetSolverType(((PC_Factor*)dir)->fact,&solverpackage);
     69:     PCFactorSetMatSolverType(pc,solverpackage);
     70:   }
     71:   return(0);
     72: }

     74: static PetscErrorCode PCReset_QR(PC pc)
     75: {
     76:   PC_QR          *dir = (PC_QR*)pc->data;

     80:   if (!dir->hdr.inplace && ((PC_Factor*)dir)->fact) {MatDestroy(&((PC_Factor*)dir)->fact);}
     81:   ISDestroy(&dir->col);
     82:   return(0);
     83: }

     85: static PetscErrorCode PCDestroy_QR(PC pc)
     86: {
     87:   PC_QR          *dir = (PC_QR*)pc->data;

     91:   PCReset_QR(pc);
     92:   PetscFree(((PC_Factor*)dir)->ordering);
     93:   PetscFree(((PC_Factor*)dir)->solvertype);
     94:   PetscFree(pc->data);
     95:   return(0);
     96: }

     98: static PetscErrorCode PCApply_QR(PC pc,Vec x,Vec y)
     99: {
    100:   PC_QR          *dir = (PC_QR*)pc->data;
    101:   Mat            fact;

    105:   fact = dir->hdr.inplace ? pc->pmat : ((PC_Factor*)dir)->fact;
    106:   MatSolve(fact,x,y);
    107:   return(0);
    108: }

    110: static PetscErrorCode PCMatApply_QR(PC pc,Mat X,Mat Y)
    111: {
    112:   PC_QR          *dir = (PC_QR*)pc->data;
    113:   Mat            fact;

    117:   fact = dir->hdr.inplace ? pc->pmat : ((PC_Factor*)dir)->fact;
    118:   MatMatSolve(fact,X,Y);
    119:   return(0);
    120: }

    122: static PetscErrorCode PCApplyTranspose_QR(PC pc,Vec x,Vec y)
    123: {
    124:   PC_QR          *dir = (PC_QR*)pc->data;
    125:   Mat            fact;

    129:   fact = dir->hdr.inplace ? pc->pmat : ((PC_Factor*)dir)->fact;
    130:   MatSolveTranspose(fact,x,y);
    131:   return(0);
    132: }

    134: /* -----------------------------------------------------------------------------------*/

    136: /*MC
    137:    PCQR - Uses a direct solver, based on QR factorization, as a preconditioner

    139:    Level: beginner

    141:    Notes:
    142:     Usually this will compute an "exact" solution in one iteration and does
    143:           not need a Krylov method (i.e. you can use -ksp_type preonly, or
    144:           KSPSetType(ksp,KSPPREONLY) for the Krylov method

    146: .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
    147:            PCILU, PCLU, PCCHOLESKY, PCICC, PCFactorSetReuseOrdering(), PCFactorSetReuseFill(), PCFactorGetMatrix(),
    148:            PCFactorSetFill(), PCFactorSetUseInPlace(), PCFactorSetMatOrderingType(), PCFactorSetColumnPivot(),
    149:            PCFactorSetPivotingInBlocks(),PCFactorSetShiftType(),PCFactorSetShiftAmount()
    150:            PCFactorReorderForNonzeroDiagonal()
    151: M*/

    153: PETSC_EXTERN PetscErrorCode PCCreate_QR(PC pc)
    154: {
    156:   PC_QR          *dir;

    159:   PetscNewLog(pc,&dir);
    160:   pc->data = (void*)dir;
    161:   PCFactorInitialize(pc, MAT_FACTOR_QR);

    163:   dir->col                   = NULL;
    164:   pc->ops->reset             = PCReset_QR;
    165:   pc->ops->destroy           = PCDestroy_QR;
    166:   pc->ops->apply             = PCApply_QR;
    167:   pc->ops->matapply          = PCMatApply_QR;
    168:   pc->ops->applytranspose    = PCApplyTranspose_QR;
    169:   pc->ops->setup             = PCSetUp_QR;
    170:   pc->ops->setfromoptions    = PCSetFromOptions_Factor;
    171:   pc->ops->view              = PCView_Factor;
    172:   pc->ops->applyrichardson   = NULL;
    173:   return(0);
    174: }