xref: /petsc/src/ksp/pc/impls/factor/cholesky/cholesky.c (revision 075768bc809001225c61399c80901bb8d8a18b20)
1dba47a55SKris Buschelman #define PETSCKSP_DLL
29b54502bSHong Zhang 
39b54502bSHong Zhang /*
49b54502bSHong Zhang    Defines a direct factorization preconditioner for any Mat implementation
59b54502bSHong Zhang    Note: this need not be consided a preconditioner since it supplies
69b54502bSHong Zhang          a direct solver.
79b54502bSHong Zhang */
8*075768bcSBarry Smith #include "src/ksp/pc/impls/factor/factor.h"         /*I "petscpc.h" I*/
99b54502bSHong Zhang 
109b54502bSHong Zhang typedef struct {
11*075768bcSBarry Smith   PC_Factor        hdr;
129b54502bSHong Zhang   PetscReal        actualfill;       /* actual fill in factor */
139b54502bSHong Zhang   PetscTruth       inplace;          /* flag indicating in-place factorization */
149b54502bSHong Zhang   IS               row,col;          /* index sets used for reordering */
159b54502bSHong Zhang   PetscTruth       reuseordering;    /* reuses previous reordering computed */
169b54502bSHong Zhang   PetscTruth       reusefill;        /* reuse fill from previous Cholesky */
179b54502bSHong Zhang } PC_Cholesky;
189b54502bSHong Zhang 
199b54502bSHong Zhang EXTERN_C_BEGIN
209b54502bSHong Zhang #undef __FUNCT__
21a541d17aSBarry Smith #define __FUNCT__ "PCFactorSetMatSolverPackage_Cholesky"
22c7393fdbSBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetMatSolverPackage_Cholesky(PC pc,const MatSolverPackage stype)
23c62fe420SBarry Smith {
24c62fe420SBarry Smith   PetscErrorCode ierr;
2535bd34faSBarry Smith   PC_Cholesky    *cholesky = (PC_Cholesky*)pc->data;
26c62fe420SBarry Smith 
27c62fe420SBarry Smith   PetscFunctionBegin;
28*075768bcSBarry Smith   if (((PC_Factor*)cholesky)->fact) {
2935bd34faSBarry Smith     const MatSolverPackage ltype;
3035bd34faSBarry Smith     PetscTruth             flg;
31*075768bcSBarry Smith     ierr = MatFactorGetSolverPackage(((PC_Factor*)cholesky)->fact,&ltype);CHKERRQ(ierr);
3235bd34faSBarry Smith     ierr = PetscStrcmp(stype,ltype,&flg);CHKERRQ(ierr);
3335bd34faSBarry Smith     if (!flg) {
3435bd34faSBarry Smith       SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot change solver matrix package after PC has been setup or used");
3535bd34faSBarry Smith     }
3635bd34faSBarry Smith   }
37*075768bcSBarry Smith   ierr = PetscStrfree(((PC_Factor*)cholesky)->solvertype);CHKERRQ(ierr);
38*075768bcSBarry Smith   ierr = PetscStrallocpy(stype,&((PC_Factor*)cholesky)->solvertype);CHKERRQ(ierr);
39c62fe420SBarry Smith   PetscFunctionReturn(0);
40c62fe420SBarry Smith }
41c62fe420SBarry Smith EXTERN_C_END
42c62fe420SBarry Smith 
43c62fe420SBarry Smith EXTERN_C_BEGIN
44c62fe420SBarry Smith #undef __FUNCT__
45afaefe49SHong Zhang #define __FUNCT__ "PCFactorSetZeroPivot_Cholesky"
46dba47a55SKris Buschelman PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetZeroPivot_Cholesky(PC pc,PetscReal z)
47afaefe49SHong Zhang {
48*075768bcSBarry Smith   PC_Cholesky *ch = (PC_Cholesky*)pc->data;
49afaefe49SHong Zhang 
50afaefe49SHong Zhang   PetscFunctionBegin;
51*075768bcSBarry Smith   ((PC_Factor*)ch)->info.zeropivot = z;
52afaefe49SHong Zhang   PetscFunctionReturn(0);
53afaefe49SHong Zhang }
54afaefe49SHong Zhang EXTERN_C_END
55afaefe49SHong Zhang 
56afaefe49SHong Zhang EXTERN_C_BEGIN
57afaefe49SHong Zhang #undef __FUNCT__
58afaefe49SHong Zhang #define __FUNCT__ "PCFactorSetShiftNonzero_Cholesky"
59dba47a55SKris Buschelman PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetShiftNonzero_Cholesky(PC pc,PetscReal shift)
60afaefe49SHong Zhang {
61afaefe49SHong Zhang   PC_Cholesky *dir;
62afaefe49SHong Zhang 
63afaefe49SHong Zhang   PetscFunctionBegin;
64afaefe49SHong Zhang   dir = (PC_Cholesky*)pc->data;
65afaefe49SHong Zhang   if (shift == (PetscReal) PETSC_DECIDE) {
66*075768bcSBarry Smith     ((PC_Factor*)dir)->info.shiftnz = 1.e-12;
67afaefe49SHong Zhang   } else {
68*075768bcSBarry Smith     ((PC_Factor*)dir)->info.shiftnz = shift;
69afaefe49SHong Zhang   }
70afaefe49SHong Zhang   PetscFunctionReturn(0);
71afaefe49SHong Zhang }
72afaefe49SHong Zhang EXTERN_C_END
73afaefe49SHong Zhang 
74afaefe49SHong Zhang EXTERN_C_BEGIN
75afaefe49SHong Zhang #undef __FUNCT__
76afaefe49SHong Zhang #define __FUNCT__ "PCFactorSetShiftPd_Cholesky"
77dba47a55SKris Buschelman PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetShiftPd_Cholesky(PC pc,PetscTruth shift)
78afaefe49SHong Zhang {
79afaefe49SHong Zhang   PC_Cholesky *dir;
80afaefe49SHong Zhang 
81afaefe49SHong Zhang   PetscFunctionBegin;
82afaefe49SHong Zhang   dir = (PC_Cholesky*)pc->data;
83fbf22428SSatish Balay   if (shift) {
84*075768bcSBarry Smith     ((PC_Factor*)dir)->info.shiftpd = 1.0;
85fbf22428SSatish Balay   } else {
86*075768bcSBarry Smith     ((PC_Factor*)dir)->info.shiftpd = 0.0;
87fbf22428SSatish Balay   }
88afaefe49SHong Zhang   PetscFunctionReturn(0);
89afaefe49SHong Zhang }
90afaefe49SHong Zhang EXTERN_C_END
91afaefe49SHong Zhang 
92afaefe49SHong Zhang EXTERN_C_BEGIN
93afaefe49SHong Zhang #undef __FUNCT__
942401956bSBarry Smith #define __FUNCT__ "PCFactorSetReuseOrdering_Cholesky"
952401956bSBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetReuseOrdering_Cholesky(PC pc,PetscTruth flag)
969b54502bSHong Zhang {
979b54502bSHong Zhang   PC_Cholesky *lu;
989b54502bSHong Zhang 
999b54502bSHong Zhang   PetscFunctionBegin;
1009b54502bSHong Zhang   lu               = (PC_Cholesky*)pc->data;
1019b54502bSHong Zhang   lu->reuseordering = flag;
1029b54502bSHong Zhang   PetscFunctionReturn(0);
1039b54502bSHong Zhang }
1049b54502bSHong Zhang EXTERN_C_END
1059b54502bSHong Zhang 
1069b54502bSHong Zhang EXTERN_C_BEGIN
1079b54502bSHong Zhang #undef __FUNCT__
1082401956bSBarry Smith #define __FUNCT__ "PCFactorSetReuseFill_Cholesky"
1092401956bSBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetReuseFill_Cholesky(PC pc,PetscTruth flag)
1109b54502bSHong Zhang {
1119b54502bSHong Zhang   PC_Cholesky *lu;
1129b54502bSHong Zhang 
1139b54502bSHong Zhang   PetscFunctionBegin;
1149b54502bSHong Zhang   lu = (PC_Cholesky*)pc->data;
1159b54502bSHong Zhang   lu->reusefill = flag;
1169b54502bSHong Zhang   PetscFunctionReturn(0);
1179b54502bSHong Zhang }
1189b54502bSHong Zhang EXTERN_C_END
1199b54502bSHong Zhang 
1209b54502bSHong Zhang #undef __FUNCT__
1219b54502bSHong Zhang #define __FUNCT__ "PCSetFromOptions_Cholesky"
1229b54502bSHong Zhang static PetscErrorCode PCSetFromOptions_Cholesky(PC pc)
1239b54502bSHong Zhang {
1249b54502bSHong Zhang   PC_Cholesky    *lu = (PC_Cholesky*)pc->data;
1259b54502bSHong Zhang   PetscErrorCode ierr;
1269b54502bSHong Zhang   PetscTruth     flg;
1275c9eb25fSBarry Smith   char           tname[256], solvertype[64];
1289b54502bSHong Zhang   PetscFList     ordlist;
1299b54502bSHong Zhang 
1309b54502bSHong Zhang   PetscFunctionBegin;
1319b54502bSHong Zhang   ierr = MatOrderingRegisterAll(PETSC_NULL);CHKERRQ(ierr);
1329b54502bSHong Zhang   ierr = PetscOptionsHead("Cholesky options");CHKERRQ(ierr);
1332401956bSBarry Smith     ierr = PetscOptionsName("-pc_factor_in_place","Form Cholesky in the same memory as the matrix","PCFactorSetUseInPlace",&flg);CHKERRQ(ierr);
1349b54502bSHong Zhang     if (flg) {
1352401956bSBarry Smith       ierr = PCFactorSetUseInPlace(pc);CHKERRQ(ierr);
1369b54502bSHong Zhang     }
137*075768bcSBarry Smith     ierr = PetscOptionsReal("-pc_factor_fill","Expected non-zeros in Cholesky/non-zeros in matrix","PCFactorSetFill",((PC_Factor*)lu)->info.fill,&((PC_Factor*)lu)->info.fill,0);CHKERRQ(ierr);
1389b54502bSHong Zhang 
1392401956bSBarry Smith     ierr = PetscOptionsName("-pc_factor_reuse_fill","Use fill from previous factorization","PCFactorSetReuseFill",&flg);CHKERRQ(ierr);
1409b54502bSHong Zhang     if (flg) {
1412401956bSBarry Smith       ierr = PCFactorSetReuseFill(pc,PETSC_TRUE);CHKERRQ(ierr);
1429b54502bSHong Zhang     }
1432401956bSBarry Smith     ierr = PetscOptionsName("-pc_factor_reuse_ordering","Reuse ordering from previous factorization","PCFactorSetReuseOrdering",&flg);CHKERRQ(ierr);
1449b54502bSHong Zhang     if (flg) {
1452401956bSBarry Smith       ierr = PCFactorSetReuseOrdering(pc,PETSC_TRUE);CHKERRQ(ierr);
1469b54502bSHong Zhang     }
1479b54502bSHong Zhang 
1489b54502bSHong Zhang     ierr = MatGetOrderingList(&ordlist);CHKERRQ(ierr);
149*075768bcSBarry Smith     ierr = PetscOptionsList("-pc_factor_mat_ordering_type","Reordering to reduce nonzeros in Cholesky","PCFactorSetMatOrderingType",ordlist,((PC_Factor*)lu)->ordering,tname,256,&flg);CHKERRQ(ierr);
1509b54502bSHong Zhang     if (flg) {
151e5a9bf91SBarry Smith       ierr = PCFactorSetMatOrderingType(pc,tname);CHKERRQ(ierr);
1529b54502bSHong Zhang     }
1535c9eb25fSBarry Smith 
1545c9eb25fSBarry Smith     /* maybe should have MatGetSolverTypes(Mat,&list) like the ordering list */
155*075768bcSBarry Smith     ierr = PetscOptionsString("-pc_factor_mat_solver_package","Specific Cholesky solver to use","MatGetFactor",((PC_Factor*)lu)->solvertype,solvertype,64,&flg);CHKERRQ(ierr);
1565c9eb25fSBarry Smith     if (flg) {
157c7393fdbSBarry Smith       ierr = PCFactorSetMatSolverPackage(pc,solvertype);CHKERRQ(ierr);
1585c9eb25fSBarry Smith     }
1595c9eb25fSBarry Smith 
1609f95998fSHong Zhang     ierr = PetscOptionsName("-pc_factor_shift_nonzero","Shift added to diagonal","PCFactorSetShiftNonzero",&flg);CHKERRQ(ierr);
1619b54502bSHong Zhang     if (flg) {
162afaefe49SHong Zhang       ierr = PCFactorSetShiftNonzero(pc,(PetscReal) PETSC_DECIDE);CHKERRQ(ierr);
1639b54502bSHong Zhang     }
164*075768bcSBarry Smith     ierr = PetscOptionsReal("-pc_factor_shift_nonzero","Shift added to diagonal","PCFactorSetShiftNonzero",((PC_Factor*)lu)->info.shiftnz,&((PC_Factor*)lu)->info.shiftnz,0);CHKERRQ(ierr);
1659f95998fSHong Zhang     ierr = PetscOptionsName("-pc_factor_shift_positive_definite","Manteuffel shift applied to diagonal","PCFactorSetShiftPd",&flg);CHKERRQ(ierr);
1669b54502bSHong Zhang     if (flg) {
167afaefe49SHong Zhang       ierr = PCFactorSetShiftPd(pc,PETSC_TRUE);CHKERRQ(ierr);
1689b54502bSHong Zhang     }
169*075768bcSBarry Smith     ierr = PetscOptionsReal("-pc_factor_zeropivot","Pivot is considered zero if less than","PCFactorSetZeroPivot",((PC_Factor*)lu)->info.zeropivot,&((PC_Factor*)lu)->info.zeropivot,0);CHKERRQ(ierr);
1709b54502bSHong Zhang 
1719b54502bSHong Zhang   ierr = PetscOptionsTail();CHKERRQ(ierr);
1729b54502bSHong Zhang   PetscFunctionReturn(0);
1739b54502bSHong Zhang }
1749b54502bSHong Zhang 
1759b54502bSHong Zhang #undef __FUNCT__
1769b54502bSHong Zhang #define __FUNCT__ "PCView_Cholesky"
1779b54502bSHong Zhang static PetscErrorCode PCView_Cholesky(PC pc,PetscViewer viewer)
1789b54502bSHong Zhang {
1799b54502bSHong Zhang   PC_Cholesky    *lu = (PC_Cholesky*)pc->data;
1809b54502bSHong Zhang   PetscErrorCode ierr;
1819b54502bSHong Zhang   PetscTruth     iascii,isstring;
1829b54502bSHong Zhang 
1839b54502bSHong Zhang   PetscFunctionBegin;
1849b54502bSHong Zhang   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
1859b54502bSHong Zhang   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);CHKERRQ(ierr);
1869b54502bSHong Zhang   if (iascii) {
1879b54502bSHong Zhang 
1889b54502bSHong Zhang     if (lu->inplace) {ierr = PetscViewerASCIIPrintf(viewer,"  Cholesky: in-place factorization\n");CHKERRQ(ierr);}
1899b54502bSHong Zhang     else             {ierr = PetscViewerASCIIPrintf(viewer,"  Cholesky: out-of-place factorization\n");CHKERRQ(ierr);}
190*075768bcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    matrix ordering: %s\n",((PC_Factor*)lu)->ordering);CHKERRQ(ierr);
191*075768bcSBarry Smith     if (((PC_Factor*)lu)->fact) {
192f3a39becSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Cholesky: factor fill ratio needed %G\n",lu->actualfill);CHKERRQ(ierr);
193f3a39becSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"       Factored matrix follows\n");CHKERRQ(ierr);
194f3a39becSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
195f3a39becSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
196f3a39becSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
197f3a39becSBarry Smith       ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
198*075768bcSBarry Smith       ierr = MatView(((PC_Factor*)lu)->fact,viewer);CHKERRQ(ierr);
1999b54502bSHong Zhang       ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
200f3a39becSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
201f3a39becSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
202f3a39becSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2039b54502bSHong Zhang     }
2049b54502bSHong Zhang     if (lu->reusefill)    {ierr = PetscViewerASCIIPrintf(viewer,"       Reusing fill from past factorization\n");CHKERRQ(ierr);}
2059b54502bSHong Zhang     if (lu->reuseordering) {ierr = PetscViewerASCIIPrintf(viewer,"       Reusing reordering from past factorization\n");CHKERRQ(ierr);}
2069b54502bSHong Zhang   } else if (isstring) {
207*075768bcSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," order=%s",((PC_Factor*)lu)->ordering);CHKERRQ(ierr);CHKERRQ(ierr);
2089b54502bSHong Zhang   } else {
2092401956bSBarry Smith     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for PCCHOLESKY",((PetscObject)viewer)->type_name);
2109b54502bSHong Zhang   }
2119b54502bSHong Zhang   PetscFunctionReturn(0);
2129b54502bSHong Zhang }
2139b54502bSHong Zhang 
2149b54502bSHong Zhang #undef __FUNCT__
215a4fd02acSBarry Smith #define __FUNCT__ "PCFactorGetMatrix_Cholesky"
216a4fd02acSBarry Smith static PetscErrorCode PCFactorGetMatrix_Cholesky(PC pc,Mat *mat)
2179b54502bSHong Zhang {
2189b54502bSHong Zhang   PC_Cholesky *dir = (PC_Cholesky*)pc->data;
2199b54502bSHong Zhang 
2209b54502bSHong Zhang   PetscFunctionBegin;
221*075768bcSBarry Smith   if (!((PC_Factor*)dir)->fact) SETERRQ(PETSC_ERR_ORDER,"Matrix not yet factored; call after KSPSetUp() or PCSetUp()");
222*075768bcSBarry Smith   *mat = ((PC_Factor*)dir)->fact;
2239b54502bSHong Zhang   PetscFunctionReturn(0);
2249b54502bSHong Zhang }
2259b54502bSHong Zhang 
2269b54502bSHong Zhang #undef __FUNCT__
2279b54502bSHong Zhang #define __FUNCT__ "PCSetUp_Cholesky"
2289b54502bSHong Zhang static PetscErrorCode PCSetUp_Cholesky(PC pc)
2299b54502bSHong Zhang {
2309b54502bSHong Zhang   PetscErrorCode ierr;
2319b54502bSHong Zhang   PetscTruth     flg;
2329b54502bSHong Zhang   PC_Cholesky    *dir = (PC_Cholesky*)pc->data;
2339b54502bSHong Zhang 
2349b54502bSHong Zhang   PetscFunctionBegin;
235*075768bcSBarry Smith   if (dir->reusefill && pc->setupcalled) ((PC_Factor*)dir)->info.fill = dir->actualfill;
2369b54502bSHong Zhang 
2379b54502bSHong Zhang   if (dir->inplace) {
2389b54502bSHong Zhang     if (dir->row && dir->col && (dir->row != dir->col)) {
2399b54502bSHong Zhang       ierr = ISDestroy(dir->row);CHKERRQ(ierr);
2409b54502bSHong Zhang       dir->row = 0;
2419b54502bSHong Zhang     }
2429b54502bSHong Zhang     if (dir->col) {
2439b54502bSHong Zhang       ierr = ISDestroy(dir->col);CHKERRQ(ierr);
2449b54502bSHong Zhang       dir->col = 0;
2459b54502bSHong Zhang     }
246*075768bcSBarry Smith     ierr = MatGetOrdering(pc->pmat,((PC_Factor*)dir)->ordering,&dir->row,&dir->col);CHKERRQ(ierr);
2479b54502bSHong Zhang     if (dir->col && (dir->row != dir->col)) {  /* only use row ordering for SBAIJ */
2489b54502bSHong Zhang       ierr = ISDestroy(dir->col);CHKERRQ(ierr);
2499b54502bSHong Zhang       dir->col=0;
2509b54502bSHong Zhang     }
251efee365bSSatish Balay     if (dir->row) {ierr = PetscLogObjectParent(pc,dir->row);CHKERRQ(ierr);}
252*075768bcSBarry Smith     ierr = MatCholeskyFactor(pc->pmat,dir->row,&((PC_Factor*)dir)->info);CHKERRQ(ierr);
253*075768bcSBarry Smith     ((PC_Factor*)dir)->fact = pc->pmat;
2549b54502bSHong Zhang   } else {
2559b54502bSHong Zhang     MatInfo info;
2569b54502bSHong Zhang     if (!pc->setupcalled) {
257*075768bcSBarry Smith       ierr = MatGetOrdering(pc->pmat,((PC_Factor*)dir)->ordering,&dir->row,&dir->col);CHKERRQ(ierr);
2589bfd6278SHong Zhang       /* check if dir->row == dir->col */
2599bfd6278SHong Zhang       ierr = ISEqual(dir->row,dir->col,&flg);CHKERRQ(ierr);
2609bfd6278SHong Zhang       if (!flg) SETERRQ(PETSC_ERR_ARG_INCOMP,"row and column permutations must equal");
2619bfd6278SHong Zhang       ierr = ISDestroy(dir->col);CHKERRQ(ierr); /* only pass one ordering into CholeskyFactor */
2629b54502bSHong Zhang       dir->col=0;
2639bfd6278SHong Zhang 
2647adad957SLisandro Dalcin       ierr = PetscOptionsHasName(((PetscObject)pc)->prefix,"-pc_factor_nonzeros_along_diagonal",&flg);CHKERRQ(ierr);
2659b54502bSHong Zhang       if (flg) {
2669b54502bSHong Zhang         PetscReal tol = 1.e-10;
2677adad957SLisandro Dalcin         ierr = PetscOptionsGetReal(((PetscObject)pc)->prefix,"-pc_factor_nonzeros_along_diagonal",&tol,PETSC_NULL);CHKERRQ(ierr);
2689b54502bSHong Zhang         ierr = MatReorderForNonzeroDiagonal(pc->pmat,tol,dir->row,dir->row);CHKERRQ(ierr);
2699b54502bSHong Zhang       }
270efee365bSSatish Balay       if (dir->row) {ierr = PetscLogObjectParent(pc,dir->row);CHKERRQ(ierr);}
271*075768bcSBarry Smith       ierr = MatGetFactor(pc->pmat,((PC_Factor*)dir)->solvertype,MAT_FACTOR_CHOLESKY,&((PC_Factor*)dir)->fact);CHKERRQ(ierr);
272*075768bcSBarry Smith       ierr = MatCholeskyFactorSymbolic(((PC_Factor*)dir)->fact,pc->pmat,dir->row,&((PC_Factor*)dir)->info);CHKERRQ(ierr);
273*075768bcSBarry Smith       ierr = MatGetInfo(((PC_Factor*)dir)->fact,MAT_LOCAL,&info);CHKERRQ(ierr);
2749b54502bSHong Zhang       dir->actualfill = info.fill_ratio_needed;
275*075768bcSBarry Smith       ierr = PetscLogObjectParent(pc,((PC_Factor*)dir)->fact);CHKERRQ(ierr);
2769b54502bSHong Zhang     } else if (pc->flag != SAME_NONZERO_PATTERN) {
2779b54502bSHong Zhang       if (!dir->reuseordering) {
2789b54502bSHong Zhang         if (dir->row && dir->col && (dir->row != dir->col)) {
2799b54502bSHong Zhang           ierr = ISDestroy(dir->row);CHKERRQ(ierr);
2809b54502bSHong Zhang           dir->row = 0;
2819b54502bSHong Zhang         }
2829b54502bSHong Zhang         if (dir->col) {
2839b54502bSHong Zhang           ierr = ISDestroy(dir->col);CHKERRQ(ierr);
2849b54502bSHong Zhang           dir->col =0;
2859b54502bSHong Zhang         }
286*075768bcSBarry Smith         ierr = MatGetOrdering(pc->pmat,((PC_Factor*)dir)->ordering,&dir->row,&dir->col);CHKERRQ(ierr);
2879b54502bSHong Zhang         if (dir->col && (dir->row != dir->col)) {  /* only use row ordering for SBAIJ */
2889b54502bSHong Zhang           ierr = ISDestroy(dir->col);CHKERRQ(ierr);
2899b54502bSHong Zhang           dir->col=0;
2909b54502bSHong Zhang         }
2917adad957SLisandro Dalcin         ierr = PetscOptionsHasName(((PetscObject)pc)->prefix,"-pc_factor_nonzeros_along_diagonal",&flg);CHKERRQ(ierr);
2929b54502bSHong Zhang         if (flg) {
2939b54502bSHong Zhang           PetscReal tol = 1.e-10;
2947adad957SLisandro Dalcin           ierr = PetscOptionsGetReal(((PetscObject)pc)->prefix,"-pc_factor_nonzeros_along_diagonal",&tol,PETSC_NULL);CHKERRQ(ierr);
2959b54502bSHong Zhang           ierr = MatReorderForNonzeroDiagonal(pc->pmat,tol,dir->row,dir->row);CHKERRQ(ierr);
2969b54502bSHong Zhang         }
297efee365bSSatish Balay         if (dir->row) {ierr = PetscLogObjectParent(pc,dir->row);CHKERRQ(ierr);}
2989b54502bSHong Zhang       }
299*075768bcSBarry Smith       ierr = MatDestroy(((PC_Factor*)dir)->fact);CHKERRQ(ierr);
300*075768bcSBarry Smith       ierr = MatGetFactor(pc->pmat,((PC_Factor*)dir)->solvertype,MAT_FACTOR_CHOLESKY,&((PC_Factor*)dir)->fact);CHKERRQ(ierr);
301*075768bcSBarry Smith       ierr = MatCholeskyFactorSymbolic(((PC_Factor*)dir)->fact,pc->pmat,dir->row,&((PC_Factor*)dir)->info);CHKERRQ(ierr);
302*075768bcSBarry Smith       ierr = MatGetInfo(((PC_Factor*)dir)->fact,MAT_LOCAL,&info);CHKERRQ(ierr);
3039b54502bSHong Zhang       dir->actualfill = info.fill_ratio_needed;
304*075768bcSBarry Smith       ierr = PetscLogObjectParent(pc,((PC_Factor*)dir)->fact);CHKERRQ(ierr);
3059b54502bSHong Zhang     }
306*075768bcSBarry Smith     ierr = MatCholeskyFactorNumeric(((PC_Factor*)dir)->fact,pc->pmat,&((PC_Factor*)dir)->info);CHKERRQ(ierr);
3079b54502bSHong Zhang   }
3089b54502bSHong Zhang   PetscFunctionReturn(0);
3099b54502bSHong Zhang }
3109b54502bSHong Zhang 
3119b54502bSHong Zhang #undef __FUNCT__
3129b54502bSHong Zhang #define __FUNCT__ "PCDestroy_Cholesky"
3139b54502bSHong Zhang static PetscErrorCode PCDestroy_Cholesky(PC pc)
3149b54502bSHong Zhang {
3159b54502bSHong Zhang   PC_Cholesky    *dir = (PC_Cholesky*)pc->data;
3169b54502bSHong Zhang   PetscErrorCode ierr;
3179b54502bSHong Zhang 
3189b54502bSHong Zhang   PetscFunctionBegin;
319*075768bcSBarry Smith   if (!dir->inplace && ((PC_Factor*)dir)->fact) {ierr = MatDestroy(((PC_Factor*)dir)->fact);CHKERRQ(ierr);}
3209b54502bSHong Zhang   if (dir->row) {ierr = ISDestroy(dir->row);CHKERRQ(ierr);}
3219b54502bSHong Zhang   if (dir->col) {ierr = ISDestroy(dir->col);CHKERRQ(ierr);}
322*075768bcSBarry Smith   ierr = PetscStrfree(((PC_Factor*)dir)->ordering);CHKERRQ(ierr);
323*075768bcSBarry Smith   ierr = PetscStrfree(((PC_Factor*)dir)->solvertype);CHKERRQ(ierr);
3249b54502bSHong Zhang   ierr = PetscFree(dir);CHKERRQ(ierr);
3259b54502bSHong Zhang   PetscFunctionReturn(0);
3269b54502bSHong Zhang }
3279b54502bSHong Zhang 
3289b54502bSHong Zhang #undef __FUNCT__
3299b54502bSHong Zhang #define __FUNCT__ "PCApply_Cholesky"
3309b54502bSHong Zhang static PetscErrorCode PCApply_Cholesky(PC pc,Vec x,Vec y)
3319b54502bSHong Zhang {
3329b54502bSHong Zhang   PC_Cholesky    *dir = (PC_Cholesky*)pc->data;
3339b54502bSHong Zhang   PetscErrorCode ierr;
3349b54502bSHong Zhang 
3359b54502bSHong Zhang   PetscFunctionBegin;
3369b54502bSHong Zhang   if (dir->inplace) {ierr = MatSolve(pc->pmat,x,y);CHKERRQ(ierr);}
337*075768bcSBarry Smith   else              {ierr = MatSolve(((PC_Factor*)dir)->fact,x,y);CHKERRQ(ierr);}
3389b54502bSHong Zhang   PetscFunctionReturn(0);
3399b54502bSHong Zhang }
3409b54502bSHong Zhang 
3419b54502bSHong Zhang #undef __FUNCT__
3429b54502bSHong Zhang #define __FUNCT__ "PCApplyTranspose_Cholesky"
3439b54502bSHong Zhang static PetscErrorCode PCApplyTranspose_Cholesky(PC pc,Vec x,Vec y)
3449b54502bSHong Zhang {
3459b54502bSHong Zhang   PC_Cholesky    *dir = (PC_Cholesky*)pc->data;
3469b54502bSHong Zhang   PetscErrorCode ierr;
3479b54502bSHong Zhang 
3489b54502bSHong Zhang   PetscFunctionBegin;
3499b54502bSHong Zhang   if (dir->inplace) {ierr = MatSolveTranspose(pc->pmat,x,y);CHKERRQ(ierr);}
350*075768bcSBarry Smith   else              {ierr = MatSolveTranspose(((PC_Factor*)dir)->fact,x,y);CHKERRQ(ierr);}
3519b54502bSHong Zhang   PetscFunctionReturn(0);
3529b54502bSHong Zhang }
3539b54502bSHong Zhang 
3549b54502bSHong Zhang /* -----------------------------------------------------------------------------------*/
3559b54502bSHong Zhang 
3569b54502bSHong Zhang EXTERN_C_BEGIN
3579b54502bSHong Zhang #undef __FUNCT__
35855ba2a51SBarry Smith #define __FUNCT__ "PCFactorSetFill_Cholesky"
35955ba2a51SBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetFill_Cholesky(PC pc,PetscReal fill)
3609b54502bSHong Zhang {
3619b54502bSHong Zhang   PC_Cholesky *dir;
3629b54502bSHong Zhang 
3639b54502bSHong Zhang   PetscFunctionBegin;
3649b54502bSHong Zhang   dir = (PC_Cholesky*)pc->data;
365*075768bcSBarry Smith   ((PC_Factor*)dir)->info.fill = fill;
3669b54502bSHong Zhang   PetscFunctionReturn(0);
3679b54502bSHong Zhang }
3689b54502bSHong Zhang EXTERN_C_END
3699b54502bSHong Zhang 
3709b54502bSHong Zhang EXTERN_C_BEGIN
3719b54502bSHong Zhang #undef __FUNCT__
3722401956bSBarry Smith #define __FUNCT__ "PCFactorSetUseInPlace_Cholesky"
3732401956bSBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetUseInPlace_Cholesky(PC pc)
3749b54502bSHong Zhang {
3759b54502bSHong Zhang   PC_Cholesky *dir;
3769b54502bSHong Zhang 
3779b54502bSHong Zhang   PetscFunctionBegin;
3789b54502bSHong Zhang   dir = (PC_Cholesky*)pc->data;
3799b54502bSHong Zhang   dir->inplace = PETSC_TRUE;
3809b54502bSHong Zhang   PetscFunctionReturn(0);
3819b54502bSHong Zhang }
3829b54502bSHong Zhang EXTERN_C_END
3839b54502bSHong Zhang 
3849b54502bSHong Zhang EXTERN_C_BEGIN
3859b54502bSHong Zhang #undef __FUNCT__
386e5a9bf91SBarry Smith #define __FUNCT__ "PCFactorSetMatOrderingType_Cholesky"
387e36ff184SSatish Balay PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetMatOrderingType_Cholesky(PC pc,const MatOrderingType ordering)
3889b54502bSHong Zhang {
3899b54502bSHong Zhang   PC_Cholesky    *dir = (PC_Cholesky*)pc->data;
3909b54502bSHong Zhang   PetscErrorCode ierr;
3919b54502bSHong Zhang 
3929b54502bSHong Zhang   PetscFunctionBegin;
393*075768bcSBarry Smith   ierr = PetscStrfree(((PC_Factor*)dir)->ordering);CHKERRQ(ierr);
394*075768bcSBarry Smith   ierr = PetscStrallocpy(ordering,&((PC_Factor*)dir)->ordering);CHKERRQ(ierr);
3959b54502bSHong Zhang   PetscFunctionReturn(0);
3969b54502bSHong Zhang }
3979b54502bSHong Zhang EXTERN_C_END
3989b54502bSHong Zhang 
3999b54502bSHong Zhang /* -----------------------------------------------------------------------------------*/
4009b54502bSHong Zhang 
4019b54502bSHong Zhang #undef __FUNCT__
4022401956bSBarry Smith #define __FUNCT__ "PCFactorSetReuseOrdering"
4039b54502bSHong Zhang /*@
4042401956bSBarry Smith    PCFactorSetReuseOrdering - When similar matrices are factored, this
4059b54502bSHong Zhang    causes the ordering computed in the first factor to be used for all
4069b54502bSHong Zhang    following factors.
4079b54502bSHong Zhang 
4089b54502bSHong Zhang    Collective on PC
4099b54502bSHong Zhang 
4109b54502bSHong Zhang    Input Parameters:
4119b54502bSHong Zhang +  pc - the preconditioner context
4129b54502bSHong Zhang -  flag - PETSC_TRUE to reuse else PETSC_FALSE
4139b54502bSHong Zhang 
4149b54502bSHong Zhang    Options Database Key:
4152401956bSBarry Smith .  -pc_factor_reuse_ordering - Activate PCFactorSetReuseOrdering()
4169b54502bSHong Zhang 
4179b54502bSHong Zhang    Level: intermediate
4189b54502bSHong Zhang 
4199b54502bSHong Zhang .keywords: PC, levels, reordering, factorization, incomplete, LU
4209b54502bSHong Zhang 
4212401956bSBarry Smith .seealso: PCFactorSetReuseFill()
4229b54502bSHong Zhang @*/
4232401956bSBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetReuseOrdering(PC pc,PetscTruth flag)
4249b54502bSHong Zhang {
4259b54502bSHong Zhang   PetscErrorCode ierr,(*f)(PC,PetscTruth);
4269b54502bSHong Zhang 
4279b54502bSHong Zhang   PetscFunctionBegin;
4289b54502bSHong Zhang   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
4292401956bSBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCFactorSetReuseOrdering_C",(void (**)(void))&f);CHKERRQ(ierr);
4309b54502bSHong Zhang   if (f) {
4319b54502bSHong Zhang     ierr = (*f)(pc,flag);CHKERRQ(ierr);
4329b54502bSHong Zhang   }
4339b54502bSHong Zhang   PetscFunctionReturn(0);
4349b54502bSHong Zhang }
4359b54502bSHong Zhang 
4369b54502bSHong Zhang #undef __FUNCT__
4372401956bSBarry Smith #define __FUNCT__ "PCFactorSetReuseFill"
4389b54502bSHong Zhang /*@
4392401956bSBarry Smith    PCFactorSetReuseFill - When matrices with same different nonzero structure are factored,
4402401956bSBarry Smith    this causes later ones to use the fill ratio computed in the initial factorization.
4419b54502bSHong Zhang 
4429b54502bSHong Zhang    Collective on PC
4439b54502bSHong Zhang 
4449b54502bSHong Zhang    Input Parameters:
4459b54502bSHong Zhang +  pc - the preconditioner context
4469b54502bSHong Zhang -  flag - PETSC_TRUE to reuse else PETSC_FALSE
4479b54502bSHong Zhang 
4489b54502bSHong Zhang    Options Database Key:
4492401956bSBarry Smith .  -pc_factor_reuse_fill - Activates PCFactorSetReuseFill()
4509b54502bSHong Zhang 
4519b54502bSHong Zhang    Level: intermediate
4529b54502bSHong Zhang 
4539b54502bSHong Zhang .keywords: PC, levels, reordering, factorization, incomplete, Cholesky
4549b54502bSHong Zhang 
4552401956bSBarry Smith .seealso: PCFactorSetReuseOrdering()
4569b54502bSHong Zhang @*/
4572401956bSBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetReuseFill(PC pc,PetscTruth flag)
4589b54502bSHong Zhang {
4599b54502bSHong Zhang   PetscErrorCode ierr,(*f)(PC,PetscTruth);
4609b54502bSHong Zhang 
4619b54502bSHong Zhang   PetscFunctionBegin;
4629b54502bSHong Zhang   PetscValidHeaderSpecific(pc,PC_COOKIE,2);
4632401956bSBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCFactorSetReuseFill_C",(void (**)(void))&f);CHKERRQ(ierr);
4649b54502bSHong Zhang   if (f) {
4659b54502bSHong Zhang     ierr = (*f)(pc,flag);CHKERRQ(ierr);
4669b54502bSHong Zhang   }
4679b54502bSHong Zhang   PetscFunctionReturn(0);
4689b54502bSHong Zhang }
4699b54502bSHong Zhang 
4709b54502bSHong Zhang /*MC
47196fc60bcSBarry Smith    PCCHOLESKY - Uses a direct solver, based on Cholesky factorization, as a preconditioner
4729b54502bSHong Zhang 
4739b54502bSHong Zhang    Options Database Keys:
4742401956bSBarry Smith +  -pc_factor_reuse_ordering - Activate PCFactorSetReuseOrdering()
475c7393fdbSBarry Smith .  -pc_factor_mat_solver_package - Actives PCFactorSetMatSolverPackage() to choose the direct solver, like spooles
4762401956bSBarry Smith .  -pc_factor_reuse_fill - Activates PCFactorSetReuseFill()
47755ba2a51SBarry Smith .  -pc_factor_fill <fill> - Sets fill amount
4782401956bSBarry Smith .  -pc_factor_in_place - Activates in-place factorization
4792401956bSBarry Smith .  -pc_factor_mat_ordering_type <nd,rcm,...> - Sets ordering routine
480f251bdbdSHong Zhang .  -pc_factor_shift_nonzero <shift> - Sets shift amount or PETSC_DECIDE for the default
481f251bdbdSHong Zhang -  -pc_factor_shift_positive_definite [PETSC_TRUE/PETSC_FALSE] - Activate/Deactivate PCFactorSetShiftPd(); the value
482f251bdbdSHong Zhang    is optional with PETSC_TRUE being the default
4839b54502bSHong Zhang 
4849b54502bSHong Zhang    Notes: Not all options work for all matrix formats
4859b54502bSHong Zhang 
4869b54502bSHong Zhang    Level: beginner
4879b54502bSHong Zhang 
4889b54502bSHong Zhang    Concepts: Cholesky factorization, direct solver
4899b54502bSHong Zhang 
4909b54502bSHong Zhang    Notes: Usually this will compute an "exact" solution in one iteration and does
4919b54502bSHong Zhang           not need a Krylov method (i.e. you can use -ksp_type preonly, or
4929b54502bSHong Zhang           KSPSetType(ksp,KSPPREONLY) for the Krylov method
4939b54502bSHong Zhang 
4949b54502bSHong Zhang .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
495a4fd02acSBarry Smith            PCILU, PCLU, PCICC, PCFactorSetReuseOrdering(), PCFactorSetReuseFill(), PCFactorGetMatrix(),
49655ba2a51SBarry Smith            PCFactorSetFill(), PCFactorSetShiftNonzero(), PCFactorSetShiftPd(),
497e5a9bf91SBarry Smith 	   PCFactorSetUseInPlace(), PCFactorSetMatOrderingType(),PCFactorSetShiftNonzero(),PCFactorSetShiftPd()
4989b54502bSHong Zhang 
4999b54502bSHong Zhang M*/
5009b54502bSHong Zhang 
5019b54502bSHong Zhang EXTERN_C_BEGIN
5029b54502bSHong Zhang #undef __FUNCT__
5039b54502bSHong Zhang #define __FUNCT__ "PCCreate_Cholesky"
504dba47a55SKris Buschelman PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_Cholesky(PC pc)
5059b54502bSHong Zhang {
5069b54502bSHong Zhang   PetscErrorCode ierr;
5079b54502bSHong Zhang   PC_Cholesky    *dir;
5089b54502bSHong Zhang 
5099b54502bSHong Zhang   PetscFunctionBegin;
51038f2d2fdSLisandro Dalcin   ierr = PetscNewLog(pc,PC_Cholesky,&dir);CHKERRQ(ierr);
5119b54502bSHong Zhang 
512*075768bcSBarry Smith   ((PC_Factor*)dir)->fact                   = 0;
5139b54502bSHong Zhang   dir->inplace                = PETSC_FALSE;
514*075768bcSBarry Smith   ierr = MatFactorInfoInitialize(&((PC_Factor*)dir)->info);CHKERRQ(ierr);
515*075768bcSBarry Smith   ((PC_Factor*)dir)->info.fill              = 5.0;
516*075768bcSBarry Smith   ((PC_Factor*)dir)->info.shiftnz           = 0.0;
517*075768bcSBarry Smith   ((PC_Factor*)dir)->info.shiftpd           = 0.0; /* false */
518*075768bcSBarry Smith   ((PC_Factor*)dir)->info.pivotinblocks     = 1.0;
5199b54502bSHong Zhang   dir->col                    = 0;
5209b54502bSHong Zhang   dir->row                    = 0;
521*075768bcSBarry Smith   ierr = PetscStrallocpy(MATORDERING_NATURAL,&((PC_Factor*)dir)->ordering);CHKERRQ(ierr);
522*075768bcSBarry Smith   ierr = PetscStrallocpy(MAT_SOLVER_PETSC,&((PC_Factor*)dir)->solvertype);CHKERRQ(ierr);
5239b54502bSHong Zhang   dir->reusefill        = PETSC_FALSE;
5249b54502bSHong Zhang   dir->reuseordering    = PETSC_FALSE;
5259b54502bSHong Zhang   pc->data              = (void*)dir;
5269b54502bSHong Zhang 
5279b54502bSHong Zhang   pc->ops->destroy           = PCDestroy_Cholesky;
5289b54502bSHong Zhang   pc->ops->apply             = PCApply_Cholesky;
5299b54502bSHong Zhang   pc->ops->applytranspose    = PCApplyTranspose_Cholesky;
5309b54502bSHong Zhang   pc->ops->setup             = PCSetUp_Cholesky;
5319b54502bSHong Zhang   pc->ops->setfromoptions    = PCSetFromOptions_Cholesky;
5329b54502bSHong Zhang   pc->ops->view              = PCView_Cholesky;
5339b54502bSHong Zhang   pc->ops->applyrichardson   = 0;
534a4fd02acSBarry Smith   pc->ops->getfactoredmatrix = PCFactorGetMatrix_Cholesky;
5359b54502bSHong Zhang 
536c7393fdbSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetMatSolverPackage_C","PCFactorSetMatSolverPackage_Cholesky",
537c7393fdbSBarry Smith                     PCFactorSetMatSolverPackage_Cholesky);CHKERRQ(ierr);
538afaefe49SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetZeroPivot_C","PCFactorSetZeroPivot_Cholesky",
539afaefe49SHong Zhang                     PCFactorSetZeroPivot_Cholesky);CHKERRQ(ierr);
540afaefe49SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftNonzero_C","PCFactorSetShiftNonzero_Cholesky",
541afaefe49SHong Zhang                     PCFactorSetShiftNonzero_Cholesky);CHKERRQ(ierr);
542afaefe49SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftPd_C","PCFactorSetShiftPd_Cholesky",
543afaefe49SHong Zhang                     PCFactorSetShiftPd_Cholesky);CHKERRQ(ierr);
544afaefe49SHong Zhang 
54555ba2a51SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetFill_C","PCFactorSetFill_Cholesky",
54655ba2a51SBarry Smith                     PCFactorSetFill_Cholesky);CHKERRQ(ierr);
5472401956bSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetUseInPlace_C","PCFactorSetUseInPlace_Cholesky",
5482401956bSBarry Smith                     PCFactorSetUseInPlace_Cholesky);CHKERRQ(ierr);
549e5a9bf91SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetMatOrderingType_C","PCFactorSetMatOrderingType_Cholesky",
550e5a9bf91SBarry Smith                     PCFactorSetMatOrderingType_Cholesky);CHKERRQ(ierr);
5512401956bSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetReuseOrdering_C","PCFactorSetReuseOrdering_Cholesky",
5522401956bSBarry Smith                     PCFactorSetReuseOrdering_Cholesky);CHKERRQ(ierr);
5532401956bSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetReuseFill_C","PCFactorSetReuseFill_Cholesky",
5542401956bSBarry Smith                     PCFactorSetReuseFill_Cholesky);CHKERRQ(ierr);
5559b54502bSHong Zhang   PetscFunctionReturn(0);
5569b54502bSHong Zhang }
5579b54502bSHong Zhang EXTERN_C_END
558