xref: /petsc/src/ksp/pc/impls/factor/icc/icc.c (revision 8ff23777322cfdc407588772804a6ce977f33084)
1dba47a55SKris Buschelman #define PETSCKSP_DLL
2dba47a55SKris Buschelman 
37c4f633dSBarry Smith #include "../src/ksp/pc/impls/factor/icc/icc.h"   /*I "petscpc.h" I*/
49b54502bSHong Zhang 
59b54502bSHong Zhang #undef __FUNCT__
69b54502bSHong Zhang #define __FUNCT__ "PCSetup_ICC"
79b54502bSHong Zhang static PetscErrorCode PCSetup_ICC(PC pc)
89b54502bSHong Zhang {
99b54502bSHong Zhang   PC_ICC         *icc = (PC_ICC*)pc->data;
109b54502bSHong Zhang   IS             perm,cperm;
119b54502bSHong Zhang   PetscErrorCode ierr;
12f3a39becSBarry Smith   MatInfo        info;
139b54502bSHong Zhang 
149b54502bSHong Zhang   PetscFunctionBegin;
15075768bcSBarry Smith   ierr = MatGetOrdering(pc->pmat, ((PC_Factor*)icc)->ordering,&perm,&cperm);CHKERRQ(ierr);
169b54502bSHong Zhang 
179b54502bSHong Zhang   if (!pc->setupcalled) {
18075768bcSBarry Smith     ierr = MatGetFactor(pc->pmat,MAT_SOLVER_PETSC,MAT_FACTOR_ICC,& ((PC_Factor*)icc)->fact);CHKERRQ(ierr);
19075768bcSBarry Smith     ierr = MatICCFactorSymbolic(((PC_Factor*)icc)->fact,pc->pmat,perm,&((PC_Factor*)icc)->info);CHKERRQ(ierr);
209b54502bSHong Zhang   } else if (pc->flag != SAME_NONZERO_PATTERN) {
21075768bcSBarry Smith     ierr = MatDestroy(((PC_Factor*)icc)->fact);CHKERRQ(ierr);
22075768bcSBarry Smith     ierr = MatGetFactor(pc->pmat,MAT_SOLVER_PETSC,MAT_FACTOR_ICC,&((PC_Factor*)icc)->fact);CHKERRQ(ierr);
23075768bcSBarry Smith     ierr = MatICCFactorSymbolic(((PC_Factor*)icc)->fact,pc->pmat,perm,&((PC_Factor*)icc)->info);CHKERRQ(ierr);
249b54502bSHong Zhang   }
25075768bcSBarry Smith   ierr = MatGetInfo(((PC_Factor*)icc)->fact,MAT_LOCAL,&info);CHKERRQ(ierr);
26f3a39becSBarry Smith   icc->actualfill = info.fill_ratio_needed;
27f3a39becSBarry Smith 
289b54502bSHong Zhang   ierr = ISDestroy(cperm);CHKERRQ(ierr);
299b54502bSHong Zhang   ierr = ISDestroy(perm);CHKERRQ(ierr);
30075768bcSBarry Smith   ierr = MatCholeskyFactorNumeric(((PC_Factor*)icc)->fact,pc->pmat,&((PC_Factor*)icc)->info);CHKERRQ(ierr);
319b54502bSHong Zhang   PetscFunctionReturn(0);
329b54502bSHong Zhang }
339b54502bSHong Zhang 
349b54502bSHong Zhang #undef __FUNCT__
359b54502bSHong Zhang #define __FUNCT__ "PCDestroy_ICC"
369b54502bSHong Zhang static PetscErrorCode PCDestroy_ICC(PC pc)
379b54502bSHong Zhang {
389b54502bSHong Zhang   PC_ICC         *icc = (PC_ICC*)pc->data;
399b54502bSHong Zhang   PetscErrorCode ierr;
409b54502bSHong Zhang 
419b54502bSHong Zhang   PetscFunctionBegin;
42075768bcSBarry Smith   if (((PC_Factor*)icc)->fact) {ierr = MatDestroy(((PC_Factor*)icc)->fact);CHKERRQ(ierr);}
43075768bcSBarry Smith   ierr = PetscStrfree(((PC_Factor*)icc)->ordering);CHKERRQ(ierr);
449b54502bSHong Zhang   ierr = PetscFree(icc);CHKERRQ(ierr);
459b54502bSHong Zhang   PetscFunctionReturn(0);
469b54502bSHong Zhang }
479b54502bSHong Zhang 
489b54502bSHong Zhang #undef __FUNCT__
499b54502bSHong Zhang #define __FUNCT__ "PCApply_ICC"
509b54502bSHong Zhang static PetscErrorCode PCApply_ICC(PC pc,Vec x,Vec y)
519b54502bSHong Zhang {
529b54502bSHong Zhang   PC_ICC         *icc = (PC_ICC*)pc->data;
539b54502bSHong Zhang   PetscErrorCode ierr;
549b54502bSHong Zhang 
559b54502bSHong Zhang   PetscFunctionBegin;
56075768bcSBarry Smith   ierr = MatSolve(((PC_Factor*)icc)->fact,x,y);CHKERRQ(ierr);
579b54502bSHong Zhang   PetscFunctionReturn(0);
589b54502bSHong Zhang }
599b54502bSHong Zhang 
609b54502bSHong Zhang #undef __FUNCT__
619b54502bSHong Zhang #define __FUNCT__ "PCApplySymmetricLeft_ICC"
629b54502bSHong Zhang static PetscErrorCode PCApplySymmetricLeft_ICC(PC pc,Vec x,Vec y)
639b54502bSHong Zhang {
649b54502bSHong Zhang   PetscErrorCode ierr;
659b54502bSHong Zhang   PC_ICC         *icc = (PC_ICC*)pc->data;
669b54502bSHong Zhang 
679b54502bSHong Zhang   PetscFunctionBegin;
68075768bcSBarry Smith   ierr = MatForwardSolve(((PC_Factor*)icc)->fact,x,y);CHKERRQ(ierr);
699b54502bSHong Zhang   PetscFunctionReturn(0);
709b54502bSHong Zhang }
719b54502bSHong Zhang 
729b54502bSHong Zhang #undef __FUNCT__
739b54502bSHong Zhang #define __FUNCT__ "PCApplySymmetricRight_ICC"
749b54502bSHong Zhang static PetscErrorCode PCApplySymmetricRight_ICC(PC pc,Vec x,Vec y)
759b54502bSHong Zhang {
769b54502bSHong Zhang   PetscErrorCode ierr;
779b54502bSHong Zhang   PC_ICC         *icc = (PC_ICC*)pc->data;
789b54502bSHong Zhang 
799b54502bSHong Zhang   PetscFunctionBegin;
80075768bcSBarry Smith   ierr = MatBackwardSolve(((PC_Factor*)icc)->fact,x,y);CHKERRQ(ierr);
819b54502bSHong Zhang   PetscFunctionReturn(0);
829b54502bSHong Zhang }
839b54502bSHong Zhang 
849b54502bSHong Zhang #undef __FUNCT__
859b54502bSHong Zhang #define __FUNCT__ "PCSetFromOptions_ICC"
869b54502bSHong Zhang static PetscErrorCode PCSetFromOptions_ICC(PC pc)
879b54502bSHong Zhang {
889b54502bSHong Zhang   PC_ICC         *icc = (PC_ICC*)pc->data;
899b54502bSHong Zhang   PetscTruth     flg;
909b54502bSHong Zhang   PetscErrorCode ierr;
919b54502bSHong Zhang 
929b54502bSHong Zhang   PetscFunctionBegin;
939b54502bSHong Zhang   ierr = PetscOptionsHead("ICC Options");CHKERRQ(ierr);
94*8ff23777SHong Zhang     ierr = PCSetFromOptions_Factor(pc);CHKERRQ(ierr);
959b54502bSHong Zhang 
96*8ff23777SHong Zhang     ierr = PetscOptionsReal("-pc_factor_levels","levels of fill","PCFactorSetLevels",((PC_Factor*)icc)->info.levels,&((PC_Factor*)icc)->info.levels,&flg);CHKERRQ(ierr);
979b54502bSHong Zhang   ierr = PetscOptionsTail();CHKERRQ(ierr);
989b54502bSHong Zhang   PetscFunctionReturn(0);
999b54502bSHong Zhang }
1009b54502bSHong Zhang 
1019b54502bSHong Zhang #undef __FUNCT__
1029b54502bSHong Zhang #define __FUNCT__ "PCView_ICC"
1039b54502bSHong Zhang static PetscErrorCode PCView_ICC(PC pc,PetscViewer viewer)
1049b54502bSHong Zhang {
1059b54502bSHong Zhang   PC_ICC         *icc = (PC_ICC*)pc->data;
1069b54502bSHong Zhang   PetscErrorCode ierr;
1079b54502bSHong Zhang   PetscTruth     isstring,iascii;
1089b54502bSHong Zhang 
1099b54502bSHong Zhang   PetscFunctionBegin;
1109b54502bSHong Zhang   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);CHKERRQ(ierr);
1119b54502bSHong Zhang   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
1129b54502bSHong Zhang   if (iascii) {
113075768bcSBarry Smith     if (((PC_Factor*)icc)->info.levels == 1) {
114075768bcSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  ICC: %D level of fill\n",(PetscInt)((PC_Factor*)icc)->info.levels);CHKERRQ(ierr);
1159b54502bSHong Zhang     } else {
116075768bcSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  ICC: %D levels of fill\n",(PetscInt)((PC_Factor*)icc)->info.levels);CHKERRQ(ierr);
1179b54502bSHong Zhang     }
118075768bcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  ICC: factor fill ratio allocated %G, ordering used %s\n",((PC_Factor*)icc)->info.fill,((PC_Factor*)icc)->ordering);CHKERRQ(ierr);
119075768bcSBarry Smith     if (((PC_Factor*)icc)->info.shiftpd) {ierr = PetscViewerASCIIPrintf(viewer,"  ICC: using Manteuffel shift\n");CHKERRQ(ierr);}
120075768bcSBarry Smith     if (((PC_Factor*)icc)->info.shiftnz) {ierr = PetscViewerASCIIPrintf(viewer,"  ICC: using diagonal shift to prevent zero pivot\n");CHKERRQ(ierr);}
121075768bcSBarry Smith     if (((PC_Factor*)icc)->fact) {
122f3a39becSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  ICC: factor fill ratio needed %G\n",icc->actualfill);CHKERRQ(ierr);
123f3a39becSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"       Factored matrix follows\n");CHKERRQ(ierr);
124f3a39becSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
125f3a39becSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
126f3a39becSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
127f3a39becSBarry Smith       ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
128075768bcSBarry Smith       ierr = MatView(((PC_Factor*)icc)->fact,viewer);CHKERRQ(ierr);
129f3a39becSBarry Smith       ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
130f3a39becSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
131f3a39becSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
132f3a39becSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
133f3a39becSBarry Smith     }
1349b54502bSHong Zhang   } else if (isstring) {
135075768bcSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," lvls=%D",(PetscInt)((PC_Factor*)icc)->info.levels);CHKERRQ(ierr);CHKERRQ(ierr);
1369b54502bSHong Zhang   } else {
1379b54502bSHong Zhang     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for PCICC",((PetscObject)viewer)->type_name);
1389b54502bSHong Zhang   }
1399b54502bSHong Zhang   PetscFunctionReturn(0);
1409b54502bSHong Zhang }
1419b54502bSHong Zhang 
1429b54502bSHong Zhang /*MC
1439b54502bSHong Zhang      PCICC - Incomplete Cholesky factorization preconditioners.
1449b54502bSHong Zhang 
1459b54502bSHong Zhang    Options Database Keys:
1462401956bSBarry Smith +  -pc_factor_levels <k> - number of levels of fill for ICC(k)
1472401956bSBarry Smith .  -pc_factor_in_place - only for ICC(0) with natural ordering, reuses the space of the matrix for
1489b54502bSHong Zhang                       its factorization (overwrites original matrix)
14955ba2a51SBarry Smith .  -pc_factor_fill <nfill> - expected amount of fill in factored matrix compared to original matrix, nfill > 1
1502401956bSBarry Smith .  -pc_factor_mat_ordering_type <natural,nd,1wd,rcm,qmd> - set the row/column ordering of the factored matrix
151f251bdbdSHong Zhang .  -pc_factor_shift_nonzero <shift> - Sets shift amount or PETSC_DECIDE for the default
152f251bdbdSHong Zhang -  -pc_factor_shift_positive_definite [PETSC_TRUE/PETSC_FALSE] - Activate/Deactivate PCFactorSetShiftPd(); the value
153f251bdbdSHong Zhang    is optional with PETSC_TRUE being the default
1549b54502bSHong Zhang 
1559b54502bSHong Zhang    Level: beginner
1569b54502bSHong Zhang 
1579b54502bSHong Zhang   Concepts: incomplete Cholesky factorization
1589b54502bSHong Zhang 
159c582cd25SBarry Smith    Notes: Only implemented for some matrix formats. Not implemented in parallel (for parallel use you
160c582cd25SBarry Smith              must use MATMPIROWBS, see MatCreateMPIRowbs(), this supports only ICC(0) and this is not recommended
161c582cd25SBarry Smith              unless you really want a parallel ICC).
1629b54502bSHong Zhang 
1639b54502bSHong Zhang           For BAIJ matrices this implements a point block ICC.
1649b54502bSHong Zhang 
1659b54502bSHong Zhang           The Manteuffel shift is only implemented for matrices with block size 1
1669b54502bSHong Zhang 
1672401956bSBarry Smith           By default, the Manteuffel is applied (for matrices with block size 1). Call PCFactorSetShiftPd(pc,PETSC_FALSE);
1689b54502bSHong Zhang           to turn off the shift.
1699b54502bSHong Zhang 
170c582cd25SBarry Smith    References:
171c582cd25SBarry Smith    Review article: APPROXIMATE AND INCOMPLETE FACTORIZATIONS, TONY F. CHAN AND HENK A. VAN DER VORST
172c582cd25SBarry Smith       http://igitur-archive.library.uu.nl/math/2001-0621-115821/proc.pdf chapter in Parallel Numerical
173c582cd25SBarry Smith       Algorithms, edited by D. Keyes, A. Semah, V. Venkatakrishnan, ICASE/LaRC Interdisciplinary Series in
174c582cd25SBarry Smith       Science and Engineering, Kluwer, pp. 167--202.
175c582cd25SBarry Smith 
1769b54502bSHong Zhang 
1779b54502bSHong Zhang .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC, PCSOR, MatOrderingType,
178*8ff23777SHong Zhang            PCFactorSetZeroPivot(), PCFactorSetShiftNonzero(), PCFactorSetShiftPd(),PCFactorSetShiftInBlocks(),
179e5a9bf91SBarry Smith            PCFactorSetFill(), PCFactorSetMatOrderingType(), PCFactorSetReuseOrdering(),
180*8ff23777SHong Zhang            PCFactorSetLevels()
1819b54502bSHong Zhang 
1829b54502bSHong Zhang M*/
1839b54502bSHong Zhang 
1849b54502bSHong Zhang EXTERN_C_BEGIN
1859b54502bSHong Zhang #undef __FUNCT__
1869b54502bSHong Zhang #define __FUNCT__ "PCCreate_ICC"
187dba47a55SKris Buschelman PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_ICC(PC pc)
1889b54502bSHong Zhang {
1899b54502bSHong Zhang   PetscErrorCode ierr;
1909b54502bSHong Zhang   PC_ICC         *icc;
1919b54502bSHong Zhang 
1929b54502bSHong Zhang   PetscFunctionBegin;
19338f2d2fdSLisandro Dalcin   ierr = PetscNewLog(pc,PC_ICC,&icc);CHKERRQ(ierr);
1949b54502bSHong Zhang 
195075768bcSBarry Smith   ((PC_Factor*)icc)->fact	          = 0;
196075768bcSBarry Smith   ierr = PetscStrallocpy(MATORDERING_NATURAL,&((PC_Factor*)icc)->ordering);CHKERRQ(ierr);
197075768bcSBarry Smith   ierr = MatFactorInfoInitialize(&((PC_Factor*)icc)->info);CHKERRQ(ierr);
198075768bcSBarry Smith   ((PC_Factor*)icc)->info.levels	  = 0;
199075768bcSBarry Smith   ((PC_Factor*)icc)->info.fill          = 1.0;
2009b54502bSHong Zhang   icc->implctx            = 0;
2019b54502bSHong Zhang 
202075768bcSBarry Smith   ((PC_Factor*)icc)->info.dtcol              = PETSC_DEFAULT;
203075768bcSBarry Smith   ((PC_Factor*)icc)->info.shiftnz            = 0.0;
204075768bcSBarry Smith   ((PC_Factor*)icc)->info.shiftpd            = 1.0; /* true */
205075768bcSBarry Smith   ((PC_Factor*)icc)->info.zeropivot          = 1.e-12;
2069b54502bSHong Zhang   pc->data	               = (void*)icc;
2079b54502bSHong Zhang 
2089b54502bSHong Zhang   pc->ops->apply	       = PCApply_ICC;
2099b54502bSHong Zhang   pc->ops->setup               = PCSetup_ICC;
2109b54502bSHong Zhang   pc->ops->destroy	       = PCDestroy_ICC;
2119b54502bSHong Zhang   pc->ops->setfromoptions      = PCSetFromOptions_ICC;
2129b54502bSHong Zhang   pc->ops->view                = PCView_ICC;
21385317021SBarry Smith   pc->ops->getfactoredmatrix   = PCFactorGetMatrix_Factor;
2149b54502bSHong Zhang   pc->ops->applysymmetricleft  = PCApplySymmetricLeft_ICC;
2159b54502bSHong Zhang   pc->ops->applysymmetricright = PCApplySymmetricRight_ICC;
2169b54502bSHong Zhang 
2177112b564SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorGetMatSolverPackage_C","PCFactorGetMatSolverPackage_Factor",
2187112b564SBarry Smith                     PCFactorGetMatSolverPackage_Factor);CHKERRQ(ierr);
21985317021SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetZeroPivot_C","PCFactorSetZeroPivot_Factor",
22085317021SBarry Smith                     PCFactorSetZeroPivot_Factor);CHKERRQ(ierr);
22185317021SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftNonzero_C","PCFactorSetShiftNonzero_Factor",
22285317021SBarry Smith                     PCFactorSetShiftNonzero_Factor);CHKERRQ(ierr);
22385317021SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftPd_C","PCFactorSetShiftPd_Factor",
22485317021SBarry Smith                     PCFactorSetShiftPd_Factor);CHKERRQ(ierr);
225*8ff23777SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftInBlocks_C","PCFactorSetShiftInBlocks_Factor",
226*8ff23777SHong Zhang                     PCFactorSetShiftInBlocks_Factor);CHKERRQ(ierr);
227afaefe49SHong Zhang 
22885317021SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetLevels_C","PCFactorSetLevels_Factor",
22985317021SBarry Smith                     PCFactorSetLevels_Factor);CHKERRQ(ierr);
23085317021SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetFill_C","PCFactorSetFill_Factor",
23185317021SBarry Smith                     PCFactorSetFill_Factor);CHKERRQ(ierr);
23285317021SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetMatOrderingType_C","PCFactorSetMatOrderingType_Factor",
23385317021SBarry Smith                     PCFactorSetMatOrderingType_Factor);CHKERRQ(ierr);
2349b54502bSHong Zhang   PetscFunctionReturn(0);
2359b54502bSHong Zhang }
2369b54502bSHong Zhang EXTERN_C_END
2379b54502bSHong Zhang 
2389b54502bSHong Zhang 
239