Exemplo n.º 1
0
PETSC_EXTERN void PETSC_STDCALL  matseterroriffailure_(Mat mat,PetscBool *flg, int *__ierr ){
*__ierr = MatSetErrorIfFailure(
	(Mat)PetscToPointer((mat) ),*flg);
}
Exemplo n.º 2
0
static PetscErrorCode PCSetUp_ILU(PC pc)
{
  PetscErrorCode         ierr;
  PC_ILU                 *ilu = (PC_ILU*)pc->data;
  MatInfo                info;
  PetscBool              flg;
  const MatSolverPackage stype;
  MatFactorError         err;

  PetscFunctionBegin;
  pc->failedreason = PC_NOERROR;
  /* ugly hack to change default, since it is not support by some matrix types */
  if (((PC_Factor*)ilu)->info.shifttype == (PetscReal)MAT_SHIFT_NONZERO) {
    ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATSEQAIJ,&flg);CHKERRQ(ierr);
    if (!flg) {
      ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATMPIAIJ,&flg);CHKERRQ(ierr);
      if (!flg) {
        ((PC_Factor*)ilu)->info.shifttype = (PetscReal)MAT_SHIFT_INBLOCKS;
        PetscInfo(pc,"Changing shift type from NONZERO to INBLOCKS because block matrices do not support NONZERO\n");CHKERRQ(ierr);
      }
    }
  }

  ierr = MatSetErrorIfFailure(pc->pmat,pc->erroriffailure);CHKERRQ(ierr);
  if (ilu->hdr.inplace) {
    if (!pc->setupcalled) {

      /* In-place factorization only makes sense with the natural ordering,
         so we only need to get the ordering once, even if nonzero structure changes */
      ierr = MatGetOrdering(pc->pmat,((PC_Factor*)ilu)->ordering,&ilu->row,&ilu->col);CHKERRQ(ierr);
      if (ilu->row) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->row);CHKERRQ(ierr);}
      if (ilu->col) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->col);CHKERRQ(ierr);}
    }

    /* In place ILU only makes sense with fill factor of 1.0 because
       cannot have levels of fill */
    ((PC_Factor*)ilu)->info.fill          = 1.0;
    ((PC_Factor*)ilu)->info.diagonal_fill = 0.0;

    ierr = MatILUFactor(pc->pmat,ilu->row,ilu->col,&((PC_Factor*)ilu)->info);CHKERRQ(ierr);CHKERRQ(ierr);
    ierr = MatFactorGetError(pc->pmat,&err);CHKERRQ(ierr);
    if (err) { /* Factor() fails */
      pc->failedreason = (PCFailedReason)err;
      PetscFunctionReturn(0);
    }

    ((PC_Factor*)ilu)->fact = pc->pmat;
    /* must update the pc record of the matrix state or the PC will attempt to run PCSetUp() yet again */
    ierr = PetscObjectStateGet((PetscObject)pc->pmat,&pc->matstate);CHKERRQ(ierr);
  } else {
    if (!pc->setupcalled) {
      /* first time in so compute reordering and symbolic factorization */
      ierr = MatGetOrdering(pc->pmat,((PC_Factor*)ilu)->ordering,&ilu->row,&ilu->col);CHKERRQ(ierr);
      if (ilu->row) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->row);CHKERRQ(ierr);}
      if (ilu->col) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->col);CHKERRQ(ierr);}
      /*  Remove zeros along diagonal?     */
      if (ilu->nonzerosalongdiagonal) {
        ierr = MatReorderForNonzeroDiagonal(pc->pmat,ilu->nonzerosalongdiagonaltol,ilu->row,ilu->col);CHKERRQ(ierr);
      }
      if (!((PC_Factor*)ilu)->fact) {
        ierr = MatGetFactor(pc->pmat,((PC_Factor*)ilu)->solvertype,MAT_FACTOR_ILU,&((PC_Factor*)ilu)->fact);CHKERRQ(ierr);
      }
      ierr = MatILUFactorSymbolic(((PC_Factor*)ilu)->fact,pc->pmat,ilu->row,ilu->col,&((PC_Factor*)ilu)->info);CHKERRQ(ierr);
      ierr = MatGetInfo(((PC_Factor*)ilu)->fact,MAT_LOCAL,&info);CHKERRQ(ierr);
      ilu->hdr.actualfill = info.fill_ratio_needed;

      ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)((PC_Factor*)ilu)->fact);CHKERRQ(ierr);
    } else if (pc->flag != SAME_NONZERO_PATTERN) {
      if (!ilu->hdr.reuseordering) {
        /* compute a new ordering for the ILU */
        ierr = ISDestroy(&ilu->row);CHKERRQ(ierr);
        ierr = ISDestroy(&ilu->col);CHKERRQ(ierr);
        ierr = MatGetOrdering(pc->pmat,((PC_Factor*)ilu)->ordering,&ilu->row,&ilu->col);CHKERRQ(ierr);
        if (ilu->row) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->row);CHKERRQ(ierr);}
        if (ilu->col) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->col);CHKERRQ(ierr);}
        /*  Remove zeros along diagonal?     */
        if (ilu->nonzerosalongdiagonal) {
          ierr = MatReorderForNonzeroDiagonal(pc->pmat,ilu->nonzerosalongdiagonaltol,ilu->row,ilu->col);CHKERRQ(ierr);
        }
      }
      ierr = MatDestroy(&((PC_Factor*)ilu)->fact);CHKERRQ(ierr);
      ierr = MatGetFactor(pc->pmat,((PC_Factor*)ilu)->solvertype,MAT_FACTOR_ILU,&((PC_Factor*)ilu)->fact);CHKERRQ(ierr);
      ierr = MatILUFactorSymbolic(((PC_Factor*)ilu)->fact,pc->pmat,ilu->row,ilu->col,&((PC_Factor*)ilu)->info);CHKERRQ(ierr);
      ierr = MatGetInfo(((PC_Factor*)ilu)->fact,MAT_LOCAL,&info);CHKERRQ(ierr);
      ilu->hdr.actualfill = info.fill_ratio_needed;

      ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)((PC_Factor*)ilu)->fact);CHKERRQ(ierr);
    }
    ierr = MatFactorGetError(((PC_Factor*)ilu)->fact,&err);CHKERRQ(ierr);
    if (err) { /* FactorSymbolic() fails */
      pc->failedreason = (PCFailedReason)err;
      PetscFunctionReturn(0);
    }

    ierr = MatLUFactorNumeric(((PC_Factor*)ilu)->fact,pc->pmat,&((PC_Factor*)ilu)->info);CHKERRQ(ierr);
    ierr = MatFactorGetError(((PC_Factor*)ilu)->fact,&err);CHKERRQ(ierr);
    if (err) { /* FactorNumeric() fails */
      pc->failedreason = (PCFailedReason)err;
    }
  }

  ierr = PCFactorGetMatSolverPackage(pc,&stype);CHKERRQ(ierr);
  if (!stype) {
    const MatSolverPackage solverpackage;
    ierr = MatFactorGetSolverPackage(((PC_Factor*)ilu)->fact,&solverpackage);CHKERRQ(ierr);
    ierr = PCFactorSetMatSolverPackage(pc,solverpackage);CHKERRQ(ierr);
  }
  PetscFunctionReturn(0);
}
Exemplo n.º 3
0
static PetscErrorCode PCSetUp_Cholesky(PC pc)
{
    PetscErrorCode         ierr;
    PetscBool              flg;
    PC_Cholesky            *dir = (PC_Cholesky*)pc->data;
    const MatSolverPackage stype;
    MatFactorError         err;

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

    ierr = MatSetErrorIfFailure(pc->pmat,pc->erroriffailure);
    CHKERRQ(ierr);
    if (dir->hdr.inplace) {
        if (dir->row && dir->col && (dir->row != dir->col)) {
            ierr = ISDestroy(&dir->row);
            CHKERRQ(ierr);
        }
        ierr = ISDestroy(&dir->col);
        CHKERRQ(ierr);
        ierr = MatGetOrdering(pc->pmat,((PC_Factor*)dir)->ordering,&dir->row,&dir->col);
        CHKERRQ(ierr);
        if (dir->col && (dir->row != dir->col)) {  /* only use row ordering for SBAIJ */
            ierr = ISDestroy(&dir->col);
            CHKERRQ(ierr);
        }
        if (dir->row) {
            ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)dir->row);
            CHKERRQ(ierr);
        }
        ierr = MatCholeskyFactor(pc->pmat,dir->row,&((PC_Factor*)dir)->info);
        CHKERRQ(ierr);
        ierr = MatFactorGetError(pc->pmat,&err);
        CHKERRQ(ierr);
        if (err) { /* Factor() fails */
            pc->failedreason = (PCFailedReason)err;
            PetscFunctionReturn(0);
        }

        ((PC_Factor*)dir)->fact = pc->pmat;
    } else {
        MatInfo info;

        if (!pc->setupcalled) {
            ierr = MatGetOrdering(pc->pmat,((PC_Factor*)dir)->ordering,&dir->row,&dir->col);
            CHKERRQ(ierr);
            /* check if dir->row == dir->col */
            ierr = ISEqual(dir->row,dir->col,&flg);
            CHKERRQ(ierr);
            if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"row and column permutations must equal");
            ierr = ISDestroy(&dir->col);
            CHKERRQ(ierr); /* only pass one ordering into CholeskyFactor */

            flg  = PETSC_FALSE;
            ierr = PetscOptionsGetBool(((PetscObject)pc)->options,((PetscObject)pc)->prefix,"-pc_factor_nonzeros_along_diagonal",&flg,NULL);
            CHKERRQ(ierr);
            if (flg) {
                PetscReal tol = 1.e-10;
                ierr = PetscOptionsGetReal(((PetscObject)pc)->options,((PetscObject)pc)->prefix,"-pc_factor_nonzeros_along_diagonal",&tol,NULL);
                CHKERRQ(ierr);
                ierr = MatReorderForNonzeroDiagonal(pc->pmat,tol,dir->row,dir->row);
                CHKERRQ(ierr);
            }
            if (dir->row) {
                ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)dir->row);
                CHKERRQ(ierr);
            }
            if (!((PC_Factor*)dir)->fact) {
                ierr = MatGetFactor(pc->pmat,((PC_Factor*)dir)->solvertype,MAT_FACTOR_CHOLESKY,&((PC_Factor*)dir)->fact);
                CHKERRQ(ierr);
            }
            ierr                = MatCholeskyFactorSymbolic(((PC_Factor*)dir)->fact,pc->pmat,dir->row,&((PC_Factor*)dir)->info);
            CHKERRQ(ierr);
            ierr                = MatGetInfo(((PC_Factor*)dir)->fact,MAT_LOCAL,&info);
            CHKERRQ(ierr);
            dir->hdr.actualfill = info.fill_ratio_needed;
            ierr                = PetscLogObjectParent((PetscObject)pc,(PetscObject)((PC_Factor*)dir)->fact);
            CHKERRQ(ierr);
        } else if (pc->flag != SAME_NONZERO_PATTERN) {
            if (!dir->hdr.reuseordering) {
                ierr = ISDestroy(&dir->row);
                CHKERRQ(ierr);
                ierr = MatGetOrdering(pc->pmat,((PC_Factor*)dir)->ordering,&dir->row,&dir->col);
                CHKERRQ(ierr);
                ierr = ISDestroy(&dir->col);
                CHKERRQ(ierr); /* only use dir->row ordering in CholeskyFactor */

                flg  = PETSC_FALSE;
                ierr = PetscOptionsGetBool(((PetscObject)pc)->options,((PetscObject)pc)->prefix,"-pc_factor_nonzeros_along_diagonal",&flg,NULL);
                CHKERRQ(ierr);
                if (flg) {
                    PetscReal tol = 1.e-10;
                    ierr = PetscOptionsGetReal(((PetscObject)pc)->options,((PetscObject)pc)->prefix,"-pc_factor_nonzeros_along_diagonal",&tol,NULL);
                    CHKERRQ(ierr);
                    ierr = MatReorderForNonzeroDiagonal(pc->pmat,tol,dir->row,dir->row);
                    CHKERRQ(ierr);
                }
                if (dir->row) {
                    ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)dir->row);
                    CHKERRQ(ierr);
                }
            }
            ierr                = MatDestroy(&((PC_Factor*)dir)->fact);
            CHKERRQ(ierr);
            ierr                = MatGetFactor(pc->pmat,((PC_Factor*)dir)->solvertype,MAT_FACTOR_CHOLESKY,&((PC_Factor*)dir)->fact);
            CHKERRQ(ierr);
            ierr                = MatCholeskyFactorSymbolic(((PC_Factor*)dir)->fact,pc->pmat,dir->row,&((PC_Factor*)dir)->info);
            CHKERRQ(ierr);
            ierr                = MatGetInfo(((PC_Factor*)dir)->fact,MAT_LOCAL,&info);
            CHKERRQ(ierr);
            dir->hdr.actualfill = info.fill_ratio_needed;
            ierr                = PetscLogObjectParent((PetscObject)pc,(PetscObject)((PC_Factor*)dir)->fact);
            CHKERRQ(ierr);
        } else {
            ierr = MatFactorGetError(((PC_Factor*)dir)->fact,&err);
            CHKERRQ(ierr);
            if (err == MAT_FACTOR_NUMERIC_ZEROPIVOT) {
                ierr = MatFactorClearError(((PC_Factor*)dir)->fact);
                CHKERRQ(ierr);
                pc->failedreason = PC_NOERROR;
            }
        }
        ierr = MatFactorGetError(((PC_Factor*)dir)->fact,&err);
        CHKERRQ(ierr);
        if (err) { /* FactorSymbolic() fails */
            pc->failedreason = (PCFailedReason)err;
            PetscFunctionReturn(0);
        }

        ierr = MatCholeskyFactorNumeric(((PC_Factor*)dir)->fact,pc->pmat,&((PC_Factor*)dir)->info);
        CHKERRQ(ierr);
        ierr = MatFactorGetError(((PC_Factor*)dir)->fact,&err);
        CHKERRQ(ierr);
        if (err) { /* FactorNumeric() fails */
            pc->failedreason = (PCFailedReason)err;
        }
    }

    ierr = PCFactorGetMatSolverPackage(pc,&stype);
    CHKERRQ(ierr);
    if (!stype) {
        const MatSolverPackage solverpackage;
        ierr = MatFactorGetSolverPackage(((PC_Factor*)dir)->fact,&solverpackage);
        CHKERRQ(ierr);
        ierr = PCFactorSetMatSolverPackage(pc,solverpackage);
        CHKERRQ(ierr);
    }
    PetscFunctionReturn(0);
}