xref: /petsc/src/ksp/pc/impls/bddc/bddc.c (revision 63602bcaa893421da8af814d137379896d1618ad)
153cdbc3dSStefano Zampini /* TODOLIST
2eb97c9d2SStefano Zampini 
3eb97c9d2SStefano Zampini    ConstraintsSetup
4eb97c9d2SStefano Zampini    - assure same constraints between neighbours by sorting vals by global index before SVD!
5eb97c9d2SStefano Zampini    - tolerances for constraints as an option (take care of single precision!)
6eb97c9d2SStefano Zampini    - Allow different constraints customizations among different linear solves (requires also reset/destroy of ksp_R and coarse_ksp)
7eb97c9d2SStefano Zampini    - MAT_IGNORE_ZERO_ENTRIES for Constraints Matrix
8eb97c9d2SStefano Zampini 
9eb97c9d2SStefano Zampini    Solvers
10eb97c9d2SStefano Zampini    - Try to reduce the work when reusing the solvers
11eb97c9d2SStefano Zampini    - Add support for reuse fill and cholecky factor for coarse solver (similar to local solvers)
12eb97c9d2SStefano Zampini    - reuse already allocated coarse matrix if possible
13eb97c9d2SStefano Zampini    - Propagate ksp prefixes for solvers to mat objects?
14eb97c9d2SStefano Zampini    - Propagate nearnullspace info among levels
15eb97c9d2SStefano Zampini 
16eb97c9d2SStefano Zampini    User interface
17eb97c9d2SStefano Zampini    - Negative indices in dirichlet and Neumann is should be skipped (now they cause out-of-bounds access)
18eb97c9d2SStefano Zampini    - Provide PCApplyTranpose_BDDC
19eb97c9d2SStefano Zampini    - DofSplitting and DM attached to pc?
20eb97c9d2SStefano Zampini 
21eb97c9d2SStefano Zampini    Debugging output
22eb97c9d2SStefano Zampini    - Better management of verbosity levels of debugging output
23eb97c9d2SStefano Zampini    - Crashes on some architecture -> call SynchronizedAllow before every SynchronizedPrintf
24eb97c9d2SStefano Zampini 
25eb97c9d2SStefano Zampini    Build
26eb97c9d2SStefano Zampini    - make runexe59
27eb97c9d2SStefano Zampini 
28eb97c9d2SStefano Zampini    Extra
29eb97c9d2SStefano Zampini    - Is it possible to work with PCBDDCGraph on boundary indices only (less memory consumed)?
30eb97c9d2SStefano Zampini    - Why options for "pc_bddc_coarse" solver gets propagated to "pc_bddc_coarse_1" solver?
31eb97c9d2SStefano Zampini    - add support for computing h,H and related using coordinates?
32c0b83709SStefano Zampini    - Change of basis approach does not work with my nonlinear mechanics example. why? (seems not an issue with l2gmap)
33eb97c9d2SStefano Zampini    - Better management in PCIS code
34eb97c9d2SStefano Zampini    - BDDC with MG framework?
35eb97c9d2SStefano Zampini 
36eb97c9d2SStefano Zampini    FETIDP
37eb97c9d2SStefano Zampini    - Move FETIDP code to its own classes
38eb97c9d2SStefano Zampini 
39eb97c9d2SStefano Zampini    MATIS related operations contained in BDDC code
40eb97c9d2SStefano Zampini    - Provide general case for subassembling
41eb97c9d2SStefano Zampini    - Preallocation routines in MatConvert_IS_AIJ
42eb97c9d2SStefano Zampini 
4353cdbc3dSStefano Zampini */
440c7d97c5SJed Brown 
4553cdbc3dSStefano Zampini /* ----------------------------------------------------------------------------------------------------------------------------------------------
460c7d97c5SJed Brown    Implementation of BDDC preconditioner based on:
470c7d97c5SJed Brown    C. Dohrmann "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007
4853cdbc3dSStefano Zampini    ---------------------------------------------------------------------------------------------------------------------------------------------- */
4953cdbc3dSStefano Zampini 
50674ae819SStefano Zampini #include "bddc.h" /*I "petscpc.h" I*/  /* includes for fortran wrappers */
51674ae819SStefano Zampini #include "bddcprivate.h"
523b03a366Sstefano_zampini #include <petscblaslapack.h>
53674ae819SStefano Zampini 
540c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
550c7d97c5SJed Brown #undef __FUNCT__
560c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC"
570c7d97c5SJed Brown PetscErrorCode PCSetFromOptions_BDDC(PC pc)
580c7d97c5SJed Brown {
590c7d97c5SJed Brown   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
600c7d97c5SJed Brown   PetscErrorCode ierr;
610c7d97c5SJed Brown 
620c7d97c5SJed Brown   PetscFunctionBegin;
630c7d97c5SJed Brown   ierr = PetscOptionsHead("BDDC options");CHKERRQ(ierr);
648eeda7d8SStefano Zampini   /* Verbose debugging */
658eeda7d8SStefano Zampini   ierr = PetscOptionsInt("-pc_bddc_check_level","Verbose output for PCBDDC (intended for debug)","none",pcbddc->dbg_flag,&pcbddc->dbg_flag,NULL);CHKERRQ(ierr);
668eeda7d8SStefano Zampini   /* Primal space cumstomization */
678eeda7d8SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_use_vertices","Use or not corner dofs in coarse space","none",pcbddc->use_vertices,&pcbddc->use_vertices,NULL);CHKERRQ(ierr);
688eeda7d8SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_use_edges","Use or not edge constraints in coarse space","none",pcbddc->use_edges,&pcbddc->use_edges,NULL);CHKERRQ(ierr);
698eeda7d8SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_use_faces","Use or not face constraints in coarse space","none",pcbddc->use_faces,&pcbddc->use_faces,NULL);CHKERRQ(ierr);
708eeda7d8SStefano Zampini   /* Change of basis */
718eeda7d8SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_use_change_of_basis","Use or not change of basis on local edge nodes","none",pcbddc->use_change_of_basis,&pcbddc->use_change_of_basis,NULL);CHKERRQ(ierr);
728eeda7d8SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_use_change_on_faces","Use or not change of basis on local face nodes","none",pcbddc->use_change_on_faces,&pcbddc->use_change_on_faces,NULL);CHKERRQ(ierr);
73674ae819SStefano Zampini   if (!pcbddc->use_change_of_basis) {
74674ae819SStefano Zampini     pcbddc->use_change_on_faces = PETSC_FALSE;
75674ae819SStefano Zampini   }
768eeda7d8SStefano Zampini   /* Switch between M_2 (default) and M_3 preconditioners (as defined by C. Dohrmann in the ref. article) */
778eeda7d8SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_switch_static","Switch on static condensation ops around the interface preconditioner","none",pcbddc->switch_static,&pcbddc->switch_static,NULL);CHKERRQ(ierr);
780298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr);
792b510759SStefano Zampini   ierr = PetscOptionsInt("-pc_bddc_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr);
80674ae819SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_use_deluxe_scaling","Use deluxe scaling for BDDC","none",pcbddc->use_deluxe_scaling,&pcbddc->use_deluxe_scaling,NULL);CHKERRQ(ierr);
810c7d97c5SJed Brown   ierr = PetscOptionsTail();CHKERRQ(ierr);
820c7d97c5SJed Brown   PetscFunctionReturn(0);
830c7d97c5SJed Brown }
840c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
85674ae819SStefano Zampini #undef __FUNCT__
86674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS_BDDC"
87674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices)
88674ae819SStefano Zampini {
89674ae819SStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
90674ae819SStefano Zampini   PetscErrorCode ierr;
911e6b0712SBarry Smith 
92674ae819SStefano Zampini   PetscFunctionBegin;
93674ae819SStefano Zampini   ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr);
94674ae819SStefano Zampini   ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr);
95674ae819SStefano Zampini   pcbddc->user_primal_vertices = PrimalVertices;
96674ae819SStefano Zampini   PetscFunctionReturn(0);
97674ae819SStefano Zampini }
98674ae819SStefano Zampini #undef __FUNCT__
99674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS"
100674ae819SStefano Zampini /*@
10128509bceSStefano Zampini  PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC
102674ae819SStefano Zampini 
103674ae819SStefano Zampini    Not collective
104674ae819SStefano Zampini 
105674ae819SStefano Zampini    Input Parameters:
106674ae819SStefano Zampini +  pc - the preconditioning context
10728509bceSStefano Zampini -  PrimalVertices - index set of primal vertices in local numbering
108674ae819SStefano Zampini 
109674ae819SStefano Zampini    Level: intermediate
110674ae819SStefano Zampini 
111674ae819SStefano Zampini    Notes:
112674ae819SStefano Zampini 
113674ae819SStefano Zampini .seealso: PCBDDC
114674ae819SStefano Zampini @*/
115674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices)
116674ae819SStefano Zampini {
117674ae819SStefano Zampini   PetscErrorCode ierr;
118674ae819SStefano Zampini 
119674ae819SStefano Zampini   PetscFunctionBegin;
120674ae819SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
121674ae819SStefano Zampini   PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2);
122674ae819SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr);
123674ae819SStefano Zampini   PetscFunctionReturn(0);
124674ae819SStefano Zampini }
125674ae819SStefano Zampini /* -------------------------------------------------------------------------- */
1260c7d97c5SJed Brown #undef __FUNCT__
1274fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio_BDDC"
1284fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k)
1294fad6a16SStefano Zampini {
1304fad6a16SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
1314fad6a16SStefano Zampini 
1324fad6a16SStefano Zampini   PetscFunctionBegin;
1334fad6a16SStefano Zampini   pcbddc->coarsening_ratio = k;
1344fad6a16SStefano Zampini   PetscFunctionReturn(0);
1354fad6a16SStefano Zampini }
1361e6b0712SBarry Smith 
1374fad6a16SStefano Zampini #undef __FUNCT__
1384fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio"
1394fad6a16SStefano Zampini /*@
14028509bceSStefano Zampini  PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel
1414fad6a16SStefano Zampini 
1424fad6a16SStefano Zampini    Logically collective on PC
1434fad6a16SStefano Zampini 
1444fad6a16SStefano Zampini    Input Parameters:
1454fad6a16SStefano Zampini +  pc - the preconditioning context
14628509bceSStefano Zampini -  k - coarsening ratio (H/h at the coarser level)
1474fad6a16SStefano Zampini 
14828509bceSStefano Zampini    Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level
1494fad6a16SStefano Zampini 
1504fad6a16SStefano Zampini    Level: intermediate
1514fad6a16SStefano Zampini 
1524fad6a16SStefano Zampini    Notes:
1534fad6a16SStefano Zampini 
1544fad6a16SStefano Zampini .seealso: PCBDDC
1554fad6a16SStefano Zampini @*/
1564fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k)
1574fad6a16SStefano Zampini {
1584fad6a16SStefano Zampini   PetscErrorCode ierr;
1594fad6a16SStefano Zampini 
1604fad6a16SStefano Zampini   PetscFunctionBegin;
1614fad6a16SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1622b510759SStefano Zampini   PetscValidLogicalCollectiveInt(pc,k,2);
1634fad6a16SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr);
1644fad6a16SStefano Zampini   PetscFunctionReturn(0);
1654fad6a16SStefano Zampini }
1662b510759SStefano Zampini 
167b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */
1682b510759SStefano Zampini #undef __FUNCT__
169b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet_BDDC"
170b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg)
171b8ffe317SStefano Zampini {
172b8ffe317SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
173b8ffe317SStefano Zampini 
174b8ffe317SStefano Zampini   PetscFunctionBegin;
17585c4d303SStefano Zampini   pcbddc->use_exact_dirichlet_trick = flg;
176b8ffe317SStefano Zampini   PetscFunctionReturn(0);
177b8ffe317SStefano Zampini }
178b8ffe317SStefano Zampini 
179b8ffe317SStefano Zampini #undef __FUNCT__
180b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet"
181b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg)
1822b510759SStefano Zampini {
1832b510759SStefano Zampini   PetscErrorCode ierr;
1842b510759SStefano Zampini 
1852b510759SStefano Zampini   PetscFunctionBegin;
1862b510759SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
187b8ffe317SStefano Zampini   PetscValidLogicalCollectiveBool(pc,flg,2);
188b8ffe317SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr);
1892b510759SStefano Zampini   PetscFunctionReturn(0);
1902b510759SStefano Zampini }
1911e6b0712SBarry Smith 
1924fad6a16SStefano Zampini #undef __FUNCT__
1932b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel_BDDC"
1942b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level)
1954fad6a16SStefano Zampini {
1964fad6a16SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
1974fad6a16SStefano Zampini 
1984fad6a16SStefano Zampini   PetscFunctionBegin;
1992b510759SStefano Zampini   pcbddc->current_level = level;
2004fad6a16SStefano Zampini   PetscFunctionReturn(0);
2014fad6a16SStefano Zampini }
2021e6b0712SBarry Smith 
2034fad6a16SStefano Zampini #undef __FUNCT__
204b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel"
205b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level)
206b8ffe317SStefano Zampini {
207b8ffe317SStefano Zampini   PetscErrorCode ierr;
208b8ffe317SStefano Zampini 
209b8ffe317SStefano Zampini   PetscFunctionBegin;
210b8ffe317SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
211b8ffe317SStefano Zampini   PetscValidLogicalCollectiveInt(pc,level,2);
212b8ffe317SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr);
213b8ffe317SStefano Zampini   PetscFunctionReturn(0);
214b8ffe317SStefano Zampini }
215b8ffe317SStefano Zampini 
216b8ffe317SStefano Zampini #undef __FUNCT__
2172b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels_BDDC"
2182b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels)
2192b510759SStefano Zampini {
2202b510759SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
2212b510759SStefano Zampini 
2222b510759SStefano Zampini   PetscFunctionBegin;
2232b510759SStefano Zampini   pcbddc->max_levels = levels;
2242b510759SStefano Zampini   PetscFunctionReturn(0);
2252b510759SStefano Zampini }
2262b510759SStefano Zampini 
2272b510759SStefano Zampini #undef __FUNCT__
2282b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels"
2294fad6a16SStefano Zampini /*@
23028509bceSStefano Zampini  PCBDDCSetLevels - Sets the maximum number of levels for multilevel
2314fad6a16SStefano Zampini 
2324fad6a16SStefano Zampini    Logically collective on PC
2334fad6a16SStefano Zampini 
2344fad6a16SStefano Zampini    Input Parameters:
2354fad6a16SStefano Zampini +  pc - the preconditioning context
23628509bceSStefano Zampini -  levels - the maximum number of levels (max 9)
2374fad6a16SStefano Zampini 
23828509bceSStefano Zampini    Default value is 0, i.e. traditional one-level BDDC
2394fad6a16SStefano Zampini 
2404fad6a16SStefano Zampini    Level: intermediate
2414fad6a16SStefano Zampini 
2424fad6a16SStefano Zampini    Notes:
2434fad6a16SStefano Zampini 
2444fad6a16SStefano Zampini .seealso: PCBDDC
2454fad6a16SStefano Zampini @*/
2462b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels)
2474fad6a16SStefano Zampini {
2484fad6a16SStefano Zampini   PetscErrorCode ierr;
2494fad6a16SStefano Zampini 
2504fad6a16SStefano Zampini   PetscFunctionBegin;
2514fad6a16SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2522b510759SStefano Zampini   PetscValidLogicalCollectiveInt(pc,levels,2);
2532b510759SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr);
2544fad6a16SStefano Zampini   PetscFunctionReturn(0);
2554fad6a16SStefano Zampini }
2564fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */
2571e6b0712SBarry Smith 
2584fad6a16SStefano Zampini #undef __FUNCT__
2590bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace_BDDC"
2600bdf917eSStefano Zampini static PetscErrorCode PCBDDCSetNullSpace_BDDC(PC pc,MatNullSpace NullSpace)
2610bdf917eSStefano Zampini {
2620bdf917eSStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
2630bdf917eSStefano Zampini   PetscErrorCode ierr;
2640bdf917eSStefano Zampini 
2650bdf917eSStefano Zampini   PetscFunctionBegin;
2660bdf917eSStefano Zampini   ierr = PetscObjectReference((PetscObject)NullSpace);CHKERRQ(ierr);
2670bdf917eSStefano Zampini   ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr);
2680bdf917eSStefano Zampini   pcbddc->NullSpace = NullSpace;
2690bdf917eSStefano Zampini   PetscFunctionReturn(0);
2700bdf917eSStefano Zampini }
2711e6b0712SBarry Smith 
2720bdf917eSStefano Zampini #undef __FUNCT__
2730bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace"
2740bdf917eSStefano Zampini /*@
27528509bceSStefano Zampini  PCBDDCSetNullSpace - Set nullspace for BDDC operator
2760bdf917eSStefano Zampini 
2770bdf917eSStefano Zampini    Logically collective on PC and MatNullSpace
2780bdf917eSStefano Zampini 
2790bdf917eSStefano Zampini    Input Parameters:
2800bdf917eSStefano Zampini +  pc - the preconditioning context
28128509bceSStefano Zampini -  NullSpace - Null space of the linear operator to be preconditioned (Pmat)
2820bdf917eSStefano Zampini 
2830bdf917eSStefano Zampini    Level: intermediate
2840bdf917eSStefano Zampini 
2850bdf917eSStefano Zampini    Notes:
2860bdf917eSStefano Zampini 
2870bdf917eSStefano Zampini .seealso: PCBDDC
2880bdf917eSStefano Zampini @*/
2890bdf917eSStefano Zampini PetscErrorCode PCBDDCSetNullSpace(PC pc,MatNullSpace NullSpace)
2900bdf917eSStefano Zampini {
2910bdf917eSStefano Zampini   PetscErrorCode ierr;
2920bdf917eSStefano Zampini 
2930bdf917eSStefano Zampini   PetscFunctionBegin;
2940bdf917eSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
295674ae819SStefano Zampini   PetscValidHeaderSpecific(NullSpace,MAT_NULLSPACE_CLASSID,2);
2962b510759SStefano Zampini   PetscCheckSameComm(pc,1,NullSpace,2);
2970bdf917eSStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetNullSpace_C",(PC,MatNullSpace),(pc,NullSpace));CHKERRQ(ierr);
2980bdf917eSStefano Zampini   PetscFunctionReturn(0);
2990bdf917eSStefano Zampini }
3000bdf917eSStefano Zampini /* -------------------------------------------------------------------------- */
3011e6b0712SBarry Smith 
3020bdf917eSStefano Zampini #undef __FUNCT__
303785d1243SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC"
304785d1243SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries)
305785d1243SStefano Zampini {
306785d1243SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
307785d1243SStefano Zampini   PetscErrorCode ierr;
308785d1243SStefano Zampini 
309785d1243SStefano Zampini   PetscFunctionBegin;
310785d1243SStefano Zampini   /* last user setting takes precendence -> destroy any other customization */
311785d1243SStefano Zampini   ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr);
312785d1243SStefano Zampini   ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr);
313785d1243SStefano Zampini   ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr);
314785d1243SStefano Zampini   pcbddc->DirichletBoundaries = DirichletBoundaries;
315785d1243SStefano Zampini   PetscFunctionReturn(0);
316785d1243SStefano Zampini }
317785d1243SStefano Zampini 
318785d1243SStefano Zampini #undef __FUNCT__
319785d1243SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries"
320785d1243SStefano Zampini /*@
321785d1243SStefano Zampini  PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem.
322785d1243SStefano Zampini 
323785d1243SStefano Zampini    Collective
324785d1243SStefano Zampini 
325785d1243SStefano Zampini    Input Parameters:
326785d1243SStefano Zampini +  pc - the preconditioning context
327785d1243SStefano Zampini -  DirichletBoundaries - parallel IS defining the Dirichlet boundaries
328785d1243SStefano Zampini 
329785d1243SStefano Zampini    Level: intermediate
330785d1243SStefano Zampini 
331785d1243SStefano Zampini    Notes: Any process can list any global node
332785d1243SStefano Zampini 
333785d1243SStefano Zampini .seealso: PCBDDC
334785d1243SStefano Zampini @*/
335785d1243SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries)
336785d1243SStefano Zampini {
337785d1243SStefano Zampini   PetscErrorCode ierr;
338785d1243SStefano Zampini 
339785d1243SStefano Zampini   PetscFunctionBegin;
340785d1243SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
341785d1243SStefano Zampini   PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2);
342785d1243SStefano Zampini   PetscCheckSameComm(pc,1,DirichletBoundaries,2);
343785d1243SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr);
344785d1243SStefano Zampini   PetscFunctionReturn(0);
345785d1243SStefano Zampini }
346785d1243SStefano Zampini /* -------------------------------------------------------------------------- */
347785d1243SStefano Zampini 
348785d1243SStefano Zampini #undef __FUNCT__
34982ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal_BDDC"
35082ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries)
3513b03a366Sstefano_zampini {
3523b03a366Sstefano_zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
3533b03a366Sstefano_zampini   PetscErrorCode ierr;
3543b03a366Sstefano_zampini 
3553b03a366Sstefano_zampini   PetscFunctionBegin;
356785d1243SStefano Zampini   /* last user setting takes precendence -> destroy any other customization */
357785d1243SStefano Zampini   ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr);
3583b03a366Sstefano_zampini   ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr);
35936e030ebSStefano Zampini   ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr);
360785d1243SStefano Zampini   pcbddc->DirichletBoundariesLocal = DirichletBoundaries;
3613b03a366Sstefano_zampini   PetscFunctionReturn(0);
3623b03a366Sstefano_zampini }
3631e6b0712SBarry Smith 
3643b03a366Sstefano_zampini #undef __FUNCT__
36582ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal"
3663b03a366Sstefano_zampini /*@
36782ba6b80SStefano Zampini  PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering.
3683b03a366Sstefano_zampini 
369785d1243SStefano Zampini    Collective
3703b03a366Sstefano_zampini 
3713b03a366Sstefano_zampini    Input Parameters:
3723b03a366Sstefano_zampini +  pc - the preconditioning context
37382ba6b80SStefano Zampini -  DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering)
3743b03a366Sstefano_zampini 
3753b03a366Sstefano_zampini    Level: intermediate
3763b03a366Sstefano_zampini 
3773b03a366Sstefano_zampini    Notes:
3783b03a366Sstefano_zampini 
3793b03a366Sstefano_zampini .seealso: PCBDDC
3803b03a366Sstefano_zampini @*/
38182ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries)
3823b03a366Sstefano_zampini {
3833b03a366Sstefano_zampini   PetscErrorCode ierr;
3843b03a366Sstefano_zampini 
3853b03a366Sstefano_zampini   PetscFunctionBegin;
3863b03a366Sstefano_zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
387674ae819SStefano Zampini   PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2);
38882ba6b80SStefano Zampini   PetscCheckSameComm(pc,1,DirichletBoundaries,2);
38982ba6b80SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr);
3903b03a366Sstefano_zampini   PetscFunctionReturn(0);
3913b03a366Sstefano_zampini }
3923b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */
3931e6b0712SBarry Smith 
3943b03a366Sstefano_zampini #undef __FUNCT__
395785d1243SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC"
396785d1243SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries)
397785d1243SStefano Zampini {
398785d1243SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
399785d1243SStefano Zampini   PetscErrorCode ierr;
400785d1243SStefano Zampini 
401785d1243SStefano Zampini   PetscFunctionBegin;
402785d1243SStefano Zampini   /* last user setting takes precendence -> destroy any other customization */
403785d1243SStefano Zampini   ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr);
404785d1243SStefano Zampini   ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr);
405785d1243SStefano Zampini   ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr);
406785d1243SStefano Zampini   pcbddc->NeumannBoundaries = NeumannBoundaries;
407785d1243SStefano Zampini   PetscFunctionReturn(0);
408785d1243SStefano Zampini }
409785d1243SStefano Zampini 
410785d1243SStefano Zampini #undef __FUNCT__
411785d1243SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundaries"
412785d1243SStefano Zampini /*@
413785d1243SStefano Zampini  PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem.
414785d1243SStefano Zampini 
415785d1243SStefano Zampini    Collective
416785d1243SStefano Zampini 
417785d1243SStefano Zampini    Input Parameters:
418785d1243SStefano Zampini +  pc - the preconditioning context
419785d1243SStefano Zampini -  NeumannBoundaries - parallel IS defining the Neumann boundaries
420785d1243SStefano Zampini 
421785d1243SStefano Zampini    Level: intermediate
422785d1243SStefano Zampini 
423785d1243SStefano Zampini    Notes: Any process can list any global node
424785d1243SStefano Zampini 
425785d1243SStefano Zampini .seealso: PCBDDC
426785d1243SStefano Zampini @*/
427785d1243SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries)
428785d1243SStefano Zampini {
429785d1243SStefano Zampini   PetscErrorCode ierr;
430785d1243SStefano Zampini 
431785d1243SStefano Zampini   PetscFunctionBegin;
432785d1243SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
433785d1243SStefano Zampini   PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2);
434785d1243SStefano Zampini   PetscCheckSameComm(pc,1,NeumannBoundaries,2);
435785d1243SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr);
436785d1243SStefano Zampini   PetscFunctionReturn(0);
437785d1243SStefano Zampini }
438785d1243SStefano Zampini /* -------------------------------------------------------------------------- */
439785d1243SStefano Zampini 
440785d1243SStefano Zampini #undef __FUNCT__
44182ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal_BDDC"
44282ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries)
4430c7d97c5SJed Brown {
4440c7d97c5SJed Brown   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
44553cdbc3dSStefano Zampini   PetscErrorCode ierr;
4460c7d97c5SJed Brown 
4470c7d97c5SJed Brown   PetscFunctionBegin;
448785d1243SStefano Zampini   /* last user setting takes precendence -> destroy any other customization */
449785d1243SStefano Zampini   ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr);
45053cdbc3dSStefano Zampini   ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr);
45136e030ebSStefano Zampini   ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr);
452785d1243SStefano Zampini   pcbddc->NeumannBoundariesLocal = NeumannBoundaries;
4530c7d97c5SJed Brown   PetscFunctionReturn(0);
4540c7d97c5SJed Brown }
4551e6b0712SBarry Smith 
4560c7d97c5SJed Brown #undef __FUNCT__
45782ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal"
45857527edcSJed Brown /*@
45982ba6b80SStefano Zampini  PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering.
46057527edcSJed Brown 
461785d1243SStefano Zampini    Collective
46257527edcSJed Brown 
46357527edcSJed Brown    Input Parameters:
46457527edcSJed Brown +  pc - the preconditioning context
46582ba6b80SStefano Zampini -  NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering)
46657527edcSJed Brown 
46757527edcSJed Brown    Level: intermediate
46857527edcSJed Brown 
46957527edcSJed Brown    Notes:
47057527edcSJed Brown 
47157527edcSJed Brown .seealso: PCBDDC
47257527edcSJed Brown @*/
47382ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries)
4740c7d97c5SJed Brown {
4750c7d97c5SJed Brown   PetscErrorCode ierr;
4760c7d97c5SJed Brown 
4770c7d97c5SJed Brown   PetscFunctionBegin;
4780c7d97c5SJed Brown   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
479674ae819SStefano Zampini   PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2);
48082ba6b80SStefano Zampini   PetscCheckSameComm(pc,1,NeumannBoundaries,2);
48182ba6b80SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr);
48253cdbc3dSStefano Zampini   PetscFunctionReturn(0);
48353cdbc3dSStefano Zampini }
48453cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */
4851e6b0712SBarry Smith 
48653cdbc3dSStefano Zampini #undef __FUNCT__
487785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC"
488785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries)
489da1bb401SStefano Zampini {
490da1bb401SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
491da1bb401SStefano Zampini 
492da1bb401SStefano Zampini   PetscFunctionBegin;
493da1bb401SStefano Zampini   *DirichletBoundaries = pcbddc->DirichletBoundaries;
494da1bb401SStefano Zampini   PetscFunctionReturn(0);
495da1bb401SStefano Zampini }
4961e6b0712SBarry Smith 
497da1bb401SStefano Zampini #undef __FUNCT__
498785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries"
499785d1243SStefano Zampini /*@
500785d1243SStefano Zampini  PCBDDCGetDirichletBoundaries - Get parallel IS for Dirichlet boundaries
501785d1243SStefano Zampini 
502785d1243SStefano Zampini    Collective
503785d1243SStefano Zampini 
504785d1243SStefano Zampini    Input Parameters:
505785d1243SStefano Zampini .  pc - the preconditioning context
506785d1243SStefano Zampini 
507785d1243SStefano Zampini    Output Parameters:
508785d1243SStefano Zampini .  DirichletBoundaries - index set defining the Dirichlet boundaries
509785d1243SStefano Zampini 
510785d1243SStefano Zampini    Level: intermediate
511785d1243SStefano Zampini 
512785d1243SStefano Zampini    Notes: The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetDirichletBoundaries
513785d1243SStefano Zampini 
514785d1243SStefano Zampini .seealso: PCBDDC
515785d1243SStefano Zampini @*/
516785d1243SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries)
517785d1243SStefano Zampini {
518785d1243SStefano Zampini   PetscErrorCode ierr;
519785d1243SStefano Zampini 
520785d1243SStefano Zampini   PetscFunctionBegin;
521785d1243SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
522785d1243SStefano Zampini   ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr);
523785d1243SStefano Zampini   PetscFunctionReturn(0);
524785d1243SStefano Zampini }
525785d1243SStefano Zampini /* -------------------------------------------------------------------------- */
526785d1243SStefano Zampini 
527785d1243SStefano Zampini #undef __FUNCT__
528785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal_BDDC"
529785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries)
530785d1243SStefano Zampini {
531785d1243SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
532785d1243SStefano Zampini 
533785d1243SStefano Zampini   PetscFunctionBegin;
534785d1243SStefano Zampini   *DirichletBoundaries = pcbddc->DirichletBoundariesLocal;
535785d1243SStefano Zampini   PetscFunctionReturn(0);
536785d1243SStefano Zampini }
537785d1243SStefano Zampini 
538785d1243SStefano Zampini #undef __FUNCT__
53982ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal"
540da1bb401SStefano Zampini /*@
54182ba6b80SStefano Zampini  PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering)
542da1bb401SStefano Zampini 
543785d1243SStefano Zampini    Collective
544da1bb401SStefano Zampini 
545da1bb401SStefano Zampini    Input Parameters:
54628509bceSStefano Zampini .  pc - the preconditioning context
547da1bb401SStefano Zampini 
548da1bb401SStefano Zampini    Output Parameters:
54928509bceSStefano Zampini .  DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries
550da1bb401SStefano Zampini 
551da1bb401SStefano Zampini    Level: intermediate
552da1bb401SStefano Zampini 
553da1bb401SStefano Zampini    Notes:
554da1bb401SStefano Zampini 
555da1bb401SStefano Zampini .seealso: PCBDDC
556da1bb401SStefano Zampini @*/
55782ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries)
558da1bb401SStefano Zampini {
559da1bb401SStefano Zampini   PetscErrorCode ierr;
560da1bb401SStefano Zampini 
561da1bb401SStefano Zampini   PetscFunctionBegin;
562da1bb401SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
56382ba6b80SStefano Zampini   ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr);
564da1bb401SStefano Zampini   PetscFunctionReturn(0);
565da1bb401SStefano Zampini }
566da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */
5671e6b0712SBarry Smith 
568da1bb401SStefano Zampini #undef __FUNCT__
569785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC"
570785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries)
57153cdbc3dSStefano Zampini {
57253cdbc3dSStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
57353cdbc3dSStefano Zampini 
57453cdbc3dSStefano Zampini   PetscFunctionBegin;
57553cdbc3dSStefano Zampini   *NeumannBoundaries = pcbddc->NeumannBoundaries;
57653cdbc3dSStefano Zampini   PetscFunctionReturn(0);
57753cdbc3dSStefano Zampini }
5781e6b0712SBarry Smith 
57953cdbc3dSStefano Zampini #undef __FUNCT__
580785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries"
581785d1243SStefano Zampini /*@
582785d1243SStefano Zampini  PCBDDCGetNeumannBoundaries - Get parallel IS for Neumann boundaries
583785d1243SStefano Zampini 
584785d1243SStefano Zampini    Collective
585785d1243SStefano Zampini 
586785d1243SStefano Zampini    Input Parameters:
587785d1243SStefano Zampini .  pc - the preconditioning context
588785d1243SStefano Zampini 
589785d1243SStefano Zampini    Output Parameters:
590785d1243SStefano Zampini .  NeumannBoundaries - index set defining the Neumann boundaries
591785d1243SStefano Zampini 
592785d1243SStefano Zampini    Level: intermediate
593785d1243SStefano Zampini 
594785d1243SStefano Zampini    Notes: The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetNeumannBoundaries
595785d1243SStefano Zampini 
596785d1243SStefano Zampini .seealso: PCBDDC
597785d1243SStefano Zampini @*/
598785d1243SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries)
599785d1243SStefano Zampini {
600785d1243SStefano Zampini   PetscErrorCode ierr;
601785d1243SStefano Zampini 
602785d1243SStefano Zampini   PetscFunctionBegin;
603785d1243SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
604785d1243SStefano Zampini   ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr);
605785d1243SStefano Zampini   PetscFunctionReturn(0);
606785d1243SStefano Zampini }
607785d1243SStefano Zampini /* -------------------------------------------------------------------------- */
608785d1243SStefano Zampini 
609785d1243SStefano Zampini #undef __FUNCT__
610785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal_BDDC"
611785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries)
612785d1243SStefano Zampini {
613785d1243SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
614785d1243SStefano Zampini 
615785d1243SStefano Zampini   PetscFunctionBegin;
616785d1243SStefano Zampini   *NeumannBoundaries = pcbddc->NeumannBoundariesLocal;
617785d1243SStefano Zampini   PetscFunctionReturn(0);
618785d1243SStefano Zampini }
619785d1243SStefano Zampini 
620785d1243SStefano Zampini #undef __FUNCT__
62182ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal"
62253cdbc3dSStefano Zampini /*@
62382ba6b80SStefano Zampini  PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering)
62453cdbc3dSStefano Zampini 
625785d1243SStefano Zampini    Collective
62653cdbc3dSStefano Zampini 
62753cdbc3dSStefano Zampini    Input Parameters:
62828509bceSStefano Zampini .  pc - the preconditioning context
62953cdbc3dSStefano Zampini 
63053cdbc3dSStefano Zampini    Output Parameters:
63128509bceSStefano Zampini .  NeumannBoundaries - index set defining the subdomain part of Neumann boundaries
63253cdbc3dSStefano Zampini 
63353cdbc3dSStefano Zampini    Level: intermediate
63453cdbc3dSStefano Zampini 
63553cdbc3dSStefano Zampini    Notes:
63653cdbc3dSStefano Zampini 
63753cdbc3dSStefano Zampini .seealso: PCBDDC
63853cdbc3dSStefano Zampini @*/
63982ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries)
64053cdbc3dSStefano Zampini {
64153cdbc3dSStefano Zampini   PetscErrorCode ierr;
64253cdbc3dSStefano Zampini 
64353cdbc3dSStefano Zampini   PetscFunctionBegin;
64453cdbc3dSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
64582ba6b80SStefano Zampini   ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr);
6460c7d97c5SJed Brown   PetscFunctionReturn(0);
6470c7d97c5SJed Brown }
64836e030ebSStefano Zampini /* -------------------------------------------------------------------------- */
6491e6b0712SBarry Smith 
65036e030ebSStefano Zampini #undef __FUNCT__
651da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC"
6521a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode)
65336e030ebSStefano Zampini {
65436e030ebSStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
655da1bb401SStefano Zampini   PCBDDCGraph    mat_graph = pcbddc->mat_graph;
656da1bb401SStefano Zampini   PetscErrorCode ierr;
65736e030ebSStefano Zampini 
65836e030ebSStefano Zampini   PetscFunctionBegin;
659674ae819SStefano Zampini   /* free old CSR */
660674ae819SStefano Zampini   ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr);
661fb223d50SStefano Zampini   /* TODO: PCBDDCGraphSetAdjacency */
662674ae819SStefano Zampini   /* get CSR into graph structure */
663da1bb401SStefano Zampini   if (copymode == PETSC_COPY_VALUES) {
664674ae819SStefano Zampini     ierr = PetscMalloc((nvtxs+1)*sizeof(PetscInt),&mat_graph->xadj);CHKERRQ(ierr);
665674ae819SStefano Zampini     ierr = PetscMalloc(xadj[nvtxs]*sizeof(PetscInt),&mat_graph->adjncy);CHKERRQ(ierr);
666674ae819SStefano Zampini     ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr);
667674ae819SStefano Zampini     ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr);
668da1bb401SStefano Zampini   } else if (copymode == PETSC_OWN_POINTER) {
6691a83f524SJed Brown     mat_graph->xadj = (PetscInt*)xadj;
6701a83f524SJed Brown     mat_graph->adjncy = (PetscInt*)adjncy;
671674ae819SStefano Zampini   }
672575ad6abSStefano Zampini   mat_graph->nvtxs_csr = nvtxs;
67336e030ebSStefano Zampini   PetscFunctionReturn(0);
67436e030ebSStefano Zampini }
6751e6b0712SBarry Smith 
67636e030ebSStefano Zampini #undef __FUNCT__
677da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph"
67836e030ebSStefano Zampini /*@
67928509bceSStefano Zampini  PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local Neumann matrix
68036e030ebSStefano Zampini 
68136e030ebSStefano Zampini    Not collective
68236e030ebSStefano Zampini 
68336e030ebSStefano Zampini    Input Parameters:
68436e030ebSStefano Zampini +  pc - the preconditioning context
68528509bceSStefano Zampini .  nvtxs - number of local vertices of the graph (i.e., the local size of your problem)
68628509bceSStefano Zampini .  xadj, adjncy - the CSR graph
68728509bceSStefano Zampini -  copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER.
68836e030ebSStefano Zampini 
68936e030ebSStefano Zampini    Level: intermediate
69036e030ebSStefano Zampini 
69136e030ebSStefano Zampini    Notes:
69236e030ebSStefano Zampini 
69328509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode
69436e030ebSStefano Zampini @*/
6951a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode)
69636e030ebSStefano Zampini {
697575ad6abSStefano Zampini   void (*f)(void) = 0;
69836e030ebSStefano Zampini   PetscErrorCode ierr;
69936e030ebSStefano Zampini 
70036e030ebSStefano Zampini   PetscFunctionBegin;
70136e030ebSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
702674ae819SStefano Zampini   PetscValidIntPointer(xadj,3);
703674ae819SStefano Zampini   PetscValidIntPointer(xadj,4);
704674ae819SStefano Zampini   if (copymode != PETSC_COPY_VALUES && copymode != PETSC_OWN_POINTER) {
705674ae819SStefano Zampini     SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d in %s\n",copymode,__FUNCT__);
706da1bb401SStefano Zampini   }
70736e030ebSStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr);
708575ad6abSStefano Zampini   /* free arrays if PCBDDC is not the PC type */
709575ad6abSStefano Zampini   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr);
710575ad6abSStefano Zampini   if (!f && copymode == PETSC_OWN_POINTER) {
711575ad6abSStefano Zampini     ierr = PetscFree(xadj);CHKERRQ(ierr);
712575ad6abSStefano Zampini     ierr = PetscFree(adjncy);CHKERRQ(ierr);
71336e030ebSStefano Zampini   }
71436e030ebSStefano Zampini   PetscFunctionReturn(0);
71536e030ebSStefano Zampini }
7169c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */
7171e6b0712SBarry Smith 
7189c0446d6SStefano Zampini #undef __FUNCT__
719*63602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal_BDDC"
720*63602bcaSStefano Zampini static PetscErrorCode PCBDDCSetDofsSplittingLocal_BDDC(PC pc,PetscInt n_is, IS ISForDofs[])
721*63602bcaSStefano Zampini {
722*63602bcaSStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
723*63602bcaSStefano Zampini   PetscInt i;
724*63602bcaSStefano Zampini   PetscErrorCode ierr;
725*63602bcaSStefano Zampini 
726*63602bcaSStefano Zampini   PetscFunctionBegin;
727*63602bcaSStefano Zampini   /* Destroy ISes if they were already set */
728*63602bcaSStefano Zampini   for (i=0;i<pcbddc->n_ISForDofsLocal;i++) {
729*63602bcaSStefano Zampini     ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr);
730*63602bcaSStefano Zampini   }
731*63602bcaSStefano Zampini   ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr);
732*63602bcaSStefano Zampini   /* last user setting takes precendence -> destroy any other customization */
733*63602bcaSStefano Zampini   for (i=0;i<pcbddc->n_ISForDofs;i++) {
734*63602bcaSStefano Zampini     ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr);
735*63602bcaSStefano Zampini   }
736*63602bcaSStefano Zampini   ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr);
737*63602bcaSStefano Zampini   pcbddc->n_ISForDofs = 0;
738*63602bcaSStefano Zampini   /* allocate space then set */
739*63602bcaSStefano Zampini   ierr = PetscMalloc(n_is*sizeof(IS),&pcbddc->ISForDofsLocal);CHKERRQ(ierr);
740*63602bcaSStefano Zampini   for (i=0;i<n_is;i++) {
741*63602bcaSStefano Zampini     ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr);
742*63602bcaSStefano Zampini     pcbddc->ISForDofsLocal[i]=ISForDofs[i];
743*63602bcaSStefano Zampini   }
744*63602bcaSStefano Zampini   pcbddc->n_ISForDofsLocal=n_is;
745*63602bcaSStefano Zampini   if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE;
746*63602bcaSStefano Zampini   PetscFunctionReturn(0);
747*63602bcaSStefano Zampini }
748*63602bcaSStefano Zampini 
749*63602bcaSStefano Zampini #undef __FUNCT__
750*63602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal"
751*63602bcaSStefano Zampini /*@
752*63602bcaSStefano Zampini  PCBDDCSetDofsSplittingLocal - Set index sets defining fields of the local subdomain matrix
753*63602bcaSStefano Zampini 
754*63602bcaSStefano Zampini    Collective
755*63602bcaSStefano Zampini 
756*63602bcaSStefano Zampini    Input Parameters:
757*63602bcaSStefano Zampini +  pc - the preconditioning context
758*63602bcaSStefano Zampini -  n_is - number of index sets defining the fields
759*63602bcaSStefano Zampini .  ISForDofs - array of IS describing the fields in local ordering
760*63602bcaSStefano Zampini 
761*63602bcaSStefano Zampini    Level: intermediate
762*63602bcaSStefano Zampini 
763*63602bcaSStefano Zampini    Notes: n_is should be the same among processes. Not all nodes need to be listed: unlisted nodes will belong to a different field.
764*63602bcaSStefano Zampini 
765*63602bcaSStefano Zampini .seealso: PCBDDC
766*63602bcaSStefano Zampini @*/
767*63602bcaSStefano Zampini PetscErrorCode PCBDDCSetDofsSplittingLocal(PC pc,PetscInt n_is, IS ISForDofs[])
768*63602bcaSStefano Zampini {
769*63602bcaSStefano Zampini   PetscInt       i;
770*63602bcaSStefano Zampini   PetscErrorCode ierr;
771*63602bcaSStefano Zampini 
772*63602bcaSStefano Zampini   PetscFunctionBegin;
773*63602bcaSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
774*63602bcaSStefano Zampini   PetscValidLogicalCollectiveInt(pc,n_is,2);
775*63602bcaSStefano Zampini   for (i=0;i<n_is;i++) {
776*63602bcaSStefano Zampini     PetscCheckSameComm(pc,1,ISForDofs[i],3);
777*63602bcaSStefano Zampini     PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3);
778*63602bcaSStefano Zampini   }
779*63602bcaSStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr);
780*63602bcaSStefano Zampini   PetscFunctionReturn(0);
781*63602bcaSStefano Zampini }
782*63602bcaSStefano Zampini /* -------------------------------------------------------------------------- */
783*63602bcaSStefano Zampini 
784*63602bcaSStefano Zampini #undef __FUNCT__
7859c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC"
7869c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[])
7879c0446d6SStefano Zampini {
7889c0446d6SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
7899c0446d6SStefano Zampini   PetscInt i;
7909c0446d6SStefano Zampini   PetscErrorCode ierr;
7919c0446d6SStefano Zampini 
7929c0446d6SStefano Zampini   PetscFunctionBegin;
793da1bb401SStefano Zampini   /* Destroy ISes if they were already set */
7949c0446d6SStefano Zampini   for (i=0;i<pcbddc->n_ISForDofs;i++) {
7959c0446d6SStefano Zampini     ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr);
7969c0446d6SStefano Zampini   }
797d11ae9bbSstefano_zampini   ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr);
798*63602bcaSStefano Zampini   /* last user setting takes precendence -> destroy any other customization */
799*63602bcaSStefano Zampini   for (i=0;i<pcbddc->n_ISForDofsLocal;i++) {
800*63602bcaSStefano Zampini     ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr);
801*63602bcaSStefano Zampini   }
802*63602bcaSStefano Zampini   ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr);
803*63602bcaSStefano Zampini   pcbddc->n_ISForDofsLocal = 0;
804da1bb401SStefano Zampini   /* allocate space then set */
8059c0446d6SStefano Zampini   ierr = PetscMalloc(n_is*sizeof(IS),&pcbddc->ISForDofs);CHKERRQ(ierr);
8069c0446d6SStefano Zampini   for (i=0;i<n_is;i++) {
807da1bb401SStefano Zampini     ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr);
808da1bb401SStefano Zampini     pcbddc->ISForDofs[i]=ISForDofs[i];
8099c0446d6SStefano Zampini   }
8109c0446d6SStefano Zampini   pcbddc->n_ISForDofs=n_is;
811*63602bcaSStefano Zampini   if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE;
8129c0446d6SStefano Zampini   PetscFunctionReturn(0);
8139c0446d6SStefano Zampini }
8141e6b0712SBarry Smith 
8159c0446d6SStefano Zampini #undef __FUNCT__
8169c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting"
8179c0446d6SStefano Zampini /*@
818*63602bcaSStefano Zampini  PCBDDCSetDofsSplitting - Set index sets defining fields of the global matrix
8199c0446d6SStefano Zampini 
820*63602bcaSStefano Zampini    Collective
8219c0446d6SStefano Zampini 
8229c0446d6SStefano Zampini    Input Parameters:
8239c0446d6SStefano Zampini +  pc - the preconditioning context
82428509bceSStefano Zampini -  n_is - number of index sets defining the fields
825*63602bcaSStefano Zampini .  ISForDofs - array of IS describing the fields in global ordering
8269c0446d6SStefano Zampini 
8279c0446d6SStefano Zampini    Level: intermediate
8289c0446d6SStefano Zampini 
829*63602bcaSStefano Zampini    Notes: Any process can list any global node. Not all nodes need to be listed: unlisted nodes will belong to a different field.
8309c0446d6SStefano Zampini 
8319c0446d6SStefano Zampini .seealso: PCBDDC
8329c0446d6SStefano Zampini @*/
8339c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[])
8349c0446d6SStefano Zampini {
8352b510759SStefano Zampini   PetscInt       i;
8369c0446d6SStefano Zampini   PetscErrorCode ierr;
8379c0446d6SStefano Zampini 
8389c0446d6SStefano Zampini   PetscFunctionBegin;
8399c0446d6SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
840*63602bcaSStefano Zampini   PetscValidLogicalCollectiveInt(pc,n_is,2);
8412b510759SStefano Zampini   for (i=0;i<n_is;i++) {
842*63602bcaSStefano Zampini     PetscCheckSameComm(pc,1,ISForDofs[i],3);
843*63602bcaSStefano Zampini     PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3);
8442b510759SStefano Zampini   }
8459c0446d6SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr);
8469c0446d6SStefano Zampini   PetscFunctionReturn(0);
8479c0446d6SStefano Zampini }
848da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */
849534831adSStefano Zampini #undef __FUNCT__
850534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC"
851534831adSStefano Zampini /* -------------------------------------------------------------------------- */
852534831adSStefano Zampini /*
853534831adSStefano Zampini    PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial
854534831adSStefano Zampini                      guess if a transformation of basis approach has been selected.
8559c0446d6SStefano Zampini 
856534831adSStefano Zampini    Input Parameter:
857534831adSStefano Zampini +  pc - the preconditioner contex
858534831adSStefano Zampini 
859534831adSStefano Zampini    Application Interface Routine: PCPreSolve()
860534831adSStefano Zampini 
861534831adSStefano Zampini    Notes:
862534831adSStefano Zampini    The interface routine PCPreSolve() is not usually called directly by
863534831adSStefano Zampini    the user, but instead is called by KSPSolve().
864534831adSStefano Zampini */
865534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x)
866534831adSStefano Zampini {
867534831adSStefano Zampini   PetscErrorCode ierr;
868534831adSStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
869534831adSStefano Zampini   PC_IS          *pcis = (PC_IS*)(pc->data);
870534831adSStefano Zampini   Mat_IS         *matis = (Mat_IS*)pc->pmat->data;
871534831adSStefano Zampini   Mat            temp_mat;
8723972b0daSStefano Zampini   IS             dirIS;
8733972b0daSStefano Zampini   Vec            used_vec;
87482ba6b80SStefano Zampini   PetscBool      guess_nonzero;
875534831adSStefano Zampini 
876534831adSStefano Zampini   PetscFunctionBegin;
87785c4d303SStefano Zampini   /* if we are working with cg, one dirichlet solve can be avoided during Krylov iterations */
87885c4d303SStefano Zampini   if (ksp) {
87985c4d303SStefano Zampini     PetscBool iscg;
88085c4d303SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr);
88185c4d303SStefano Zampini     if (!iscg) {
88285c4d303SStefano Zampini       ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr);
88385c4d303SStefano Zampini     }
88485c4d303SStefano Zampini   }
88585c4d303SStefano Zampini   /* Creates parallel work vectors used in presolve */
88662a6ff1dSStefano Zampini   if (!pcbddc->original_rhs) {
88762a6ff1dSStefano Zampini     ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr);
88862a6ff1dSStefano Zampini   }
88962a6ff1dSStefano Zampini   if (!pcbddc->temp_solution) {
89062a6ff1dSStefano Zampini     ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr);
89162a6ff1dSStefano Zampini   }
8923972b0daSStefano Zampini   if (x) {
8933972b0daSStefano Zampini     ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);
8943972b0daSStefano Zampini     used_vec = x;
8953972b0daSStefano Zampini   } else {
8963972b0daSStefano Zampini     ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr);
8973972b0daSStefano Zampini     used_vec = pcbddc->temp_solution;
8983972b0daSStefano Zampini     ierr = VecSet(used_vec,0.0);CHKERRQ(ierr);
8993972b0daSStefano Zampini   }
9003972b0daSStefano Zampini   /* hack into ksp data structure PCPreSolve comes earlier in src/ksp/ksp/interface/itfunc.c */
9013972b0daSStefano Zampini   if (ksp) {
9023972b0daSStefano Zampini     ierr = KSPGetInitialGuessNonzero(ksp,&guess_nonzero);CHKERRQ(ierr);
9033972b0daSStefano Zampini     if (!guess_nonzero) {
9043972b0daSStefano Zampini       ierr = VecSet(used_vec,0.0);CHKERRQ(ierr);
9053972b0daSStefano Zampini     }
9063972b0daSStefano Zampini   }
9073308cffdSStefano Zampini 
9083972b0daSStefano Zampini   /* store the original rhs */
9093972b0daSStefano Zampini   ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr);
9103972b0daSStefano Zampini 
9113972b0daSStefano Zampini   /* Take into account zeroed rows -> change rhs and store solution removed */
912785d1243SStefano Zampini   /* note that Dirichlet boundaries in global ordering (if any) has already been translated into local ordering in PCBDDCAnalyzeInterface */
91382ba6b80SStefano Zampini   ierr = PCBDDCGetDirichletBoundariesLocal(pc,&dirIS);CHKERRQ(ierr);
91482ba6b80SStefano Zampini   if (rhs && dirIS) {
915785d1243SStefano Zampini     PetscInt    dirsize,i,*is_indices;
916785d1243SStefano Zampini     PetscScalar *array_x,*array_diagonal;
917785d1243SStefano Zampini 
9183972b0daSStefano Zampini     ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr);
9193972b0daSStefano Zampini     ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr);
9203972b0daSStefano Zampini     ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
9213972b0daSStefano Zampini     ierr = VecScatterEnd(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
9223972b0daSStefano Zampini     ierr = VecScatterBegin(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
9233972b0daSStefano Zampini     ierr = VecScatterEnd(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
92482ba6b80SStefano Zampini     ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr);
9253972b0daSStefano Zampini     ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr);
9263972b0daSStefano Zampini     ierr = VecGetArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr);
9273972b0daSStefano Zampini     ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr);
9282fa5cd67SKarl Rupp     for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]];
9293972b0daSStefano Zampini     ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr);
9303972b0daSStefano Zampini     ierr = VecRestoreArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr);
9313972b0daSStefano Zampini     ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr);
9323972b0daSStefano Zampini     ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
9333972b0daSStefano Zampini     ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
934b76ba322SStefano Zampini 
9353972b0daSStefano Zampini     /* remove the computed solution from the rhs */
9363972b0daSStefano Zampini     ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr);
9373972b0daSStefano Zampini     ierr = MatMultAdd(pc->pmat,used_vec,rhs,rhs);CHKERRQ(ierr);
9383972b0daSStefano Zampini     ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr);
9393308cffdSStefano Zampini   }
940b76ba322SStefano Zampini 
941b76ba322SStefano Zampini   /* store partially computed solution and set initial guess */
9423972b0daSStefano Zampini   if (x) {
9433972b0daSStefano Zampini     ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr);
9443972b0daSStefano Zampini     ierr = VecSet(used_vec,0.0);CHKERRQ(ierr);
94585c4d303SStefano Zampini     if (pcbddc->use_exact_dirichlet_trick) {
946b76ba322SStefano Zampini       ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
947b76ba322SStefano Zampini       ierr = VecScatterEnd  (pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
948b76ba322SStefano Zampini       ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr);
949b76ba322SStefano Zampini       ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
950b76ba322SStefano Zampini       ierr = VecScatterEnd  (pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
951b76ba322SStefano Zampini       if (ksp) {
952b76ba322SStefano Zampini         ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr);
953b76ba322SStefano Zampini       }
954b76ba322SStefano Zampini     }
9553972b0daSStefano Zampini   }
956b76ba322SStefano Zampini 
95792e3dcfbSStefano Zampini   /* prepare MatMult and rhs for solver */
958674ae819SStefano Zampini   if (pcbddc->use_change_of_basis) {
959b76ba322SStefano Zampini     /* swap pointers for local matrices */
960b76ba322SStefano Zampini     temp_mat = matis->A;
961b76ba322SStefano Zampini     matis->A = pcbddc->local_mat;
962b76ba322SStefano Zampini     pcbddc->local_mat = temp_mat;
96392e3dcfbSStefano Zampini     if (rhs) {
964b76ba322SStefano Zampini       /* Get local rhs and apply transformation of basis */
965b76ba322SStefano Zampini       ierr = VecScatterBegin(pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
966b76ba322SStefano Zampini       ierr = VecScatterEnd  (pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
967b76ba322SStefano Zampini       /* from original basis to modified basis */
968b76ba322SStefano Zampini       ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr);
969b76ba322SStefano Zampini       /* put back modified values into the global vec using INSERT_VALUES copy mode */
970b76ba322SStefano Zampini       ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
971b76ba322SStefano Zampini       ierr = VecScatterEnd  (pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
972674ae819SStefano Zampini     }
97392e3dcfbSStefano Zampini   }
97492e3dcfbSStefano Zampini 
97592e3dcfbSStefano Zampini   /* remove nullspace if present */
9760bdf917eSStefano Zampini   if (ksp && pcbddc->NullSpace) {
977d0195637SJed Brown     ierr = MatNullSpaceRemove(pcbddc->NullSpace,used_vec);CHKERRQ(ierr);
978d0195637SJed Brown     ierr = MatNullSpaceRemove(pcbddc->NullSpace,rhs);CHKERRQ(ierr);
979b76ba322SStefano Zampini   }
9800bdf917eSStefano Zampini   ierr = VecDestroy(&used_vec);CHKERRQ(ierr);
981534831adSStefano Zampini   PetscFunctionReturn(0);
982534831adSStefano Zampini }
983534831adSStefano Zampini /* -------------------------------------------------------------------------- */
984534831adSStefano Zampini #undef __FUNCT__
985534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC"
986534831adSStefano Zampini /* -------------------------------------------------------------------------- */
987534831adSStefano Zampini /*
988534831adSStefano Zampini    PCPostSolve_BDDC - Changes the computed solution if a transformation of basis
989534831adSStefano Zampini                      approach has been selected. Also, restores rhs to its original state.
990534831adSStefano Zampini 
991534831adSStefano Zampini    Input Parameter:
992534831adSStefano Zampini +  pc - the preconditioner contex
993534831adSStefano Zampini 
994534831adSStefano Zampini    Application Interface Routine: PCPostSolve()
995534831adSStefano Zampini 
996534831adSStefano Zampini    Notes:
997534831adSStefano Zampini    The interface routine PCPostSolve() is not usually called directly by
998534831adSStefano Zampini    the user, but instead is called by KSPSolve().
999534831adSStefano Zampini */
1000534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x)
1001534831adSStefano Zampini {
1002534831adSStefano Zampini   PetscErrorCode ierr;
1003534831adSStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
1004534831adSStefano Zampini   PC_IS          *pcis   = (PC_IS*)(pc->data);
1005534831adSStefano Zampini   Mat_IS         *matis = (Mat_IS*)pc->pmat->data;
1006534831adSStefano Zampini   Mat            temp_mat;
1007534831adSStefano Zampini 
1008534831adSStefano Zampini   PetscFunctionBegin;
1009674ae819SStefano Zampini   if (pcbddc->use_change_of_basis) {
1010534831adSStefano Zampini     /* swap pointers for local matrices */
1011534831adSStefano Zampini     temp_mat = matis->A;
1012534831adSStefano Zampini     matis->A = pcbddc->local_mat;
1013534831adSStefano Zampini     pcbddc->local_mat = temp_mat;
10143425bc38SStefano Zampini   }
10153308cffdSStefano Zampini   if (pcbddc->use_change_of_basis && x) {
1016534831adSStefano Zampini     /* Get Local boundary and apply transformation of basis to solution vector */
1017534831adSStefano Zampini     ierr = VecScatterBegin(pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1018534831adSStefano Zampini     ierr = VecScatterEnd  (pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1019534831adSStefano Zampini     /* from modified basis to original basis */
1020534831adSStefano Zampini     ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr);
1021534831adSStefano Zampini     /* put back modified values into the global vec using INSERT_VALUES copy mode */
1022534831adSStefano Zampini     ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1023534831adSStefano Zampini     ierr = VecScatterEnd  (pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1024534831adSStefano Zampini   }
10253972b0daSStefano Zampini   /* add solution removed in presolve */
10263425bc38SStefano Zampini   if (x) {
10273425bc38SStefano Zampini     ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr);
10283425bc38SStefano Zampini   }
1029fb223d50SStefano Zampini   /* restore rhs to its original state */
1030fb223d50SStefano Zampini   if (rhs) {
1031fb223d50SStefano Zampini     ierr = VecCopy(pcbddc->original_rhs,rhs);CHKERRQ(ierr);
1032fb223d50SStefano Zampini   }
1033534831adSStefano Zampini   PetscFunctionReturn(0);
1034534831adSStefano Zampini }
1035534831adSStefano Zampini /* -------------------------------------------------------------------------- */
103653cdbc3dSStefano Zampini #undef __FUNCT__
103753cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC"
10380c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
10390c7d97c5SJed Brown /*
10400c7d97c5SJed Brown    PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner
10410c7d97c5SJed Brown                   by setting data structures and options.
10420c7d97c5SJed Brown 
10430c7d97c5SJed Brown    Input Parameter:
104453cdbc3dSStefano Zampini +  pc - the preconditioner context
10450c7d97c5SJed Brown 
10460c7d97c5SJed Brown    Application Interface Routine: PCSetUp()
10470c7d97c5SJed Brown 
10480c7d97c5SJed Brown    Notes:
10490c7d97c5SJed Brown    The interface routine PCSetUp() is not usually called directly by
10500c7d97c5SJed Brown    the user, but instead is called by PCApply() if necessary.
10510c7d97c5SJed Brown */
105253cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc)
10530c7d97c5SJed Brown {
10540c7d97c5SJed Brown   PetscErrorCode ierr;
10550c7d97c5SJed Brown   PC_BDDC*       pcbddc = (PC_BDDC*)pc->data;
1056674ae819SStefano Zampini   MatStructure   flag;
1057674ae819SStefano Zampini   PetscBool      computeis,computetopography,computesolvers;
10580c7d97c5SJed Brown 
10590c7d97c5SJed Brown   PetscFunctionBegin;
1060674ae819SStefano Zampini   /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other nonoverlapping preconditioners */
1061fcd409f5SStefano Zampini   /* PCIS does not support MatStructures different from SAME_PRECONDITIONER */
10623b03a366Sstefano_zampini   /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup
1063fcd409f5SStefano Zampini      Also, BDDC directly build the Dirichlet problem */
10643b03a366Sstefano_zampini   /* Get stdout for dbg */
1065674ae819SStefano Zampini   if (pcbddc->dbg_flag && !pcbddc->dbg_viewer) {
1066ce94432eSBarry Smith     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pc),&pcbddc->dbg_viewer);CHKERRQ(ierr);
1067e269702eSStefano Zampini     ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr);
10682b510759SStefano Zampini     if (pcbddc->current_level) {
10692b510759SStefano Zampini       ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2);CHKERRQ(ierr);
10702b510759SStefano Zampini     }
1071e269702eSStefano Zampini   }
1072674ae819SStefano Zampini   /* first attempt to split work */
1073674ae819SStefano Zampini   if (pc->setupcalled) {
1074674ae819SStefano Zampini     computeis = PETSC_FALSE;
1075674ae819SStefano Zampini     ierr = PCGetOperators(pc,NULL,NULL,&flag);CHKERRQ(ierr);
1076674ae819SStefano Zampini     if (flag == SAME_PRECONDITIONER) {
1077674ae819SStefano Zampini       computetopography = PETSC_FALSE;
1078674ae819SStefano Zampini       computesolvers = PETSC_FALSE;
1079674ae819SStefano Zampini     } else if (flag == SAME_NONZERO_PATTERN) {
1080674ae819SStefano Zampini       computetopography = PETSC_FALSE;
1081674ae819SStefano Zampini       computesolvers = PETSC_TRUE;
1082674ae819SStefano Zampini     } else { /* DIFFERENT_NONZERO_PATTERN */
1083674ae819SStefano Zampini       computetopography = PETSC_TRUE;
1084674ae819SStefano Zampini       computesolvers = PETSC_TRUE;
1085674ae819SStefano Zampini     }
1086674ae819SStefano Zampini   } else {
1087674ae819SStefano Zampini     computeis = PETSC_TRUE;
1088674ae819SStefano Zampini     computetopography = PETSC_TRUE;
1089674ae819SStefano Zampini     computesolvers = PETSC_TRUE;
1090674ae819SStefano Zampini   }
1091fcd409f5SStefano Zampini   /* Set up all the "iterative substructuring" common block without computing solvers */
1092674ae819SStefano Zampini   if (computeis) {
1093fcd409f5SStefano Zampini     /* HACK INTO PCIS */
1094fcd409f5SStefano Zampini     PC_IS* pcis = (PC_IS*)pc->data;
1095fcd409f5SStefano Zampini     pcis->computesolvers = PETSC_FALSE;
1096674ae819SStefano Zampini     ierr = PCISSetUp(pc);CHKERRQ(ierr);
1097674ae819SStefano Zampini   }
1098674ae819SStefano Zampini   /* Analyze interface and set up local constraint and change of basis matrices */
1099674ae819SStefano Zampini   if (computetopography) {
1100674ae819SStefano Zampini     /* reset data */
1101674ae819SStefano Zampini     ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr);
1102674ae819SStefano Zampini     ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr);
1103674ae819SStefano Zampini     ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr);
1104674ae819SStefano Zampini   }
1105674ae819SStefano Zampini   if (computesolvers) {
1106674ae819SStefano Zampini     /* reset data */
1107674ae819SStefano Zampini     ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr);
1108674ae819SStefano Zampini     ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr);
110999cc7994SStefano Zampini     /* Create coarse and local stuffs */
111099cc7994SStefano Zampini     ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr);
1111674ae819SStefano Zampini     ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr);
11120c7d97c5SJed Brown   }
11132b510759SStefano Zampini   if (pcbddc->dbg_flag && pcbddc->current_level) {
11142b510759SStefano Zampini     ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2);CHKERRQ(ierr);
11152b510759SStefano Zampini   }
11160c7d97c5SJed Brown   PetscFunctionReturn(0);
11170c7d97c5SJed Brown }
11180c7d97c5SJed Brown 
11190c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
11200c7d97c5SJed Brown /*
11210c7d97c5SJed Brown    PCApply_BDDC - Applies the BDDC preconditioner to a vector.
11220c7d97c5SJed Brown 
11230c7d97c5SJed Brown    Input Parameters:
11240c7d97c5SJed Brown .  pc - the preconditioner context
11250c7d97c5SJed Brown .  r - input vector (global)
11260c7d97c5SJed Brown 
11270c7d97c5SJed Brown    Output Parameter:
11280c7d97c5SJed Brown .  z - output vector (global)
11290c7d97c5SJed Brown 
11300c7d97c5SJed Brown    Application Interface Routine: PCApply()
11310c7d97c5SJed Brown  */
11320c7d97c5SJed Brown #undef __FUNCT__
11330c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC"
113453cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z)
11350c7d97c5SJed Brown {
11360c7d97c5SJed Brown   PC_IS             *pcis = (PC_IS*)(pc->data);
11370c7d97c5SJed Brown   PC_BDDC           *pcbddc = (PC_BDDC*)(pc->data);
11380c7d97c5SJed Brown   PetscErrorCode    ierr;
11393b03a366Sstefano_zampini   const PetscScalar one = 1.0;
11403b03a366Sstefano_zampini   const PetscScalar m_one = -1.0;
11412617d88aSStefano Zampini   const PetscScalar zero = 0.0;
11420c7d97c5SJed Brown 
11430c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN
11440c7d97c5SJed Brown    NN interface preconditioner changed to BDDC
11458eeda7d8SStefano Zampini    Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static = PETSC_TRUE) */
11460c7d97c5SJed Brown 
11470c7d97c5SJed Brown   PetscFunctionBegin;
114885c4d303SStefano Zampini   if (!pcbddc->use_exact_dirichlet_trick) {
11490c7d97c5SJed Brown     /* First Dirichlet solve */
11500c7d97c5SJed Brown     ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
11510c7d97c5SJed Brown     ierr = VecScatterEnd  (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
115253cdbc3dSStefano Zampini     ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr);
11530c7d97c5SJed Brown     /*
11540c7d97c5SJed Brown       Assembling right hand side for BDDC operator
1155674ae819SStefano Zampini       - pcis->vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE)
1156674ae819SStefano Zampini       - pcis->vec1_B the interface part of the global vector z
11570c7d97c5SJed Brown     */
11580c7d97c5SJed Brown     ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr);
11590c7d97c5SJed Brown     ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr);
11608eeda7d8SStefano Zampini     if (pcbddc->switch_static) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); }
11610c7d97c5SJed Brown     ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr);
11620c7d97c5SJed Brown     ierr = VecCopy(r,z);CHKERRQ(ierr);
11630c7d97c5SJed Brown     ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
11640c7d97c5SJed Brown     ierr = VecScatterEnd  (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1165674ae819SStefano Zampini     ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr);
1166b76ba322SStefano Zampini   } else {
11670bdf917eSStefano Zampini     ierr = VecSet(pcis->vec1_D,zero);CHKERRQ(ierr);
1168b76ba322SStefano Zampini     ierr = VecSet(pcis->vec2_D,zero);CHKERRQ(ierr);
1169674ae819SStefano Zampini     ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr);
1170b76ba322SStefano Zampini   }
1171b76ba322SStefano Zampini 
11722617d88aSStefano Zampini   /* Apply interface preconditioner
11732617d88aSStefano Zampini      input/output vecs: pcis->vec1_B and pcis->vec1_D */
11742617d88aSStefano Zampini   ierr = PCBDDCApplyInterfacePreconditioner(pc);CHKERRQ(ierr);
11752617d88aSStefano Zampini 
1176674ae819SStefano Zampini   /* Apply transpose of partition of unity operator */
1177674ae819SStefano Zampini   ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr);
11780c7d97c5SJed Brown 
11793b03a366Sstefano_zampini   /* Second Dirichlet solve and assembling of output */
11800c7d97c5SJed Brown   ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
11810c7d97c5SJed Brown   ierr = VecScatterEnd  (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
11820c7d97c5SJed Brown   ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr);
11838eeda7d8SStefano Zampini   if (pcbddc->switch_static) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); }
118453cdbc3dSStefano Zampini   ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr);
11850c7d97c5SJed Brown   ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr);
11868eeda7d8SStefano Zampini   if (pcbddc->switch_static) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); }
11870c7d97c5SJed Brown   ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr);
11880c7d97c5SJed Brown   ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
11890c7d97c5SJed Brown   ierr = VecScatterEnd  (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
11900c7d97c5SJed Brown   PetscFunctionReturn(0);
11910c7d97c5SJed Brown }
1192da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */
1193674ae819SStefano Zampini 
1194da1bb401SStefano Zampini #undef __FUNCT__
1195da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC"
1196da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc)
1197da1bb401SStefano Zampini {
1198da1bb401SStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
1199da1bb401SStefano Zampini   PetscErrorCode ierr;
1200da1bb401SStefano Zampini 
1201da1bb401SStefano Zampini   PetscFunctionBegin;
1202da1bb401SStefano Zampini   /* free data created by PCIS */
1203da1bb401SStefano Zampini   ierr = PCISDestroy(pc);CHKERRQ(ierr);
1204674ae819SStefano Zampini   /* free BDDC custom data  */
1205674ae819SStefano Zampini   ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr);
1206674ae819SStefano Zampini   /* destroy objects related to topography */
1207674ae819SStefano Zampini   ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr);
1208674ae819SStefano Zampini   /* free allocated graph structure */
1209da1bb401SStefano Zampini   ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr);
1210674ae819SStefano Zampini   /* free data for scaling operator */
1211674ae819SStefano Zampini   ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr);
1212674ae819SStefano Zampini   /* free solvers stuff */
1213674ae819SStefano Zampini   ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr);
121433bc96a4SStefano Zampini   ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr);
121533bc96a4SStefano Zampini   ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr);
12169881197aSStefano Zampini   ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr);
1217ac78edfcSStefano Zampini   ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr);
121862a6ff1dSStefano Zampini   /* free global vectors needed in presolve */
121962a6ff1dSStefano Zampini   ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr);
122062a6ff1dSStefano Zampini   ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr);
12213425bc38SStefano Zampini   /* remove functions */
1222674ae819SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr);
1223bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr);
12242b510759SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr);
1225b8ffe317SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr);
12262b510759SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr);
1227bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",NULL);CHKERRQ(ierr);
1228785d1243SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr);
122982ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr);
1230785d1243SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr);
123182ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr);
1232785d1243SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr);
123382ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr);
1234785d1243SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr);
1235785d1243SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr);
1236bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr);
1237*63602bcaSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",NULL);CHKERRQ(ierr);
1238bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr);
1239bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr);
1240bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr);
1241bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr);
1242674ae819SStefano Zampini   /* Free the private data structure */
1243674ae819SStefano Zampini   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1244da1bb401SStefano Zampini   PetscFunctionReturn(0);
1245da1bb401SStefano Zampini }
12463425bc38SStefano Zampini /* -------------------------------------------------------------------------- */
12471e6b0712SBarry Smith 
12483425bc38SStefano Zampini #undef __FUNCT__
12493425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC"
12503425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs)
12513425bc38SStefano Zampini {
1252674ae819SStefano Zampini   FETIDPMat_ctx  mat_ctx;
12533425bc38SStefano Zampini   PC_IS*         pcis;
12543425bc38SStefano Zampini   PC_BDDC*       pcbddc;
12553425bc38SStefano Zampini   PetscErrorCode ierr;
12560c7d97c5SJed Brown 
12573425bc38SStefano Zampini   PetscFunctionBegin;
12583425bc38SStefano Zampini   ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr);
12593425bc38SStefano Zampini   pcis = (PC_IS*)mat_ctx->pc->data;
12603425bc38SStefano Zampini   pcbddc = (PC_BDDC*)mat_ctx->pc->data;
12613425bc38SStefano Zampini 
12623425bc38SStefano Zampini   /* change of basis for physical rhs if needed
12633425bc38SStefano Zampini      It also changes the rhs in case of dirichlet boundaries */
12643308cffdSStefano Zampini   ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,standard_rhs,NULL);CHKERRQ(ierr);
12653425bc38SStefano Zampini   /* store vectors for computation of fetidp final solution */
12663425bc38SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
12673425bc38SStefano Zampini   ierr = VecScatterEnd(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1268fb223d50SStefano Zampini   /* scale rhs since it should be unassembled */
1269fb223d50SStefano Zampini   /* TODO use counter scaling? (also below) */
12703425bc38SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
12713425bc38SStefano Zampini   ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1272674ae819SStefano Zampini   /* Apply partition of unity */
12733425bc38SStefano Zampini   ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr);
1274674ae819SStefano Zampini   /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */
12758eeda7d8SStefano Zampini   if (!pcbddc->switch_static) {
12763425bc38SStefano Zampini     /* compute partially subassembled Schur complement right-hand side */
12773425bc38SStefano Zampini     ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr);
12783425bc38SStefano Zampini     ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr);
12793425bc38SStefano Zampini     ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr);
12803425bc38SStefano Zampini     ierr = VecSet(standard_rhs,0.0);CHKERRQ(ierr);
12813425bc38SStefano Zampini     ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
12823425bc38SStefano Zampini     ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1283674ae819SStefano Zampini     /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */
12843425bc38SStefano Zampini     ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
12853425bc38SStefano Zampini     ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
12863425bc38SStefano Zampini     ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr);
12873425bc38SStefano Zampini   }
12883425bc38SStefano Zampini   /* BDDC rhs */
12893425bc38SStefano Zampini   ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr);
12908eeda7d8SStefano Zampini   if (pcbddc->switch_static) {
12913425bc38SStefano Zampini     ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr);
12923425bc38SStefano Zampini   }
12933425bc38SStefano Zampini   /* apply BDDC */
12943425bc38SStefano Zampini   ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr);
12953425bc38SStefano Zampini   /* Application of B_delta and assembling of rhs for fetidp fluxes */
12963425bc38SStefano Zampini   ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr);
12973425bc38SStefano Zampini   ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr);
12983425bc38SStefano Zampini   ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
12993425bc38SStefano Zampini   ierr = VecScatterEnd  (mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
13003425bc38SStefano Zampini   /* restore original rhs */
13013425bc38SStefano Zampini   ierr = VecCopy(pcbddc->original_rhs,standard_rhs);CHKERRQ(ierr);
13023425bc38SStefano Zampini   PetscFunctionReturn(0);
13033425bc38SStefano Zampini }
13041e6b0712SBarry Smith 
13053425bc38SStefano Zampini #undef __FUNCT__
13063425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS"
13073425bc38SStefano Zampini /*@
130828509bceSStefano Zampini  PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETIDP linear system
13093425bc38SStefano Zampini 
13103425bc38SStefano Zampini    Collective
13113425bc38SStefano Zampini 
13123425bc38SStefano Zampini    Input Parameters:
131328509bceSStefano Zampini +  fetidp_mat   - the FETIDP matrix object obtained by calling PCBDDCCreateFETIDPOperators
131428509bceSStefano Zampini .  standard_rhs - the right-hand side for your linear system
13153425bc38SStefano Zampini 
13163425bc38SStefano Zampini    Output Parameters:
131728509bceSStefano Zampini -  fetidp_flux_rhs   - the right-hand side for the FETIDP linear system
13183425bc38SStefano Zampini 
13193425bc38SStefano Zampini    Level: developer
13203425bc38SStefano Zampini 
13213425bc38SStefano Zampini    Notes:
13223425bc38SStefano Zampini 
132328509bceSStefano Zampini .seealso: PCBDDC,PCBDDCCreateFETIDPOperators
13243425bc38SStefano Zampini @*/
13253425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs)
13263425bc38SStefano Zampini {
1327674ae819SStefano Zampini   FETIDPMat_ctx  mat_ctx;
13283425bc38SStefano Zampini   PetscErrorCode ierr;
13293425bc38SStefano Zampini 
13303425bc38SStefano Zampini   PetscFunctionBegin;
13313425bc38SStefano Zampini   ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr);
13323425bc38SStefano Zampini   ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr);
13333425bc38SStefano Zampini   PetscFunctionReturn(0);
13343425bc38SStefano Zampini }
13353425bc38SStefano Zampini /* -------------------------------------------------------------------------- */
13361e6b0712SBarry Smith 
13373425bc38SStefano Zampini #undef __FUNCT__
13383425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC"
13393425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol)
13403425bc38SStefano Zampini {
1341674ae819SStefano Zampini   FETIDPMat_ctx  mat_ctx;
13423425bc38SStefano Zampini   PC_IS*         pcis;
13433425bc38SStefano Zampini   PC_BDDC*       pcbddc;
13443425bc38SStefano Zampini   PetscErrorCode ierr;
13453425bc38SStefano Zampini 
13463425bc38SStefano Zampini   PetscFunctionBegin;
13473425bc38SStefano Zampini   ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr);
13483425bc38SStefano Zampini   pcis = (PC_IS*)mat_ctx->pc->data;
13493425bc38SStefano Zampini   pcbddc = (PC_BDDC*)mat_ctx->pc->data;
13503425bc38SStefano Zampini 
13513425bc38SStefano Zampini   /* apply B_delta^T */
13523425bc38SStefano Zampini   ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
13533425bc38SStefano Zampini   ierr = VecScatterEnd  (mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
13543425bc38SStefano Zampini   ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr);
13553425bc38SStefano Zampini   /* compute rhs for BDDC application */
13563425bc38SStefano Zampini   ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr);
13578eeda7d8SStefano Zampini   if (pcbddc->switch_static) {
13583425bc38SStefano Zampini     ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr);
13593425bc38SStefano Zampini   }
13603425bc38SStefano Zampini   /* apply BDDC */
13613425bc38SStefano Zampini   ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr);
13623425bc38SStefano Zampini   /* put values into standard global vector */
13633425bc38SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
13643425bc38SStefano Zampini   ierr = VecScatterEnd  (pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
13658eeda7d8SStefano Zampini   if (!pcbddc->switch_static) {
13663425bc38SStefano Zampini     /* compute values into the interior if solved for the partially subassembled Schur complement */
13673425bc38SStefano Zampini     ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr);
13683425bc38SStefano Zampini     ierr = VecAXPY(mat_ctx->temp_solution_D,-1.0,pcis->vec1_D);CHKERRQ(ierr);
13693425bc38SStefano Zampini     ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr);
13703425bc38SStefano Zampini   }
13713425bc38SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
13723425bc38SStefano Zampini   ierr = VecScatterEnd  (pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
13733425bc38SStefano Zampini   /* final change of basis if needed
13743425bc38SStefano Zampini      Is also sums the dirichlet part removed during RHS assembling */
13753308cffdSStefano Zampini   ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr);
13763425bc38SStefano Zampini   PetscFunctionReturn(0);
13773425bc38SStefano Zampini }
13781e6b0712SBarry Smith 
13793425bc38SStefano Zampini #undef __FUNCT__
13803425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution"
13813425bc38SStefano Zampini /*@
138228509bceSStefano Zampini  PCBDDCMatFETIDPGetSolution - Compute the physical solution from the solution of the FETIDP linear system
13833425bc38SStefano Zampini 
13843425bc38SStefano Zampini    Collective
13853425bc38SStefano Zampini 
13863425bc38SStefano Zampini    Input Parameters:
138728509bceSStefano Zampini +  fetidp_mat        - the FETIDP matrix obtained by calling PCBDDCCreateFETIDPOperators
138828509bceSStefano Zampini .  fetidp_flux_sol - the solution of the FETIDP linear system
13893425bc38SStefano Zampini 
13903425bc38SStefano Zampini    Output Parameters:
139128509bceSStefano Zampini -  standard_sol      - the solution defined on the physical domain
13923425bc38SStefano Zampini 
13933425bc38SStefano Zampini    Level: developer
13943425bc38SStefano Zampini 
13953425bc38SStefano Zampini    Notes:
13963425bc38SStefano Zampini 
139728509bceSStefano Zampini .seealso: PCBDDC,PCBDDCCreateFETIDPOperators
13983425bc38SStefano Zampini @*/
13993425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol)
14003425bc38SStefano Zampini {
1401674ae819SStefano Zampini   FETIDPMat_ctx  mat_ctx;
14023425bc38SStefano Zampini   PetscErrorCode ierr;
14033425bc38SStefano Zampini 
14043425bc38SStefano Zampini   PetscFunctionBegin;
14053425bc38SStefano Zampini   ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr);
14063425bc38SStefano Zampini   ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr);
14073425bc38SStefano Zampini   PetscFunctionReturn(0);
14083425bc38SStefano Zampini }
14093425bc38SStefano Zampini /* -------------------------------------------------------------------------- */
14101e6b0712SBarry Smith 
1411f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec);
1412f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat);
1413f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec);
1414f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC);
1415674ae819SStefano Zampini 
14163425bc38SStefano Zampini #undef __FUNCT__
14173425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC"
14183425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, Mat *fetidp_mat, PC *fetidp_pc)
14193425bc38SStefano Zampini {
1420674ae819SStefano Zampini 
1421674ae819SStefano Zampini   FETIDPMat_ctx  fetidpmat_ctx;
14223425bc38SStefano Zampini   Mat            newmat;
1423674ae819SStefano Zampini   FETIDPPC_ctx   fetidppc_ctx;
14243425bc38SStefano Zampini   PC             newpc;
1425ce94432eSBarry Smith   MPI_Comm       comm;
14263425bc38SStefano Zampini   PetscErrorCode ierr;
14273425bc38SStefano Zampini 
14283425bc38SStefano Zampini   PetscFunctionBegin;
1429ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr);
14303425bc38SStefano Zampini   /* FETIDP linear matrix */
14313425bc38SStefano Zampini   ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr);
14323425bc38SStefano Zampini   ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr);
14333425bc38SStefano Zampini   ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr);
14343425bc38SStefano Zampini   ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr);
14353425bc38SStefano Zampini   ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr);
14363425bc38SStefano Zampini   ierr = MatSetUp(newmat);CHKERRQ(ierr);
14373425bc38SStefano Zampini   /* FETIDP preconditioner */
14383425bc38SStefano Zampini   ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr);
14393425bc38SStefano Zampini   ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr);
14403425bc38SStefano Zampini   ierr = PCCreate(comm,&newpc);CHKERRQ(ierr);
14413425bc38SStefano Zampini   ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr);
14423425bc38SStefano Zampini   ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr);
14433425bc38SStefano Zampini   ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr);
14443425bc38SStefano Zampini   ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr);
14453425bc38SStefano Zampini   ierr = PCSetOperators(newpc,newmat,newmat,SAME_PRECONDITIONER);CHKERRQ(ierr);
14463425bc38SStefano Zampini   ierr = PCSetUp(newpc);CHKERRQ(ierr);
14473425bc38SStefano Zampini   /* return pointers for objects created */
14483425bc38SStefano Zampini   *fetidp_mat=newmat;
14493425bc38SStefano Zampini   *fetidp_pc=newpc;
14503425bc38SStefano Zampini   PetscFunctionReturn(0);
14513425bc38SStefano Zampini }
14521e6b0712SBarry Smith 
14533425bc38SStefano Zampini #undef __FUNCT__
14543425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators"
14553425bc38SStefano Zampini /*@
145628509bceSStefano Zampini  PCBDDCCreateFETIDPOperators - Create operators for FETIDP
14573425bc38SStefano Zampini 
14583425bc38SStefano Zampini    Collective
14593425bc38SStefano Zampini 
14603425bc38SStefano Zampini    Input Parameters:
146128509bceSStefano Zampini +  pc - the BDDC preconditioning context already setup
146228509bceSStefano Zampini 
146328509bceSStefano Zampini    Output Parameters:
146428509bceSStefano Zampini .  fetidp_mat - shell FETIDP matrix object
146528509bceSStefano Zampini .  fetidp_pc  - shell Dirichlet preconditioner for FETIDP matrix
146628509bceSStefano Zampini 
146728509bceSStefano Zampini    Options Database Keys:
146828509bceSStefano Zampini -    -fetidp_fullyredundant: use or not a fully redundant set of Lagrange multipliers
14693425bc38SStefano Zampini 
14703425bc38SStefano Zampini    Level: developer
14713425bc38SStefano Zampini 
14723425bc38SStefano Zampini    Notes:
147328509bceSStefano Zampini      Currently the only operation provided for FETIDP matrix is MatMult
14743425bc38SStefano Zampini 
14753425bc38SStefano Zampini .seealso: PCBDDC
14763425bc38SStefano Zampini @*/
14773425bc38SStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, Mat *fetidp_mat, PC *fetidp_pc)
14783425bc38SStefano Zampini {
14793425bc38SStefano Zampini   PetscErrorCode ierr;
14803425bc38SStefano Zampini 
14813425bc38SStefano Zampini   PetscFunctionBegin;
14823425bc38SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14833425bc38SStefano Zampini   if (pc->setupcalled) {
1484516d51a7SStefano Zampini     ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,Mat*,PC*),(pc,fetidp_mat,fetidp_pc));CHKERRQ(ierr);
1485f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n");
14863425bc38SStefano Zampini   PetscFunctionReturn(0);
14873425bc38SStefano Zampini }
14880c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
1489da1bb401SStefano Zampini /*MC
1490da1bb401SStefano Zampini    PCBDDC - Balancing Domain Decomposition by Constraints.
14910c7d97c5SJed Brown 
149228509bceSStefano Zampini    An implementation of the BDDC preconditioner based on
149328509bceSStefano Zampini 
149428509bceSStefano Zampini .vb
149528509bceSStefano Zampini    [1] C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007
149628509bceSStefano Zampini    [2] A. Klawonn and O. B. Widlund. "Dual-Primal FETI Methods for Linear Elasticity", http://cs.nyu.edu/csweb/Research/TechReports/TR2004-855/TR2004-855.pdf
149728509bceSStefano Zampini    [3] J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", http://arxiv.org/abs/0712.3977
149828509bceSStefano Zampini .ve
149928509bceSStefano Zampini 
150028509bceSStefano Zampini    The matrix to be preconditioned (Pmat) must be of type MATIS.
150128509bceSStefano Zampini 
1502b6fdb6dfSStefano Zampini    Currently works with MATIS matrices with local Neumann matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers.
150328509bceSStefano Zampini 
150428509bceSStefano Zampini    It also works with unsymmetric and indefinite problems.
150528509bceSStefano Zampini 
1506b6fdb6dfSStefano Zampini    Unlike 'conventional' interface preconditioners, PCBDDC iterates over all degrees of freedom, not just those on the interface. This allows the use of approximate solvers on the subdomains.
1507b6fdb6dfSStefano Zampini 
150828509bceSStefano Zampini    Approximate local solvers are automatically adapted for singular linear problems (see [1]) if the user has provided the nullspace using PCBDDCSetNullSpace
150928509bceSStefano Zampini 
151028509bceSStefano Zampini    Boundary nodes are split in vertices, edges and faces using information from the local to global mapping of dofs and the local connectivity graph of nodes. The latter can be customized by using PCBDDCSetLocalAdjacencyGraph
151128509bceSStefano Zampini 
151228509bceSStefano Zampini    Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace.
151328509bceSStefano Zampini 
1514b6fdb6dfSStefano Zampini    Change of basis is performed similarly to [2] when requested. When more the one constraint is present on a single connected component (i.e. an edge or a face), a robust method based on local QR factorizations is used.
151528509bceSStefano Zampini 
151628509bceSStefano Zampini    The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using MatPartitioning object.
151728509bceSStefano Zampini 
1518da1bb401SStefano Zampini    Options Database Keys:
151928509bceSStefano Zampini 
152028509bceSStefano Zampini .    -pc_bddc_use_vertices <1> - use or not vertices in primal space
152128509bceSStefano Zampini .    -pc_bddc_use_edges <1> - use or not edges in primal space
1522b6fdb6dfSStefano Zampini .    -pc_bddc_use_faces <0> - use or not faces in primal space
152328509bceSStefano Zampini .    -pc_bddc_use_change_of_basis <0> - use change of basis approach (on edges only)
152428509bceSStefano Zampini .    -pc_bddc_use_change_on_faces <0> - use change of basis approach on faces if change of basis has been requested
152528509bceSStefano Zampini .    -pc_bddc_switch_static <0> - switches from M_2 to M_3 operator (see reference article [1])
152628509bceSStefano Zampini .    -pc_bddc_levels <0> - maximum number of levels for multilevel
152728509bceSStefano Zampini .    -pc_bddc_coarsening_ratio - H/h ratio at the coarser level
152828509bceSStefano Zampini -    -pc_bddc_check_level <0> - set verbosity level of debugging output
152928509bceSStefano Zampini 
153028509bceSStefano Zampini    Options for Dirichlet, Neumann or coarse solver can be set with
153128509bceSStefano Zampini .vb
153228509bceSStefano Zampini       -pc_bddc_dirichlet_
153328509bceSStefano Zampini       -pc_bddc_neumann_
153428509bceSStefano Zampini       -pc_bddc_coarse_
153528509bceSStefano Zampini .ve
153628509bceSStefano Zampini    e.g -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg
153728509bceSStefano Zampini 
153828509bceSStefano Zampini    When using a multilevel approach, solvers' options at the N-th level can be specified as
153928509bceSStefano Zampini .vb
154028509bceSStefano Zampini       -pc_bddc_dirichlet_N_
154128509bceSStefano Zampini       -pc_bddc_neumann_N_
154228509bceSStefano Zampini       -pc_bddc_coarse_N_
154328509bceSStefano Zampini .ve
154428509bceSStefano Zampini    Note that level number ranges from the finest 0 to the coarsest N
1545da1bb401SStefano Zampini 
1546da1bb401SStefano Zampini    Level: intermediate
1547da1bb401SStefano Zampini 
1548b6fdb6dfSStefano Zampini    Developer notes:
154928509bceSStefano Zampini      Currently does not work with KSPBCGS and other KSPs requiring the specialization of PCApplyTranspose
1550da1bb401SStefano Zampini 
155128509bceSStefano Zampini      New deluxe scaling operator will be available soon.
1552da1bb401SStefano Zampini 
1553da1bb401SStefano Zampini    Contributed by Stefano Zampini
1554da1bb401SStefano Zampini 
1555da1bb401SStefano Zampini .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,  MATIS
1556da1bb401SStefano Zampini M*/
1557b2573a8aSBarry Smith 
1558da1bb401SStefano Zampini #undef __FUNCT__
1559da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC"
15608cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc)
1561da1bb401SStefano Zampini {
1562da1bb401SStefano Zampini   PetscErrorCode      ierr;
1563da1bb401SStefano Zampini   PC_BDDC             *pcbddc;
1564da1bb401SStefano Zampini 
1565da1bb401SStefano Zampini   PetscFunctionBegin;
1566da1bb401SStefano Zampini   /* Creates the private data structure for this preconditioner and attach it to the PC object. */
1567da1bb401SStefano Zampini   ierr      = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr);
1568da1bb401SStefano Zampini   pc->data  = (void*)pcbddc;
1569da1bb401SStefano Zampini 
1570da1bb401SStefano Zampini   /* create PCIS data structure */
1571da1bb401SStefano Zampini   ierr = PCISCreate(pc);CHKERRQ(ierr);
1572da1bb401SStefano Zampini 
157347d04d0dSStefano Zampini   /* BDDC customization */
157447d04d0dSStefano Zampini   pcbddc->use_vertices        = PETSC_TRUE;
157547d04d0dSStefano Zampini   pcbddc->use_edges           = PETSC_TRUE;
157647d04d0dSStefano Zampini   pcbddc->use_faces           = PETSC_FALSE;
157747d04d0dSStefano Zampini   pcbddc->use_change_of_basis = PETSC_FALSE;
157847d04d0dSStefano Zampini   pcbddc->use_change_on_faces = PETSC_FALSE;
157947d04d0dSStefano Zampini   pcbddc->switch_static       = PETSC_FALSE;
158047d04d0dSStefano Zampini   pcbddc->use_nnsp_true       = PETSC_FALSE; /* not yet exposed */
158147d04d0dSStefano Zampini   pcbddc->dbg_flag            = 0;
158247d04d0dSStefano Zampini 
1583674ae819SStefano Zampini   pcbddc->user_primal_vertices       = 0;
15840bdf917eSStefano Zampini   pcbddc->NullSpace                  = 0;
15853972b0daSStefano Zampini   pcbddc->temp_solution              = 0;
1586534831adSStefano Zampini   pcbddc->original_rhs               = 0;
1587534831adSStefano Zampini   pcbddc->local_mat                  = 0;
1588534831adSStefano Zampini   pcbddc->ChangeOfBasisMatrix        = 0;
1589da1bb401SStefano Zampini   pcbddc->coarse_vec                 = 0;
1590da1bb401SStefano Zampini   pcbddc->coarse_rhs                 = 0;
1591da1bb401SStefano Zampini   pcbddc->coarse_ksp                 = 0;
1592da1bb401SStefano Zampini   pcbddc->coarse_phi_B               = 0;
1593da1bb401SStefano Zampini   pcbddc->coarse_phi_D               = 0;
159415aaf578SStefano Zampini   pcbddc->coarse_psi_B               = 0;
159515aaf578SStefano Zampini   pcbddc->coarse_psi_D               = 0;
1596da1bb401SStefano Zampini   pcbddc->vec1_P                     = 0;
1597da1bb401SStefano Zampini   pcbddc->vec1_R                     = 0;
1598da1bb401SStefano Zampini   pcbddc->vec2_R                     = 0;
1599da1bb401SStefano Zampini   pcbddc->local_auxmat1              = 0;
1600da1bb401SStefano Zampini   pcbddc->local_auxmat2              = 0;
1601da1bb401SStefano Zampini   pcbddc->R_to_B                     = 0;
1602da1bb401SStefano Zampini   pcbddc->R_to_D                     = 0;
1603da1bb401SStefano Zampini   pcbddc->ksp_D                      = 0;
1604da1bb401SStefano Zampini   pcbddc->ksp_R                      = 0;
1605da1bb401SStefano Zampini   pcbddc->NeumannBoundaries          = 0;
1606785d1243SStefano Zampini   pcbddc->NeumannBoundariesLocal     = 0;
1607785d1243SStefano Zampini   pcbddc->DirichletBoundaries        = 0;
1608785d1243SStefano Zampini   pcbddc->DirichletBoundariesLocal   = 0;
160960d44989SStefano Zampini   pcbddc->user_provided_isfordofs    = PETSC_FALSE;
161060d44989SStefano Zampini   pcbddc->n_ISForDofs                = 0;
1611*63602bcaSStefano Zampini   pcbddc->n_ISForDofsLocal           = 0;
1612da1bb401SStefano Zampini   pcbddc->ISForDofs                  = 0;
1613*63602bcaSStefano Zampini   pcbddc->ISForDofsLocal             = 0;
1614da1bb401SStefano Zampini   pcbddc->ConstraintMatrix           = 0;
161585c4d303SStefano Zampini   pcbddc->use_exact_dirichlet_trick  = PETSC_TRUE;
161647d04d0dSStefano Zampini   pcbddc->coarse_loc_to_glob         = 0;
161747d04d0dSStefano Zampini   pcbddc->coarsening_ratio           = 8;
16184fad6a16SStefano Zampini   pcbddc->current_level              = 0;
16192b510759SStefano Zampini   pcbddc->max_levels                 = 0;
1620da1bb401SStefano Zampini 
1621674ae819SStefano Zampini   /* create local graph structure */
1622674ae819SStefano Zampini   ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr);
1623674ae819SStefano Zampini 
1624674ae819SStefano Zampini   /* scaling */
1625674ae819SStefano Zampini   pcbddc->use_deluxe_scaling         = PETSC_FALSE;
1626674ae819SStefano Zampini   pcbddc->work_scaling               = 0;
1627da1bb401SStefano Zampini 
1628da1bb401SStefano Zampini   /* function pointers */
1629da1bb401SStefano Zampini   pc->ops->apply               = PCApply_BDDC;
1630da1bb401SStefano Zampini   pc->ops->applytranspose      = 0;
1631da1bb401SStefano Zampini   pc->ops->setup               = PCSetUp_BDDC;
1632da1bb401SStefano Zampini   pc->ops->destroy             = PCDestroy_BDDC;
1633da1bb401SStefano Zampini   pc->ops->setfromoptions      = PCSetFromOptions_BDDC;
1634da1bb401SStefano Zampini   pc->ops->view                = 0;
1635da1bb401SStefano Zampini   pc->ops->applyrichardson     = 0;
1636da1bb401SStefano Zampini   pc->ops->applysymmetricleft  = 0;
1637da1bb401SStefano Zampini   pc->ops->applysymmetricright = 0;
1638534831adSStefano Zampini   pc->ops->presolve            = PCPreSolve_BDDC;
1639534831adSStefano Zampini   pc->ops->postsolve           = PCPostSolve_BDDC;
1640da1bb401SStefano Zampini 
1641da1bb401SStefano Zampini   /* composing function */
1642674ae819SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr);
1643bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr);
16442b510759SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr);
1645b8ffe317SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr);
16462b510759SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr);
1647bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",PCBDDCSetNullSpace_BDDC);CHKERRQ(ierr);
1648785d1243SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr);
164982ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr);
1650785d1243SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr);
165182ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr);
1652785d1243SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr);
165382ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr);
1654785d1243SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr);
165582ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr);
1656bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr);
1657*63602bcaSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",PCBDDCSetDofsSplittingLocal_BDDC);CHKERRQ(ierr);
1658bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr);
1659bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr);
1660bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr);
1661bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr);
1662da1bb401SStefano Zampini   PetscFunctionReturn(0);
1663da1bb401SStefano Zampini }
16643425bc38SStefano Zampini 
1665