xref: /petsc/src/ksp/pc/impls/bddc/bddc.c (revision 93bd9ae7ebd6e32f9ba30cca0adcbe3c21787c25)
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    - Change SetNeumannBoundaries to SetNeumannBoundariesLocal and provide new SetNeumannBoundaries (same Dirichlet)
18eb97c9d2SStefano Zampini    - Negative indices in dirichlet and Neumann is should be skipped (now they cause out-of-bounds access)
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__
3033b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC"
3043b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries)
3053b03a366Sstefano_zampini {
3063b03a366Sstefano_zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
3073b03a366Sstefano_zampini   PetscErrorCode ierr;
3083b03a366Sstefano_zampini 
3093b03a366Sstefano_zampini   PetscFunctionBegin;
3103b03a366Sstefano_zampini   ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr);
31136e030ebSStefano Zampini   ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr);
31236e030ebSStefano Zampini   pcbddc->DirichletBoundaries=DirichletBoundaries;
3133b03a366Sstefano_zampini   PetscFunctionReturn(0);
3143b03a366Sstefano_zampini }
3151e6b0712SBarry Smith 
3163b03a366Sstefano_zampini #undef __FUNCT__
3173b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries"
3183b03a366Sstefano_zampini /*@
31928509bceSStefano Zampini  PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem.
3203b03a366Sstefano_zampini 
3213b03a366Sstefano_zampini    Not collective
3223b03a366Sstefano_zampini 
3233b03a366Sstefano_zampini    Input Parameters:
3243b03a366Sstefano_zampini +  pc - the preconditioning context
32528509bceSStefano Zampini -  DirichletBoundaries - sequential IS defining the subdomain part of Dirichlet boundaries (in local ordering)
3263b03a366Sstefano_zampini 
3273b03a366Sstefano_zampini    Level: intermediate
3283b03a366Sstefano_zampini 
3293b03a366Sstefano_zampini    Notes:
3303b03a366Sstefano_zampini 
3313b03a366Sstefano_zampini .seealso: PCBDDC
3323b03a366Sstefano_zampini @*/
3333b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries)
3343b03a366Sstefano_zampini {
3353b03a366Sstefano_zampini   PetscErrorCode ierr;
3363b03a366Sstefano_zampini 
3373b03a366Sstefano_zampini   PetscFunctionBegin;
3383b03a366Sstefano_zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
339674ae819SStefano Zampini   PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2);
3403b03a366Sstefano_zampini   ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr);
3413b03a366Sstefano_zampini   PetscFunctionReturn(0);
3423b03a366Sstefano_zampini }
3433b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */
3441e6b0712SBarry Smith 
3453b03a366Sstefano_zampini #undef __FUNCT__
3460c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC"
34753cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries)
3480c7d97c5SJed Brown {
3490c7d97c5SJed Brown   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
35053cdbc3dSStefano Zampini   PetscErrorCode ierr;
3510c7d97c5SJed Brown 
3520c7d97c5SJed Brown   PetscFunctionBegin;
35353cdbc3dSStefano Zampini   ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr);
35436e030ebSStefano Zampini   ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr);
35536e030ebSStefano Zampini   pcbddc->NeumannBoundaries=NeumannBoundaries;
3560c7d97c5SJed Brown   PetscFunctionReturn(0);
3570c7d97c5SJed Brown }
3581e6b0712SBarry Smith 
3590c7d97c5SJed Brown #undef __FUNCT__
3600c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries"
36157527edcSJed Brown /*@
36228509bceSStefano Zampini  PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem.
36357527edcSJed Brown 
3649c0446d6SStefano Zampini    Not collective
36557527edcSJed Brown 
36657527edcSJed Brown    Input Parameters:
36757527edcSJed Brown +  pc - the preconditioning context
36828509bceSStefano Zampini -  NeumannBoundaries - sequential IS defining the subdomain part of Neumann boundaries (in local ordering)
36957527edcSJed Brown 
37057527edcSJed Brown    Level: intermediate
37157527edcSJed Brown 
37257527edcSJed Brown    Notes:
37357527edcSJed Brown 
37457527edcSJed Brown .seealso: PCBDDC
37557527edcSJed Brown @*/
37653cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries)
3770c7d97c5SJed Brown {
3780c7d97c5SJed Brown   PetscErrorCode ierr;
3790c7d97c5SJed Brown 
3800c7d97c5SJed Brown   PetscFunctionBegin;
3810c7d97c5SJed Brown   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
382674ae819SStefano Zampini   PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2);
38353cdbc3dSStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr);
38453cdbc3dSStefano Zampini   PetscFunctionReturn(0);
38553cdbc3dSStefano Zampini }
38653cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */
3871e6b0712SBarry Smith 
38853cdbc3dSStefano Zampini #undef __FUNCT__
389da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC"
390da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries)
391da1bb401SStefano Zampini {
392da1bb401SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
393da1bb401SStefano Zampini 
394da1bb401SStefano Zampini   PetscFunctionBegin;
395da1bb401SStefano Zampini   *DirichletBoundaries = pcbddc->DirichletBoundaries;
396da1bb401SStefano Zampini   PetscFunctionReturn(0);
397da1bb401SStefano Zampini }
3981e6b0712SBarry Smith 
399da1bb401SStefano Zampini #undef __FUNCT__
400da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries"
401da1bb401SStefano Zampini /*@
40228509bceSStefano Zampini  PCBDDCGetDirichletBoundaries - Get IS for local Dirichlet boundaries
403da1bb401SStefano Zampini 
404da1bb401SStefano Zampini    Not collective
405da1bb401SStefano Zampini 
406da1bb401SStefano Zampini    Input Parameters:
40728509bceSStefano Zampini .  pc - the preconditioning context
408da1bb401SStefano Zampini 
409da1bb401SStefano Zampini    Output Parameters:
41028509bceSStefano Zampini .  DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries
411da1bb401SStefano Zampini 
412da1bb401SStefano Zampini    Level: intermediate
413da1bb401SStefano Zampini 
414da1bb401SStefano Zampini    Notes:
415da1bb401SStefano Zampini 
416da1bb401SStefano Zampini .seealso: PCBDDC
417da1bb401SStefano Zampini @*/
418da1bb401SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries)
419da1bb401SStefano Zampini {
420da1bb401SStefano Zampini   PetscErrorCode ierr;
421da1bb401SStefano Zampini 
422da1bb401SStefano Zampini   PetscFunctionBegin;
423da1bb401SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
424da1bb401SStefano Zampini   ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr);
425da1bb401SStefano Zampini   PetscFunctionReturn(0);
426da1bb401SStefano Zampini }
427da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */
4281e6b0712SBarry Smith 
429da1bb401SStefano Zampini #undef __FUNCT__
43053cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC"
43153cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries)
43253cdbc3dSStefano Zampini {
43353cdbc3dSStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
43453cdbc3dSStefano Zampini 
43553cdbc3dSStefano Zampini   PetscFunctionBegin;
43653cdbc3dSStefano Zampini   *NeumannBoundaries = pcbddc->NeumannBoundaries;
43753cdbc3dSStefano Zampini   PetscFunctionReturn(0);
43853cdbc3dSStefano Zampini }
4391e6b0712SBarry Smith 
44053cdbc3dSStefano Zampini #undef __FUNCT__
44153cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries"
44253cdbc3dSStefano Zampini /*@
44328509bceSStefano Zampini  PCBDDCGetNeumannBoundaries - Get IS for local Neumann boundaries
44453cdbc3dSStefano Zampini 
4459c0446d6SStefano Zampini    Not collective
44653cdbc3dSStefano Zampini 
44753cdbc3dSStefano Zampini    Input Parameters:
44828509bceSStefano Zampini .  pc - the preconditioning context
44953cdbc3dSStefano Zampini 
45053cdbc3dSStefano Zampini    Output Parameters:
45128509bceSStefano Zampini .  NeumannBoundaries - index set defining the subdomain part of Neumann boundaries
45253cdbc3dSStefano Zampini 
45353cdbc3dSStefano Zampini    Level: intermediate
45453cdbc3dSStefano Zampini 
45553cdbc3dSStefano Zampini    Notes:
45653cdbc3dSStefano Zampini 
45753cdbc3dSStefano Zampini .seealso: PCBDDC
45853cdbc3dSStefano Zampini @*/
45953cdbc3dSStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries)
46053cdbc3dSStefano Zampini {
46153cdbc3dSStefano Zampini   PetscErrorCode ierr;
46253cdbc3dSStefano Zampini 
46353cdbc3dSStefano Zampini   PetscFunctionBegin;
46453cdbc3dSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
46553cdbc3dSStefano Zampini   ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr);
4660c7d97c5SJed Brown   PetscFunctionReturn(0);
4670c7d97c5SJed Brown }
46836e030ebSStefano Zampini /* -------------------------------------------------------------------------- */
4691e6b0712SBarry Smith 
47036e030ebSStefano Zampini #undef __FUNCT__
471da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC"
4721a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode)
47336e030ebSStefano Zampini {
47436e030ebSStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
475da1bb401SStefano Zampini   PCBDDCGraph    mat_graph = pcbddc->mat_graph;
476da1bb401SStefano Zampini   PetscErrorCode ierr;
47736e030ebSStefano Zampini 
47836e030ebSStefano Zampini   PetscFunctionBegin;
479674ae819SStefano Zampini   /* free old CSR */
480674ae819SStefano Zampini   ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr);
481fb223d50SStefano Zampini   /* TODO: PCBDDCGraphSetAdjacency */
482674ae819SStefano Zampini   /* get CSR into graph structure */
483da1bb401SStefano Zampini   if (copymode == PETSC_COPY_VALUES) {
484674ae819SStefano Zampini     ierr = PetscMalloc((nvtxs+1)*sizeof(PetscInt),&mat_graph->xadj);CHKERRQ(ierr);
485674ae819SStefano Zampini     ierr = PetscMalloc(xadj[nvtxs]*sizeof(PetscInt),&mat_graph->adjncy);CHKERRQ(ierr);
486674ae819SStefano Zampini     ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr);
487674ae819SStefano Zampini     ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr);
488da1bb401SStefano Zampini   } else if (copymode == PETSC_OWN_POINTER) {
4891a83f524SJed Brown     mat_graph->xadj = (PetscInt*)xadj;
4901a83f524SJed Brown     mat_graph->adjncy = (PetscInt*)adjncy;
491674ae819SStefano Zampini   }
492575ad6abSStefano Zampini   mat_graph->nvtxs_csr = nvtxs;
49336e030ebSStefano Zampini   PetscFunctionReturn(0);
49436e030ebSStefano Zampini }
4951e6b0712SBarry Smith 
49636e030ebSStefano Zampini #undef __FUNCT__
497da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph"
49836e030ebSStefano Zampini /*@
49928509bceSStefano Zampini  PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local Neumann matrix
50036e030ebSStefano Zampini 
50136e030ebSStefano Zampini    Not collective
50236e030ebSStefano Zampini 
50336e030ebSStefano Zampini    Input Parameters:
50436e030ebSStefano Zampini +  pc - the preconditioning context
50528509bceSStefano Zampini .  nvtxs - number of local vertices of the graph (i.e., the local size of your problem)
50628509bceSStefano Zampini .  xadj, adjncy - the CSR graph
50728509bceSStefano Zampini -  copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER.
50836e030ebSStefano Zampini 
50936e030ebSStefano Zampini    Level: intermediate
51036e030ebSStefano Zampini 
51136e030ebSStefano Zampini    Notes:
51236e030ebSStefano Zampini 
51328509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode
51436e030ebSStefano Zampini @*/
5151a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode)
51636e030ebSStefano Zampini {
517575ad6abSStefano Zampini   void (*f)(void) = 0;
51836e030ebSStefano Zampini   PetscErrorCode ierr;
51936e030ebSStefano Zampini 
52036e030ebSStefano Zampini   PetscFunctionBegin;
52136e030ebSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
522674ae819SStefano Zampini   PetscValidIntPointer(xadj,3);
523674ae819SStefano Zampini   PetscValidIntPointer(xadj,4);
524674ae819SStefano Zampini   if (copymode != PETSC_COPY_VALUES && copymode != PETSC_OWN_POINTER) {
525674ae819SStefano Zampini     SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d in %s\n",copymode,__FUNCT__);
526da1bb401SStefano Zampini   }
52736e030ebSStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr);
528575ad6abSStefano Zampini   /* free arrays if PCBDDC is not the PC type */
529575ad6abSStefano Zampini   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr);
530575ad6abSStefano Zampini   if (!f && copymode == PETSC_OWN_POINTER) {
531575ad6abSStefano Zampini     ierr = PetscFree(xadj);CHKERRQ(ierr);
532575ad6abSStefano Zampini     ierr = PetscFree(adjncy);CHKERRQ(ierr);
53336e030ebSStefano Zampini   }
53436e030ebSStefano Zampini   PetscFunctionReturn(0);
53536e030ebSStefano Zampini }
5369c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */
5371e6b0712SBarry Smith 
5389c0446d6SStefano Zampini #undef __FUNCT__
5399c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC"
5409c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[])
5419c0446d6SStefano Zampini {
5429c0446d6SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
5439c0446d6SStefano Zampini   PetscInt i;
5449c0446d6SStefano Zampini   PetscErrorCode ierr;
5459c0446d6SStefano Zampini 
5469c0446d6SStefano Zampini   PetscFunctionBegin;
547da1bb401SStefano Zampini   /* Destroy ISes if they were already set */
5489c0446d6SStefano Zampini   for (i=0;i<pcbddc->n_ISForDofs;i++) {
5499c0446d6SStefano Zampini     ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr);
5509c0446d6SStefano Zampini   }
551d11ae9bbSstefano_zampini   ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr);
552da1bb401SStefano Zampini   /* allocate space then set */
5539c0446d6SStefano Zampini   ierr = PetscMalloc(n_is*sizeof(IS),&pcbddc->ISForDofs);CHKERRQ(ierr);
5549c0446d6SStefano Zampini   for (i=0;i<n_is;i++) {
555da1bb401SStefano Zampini     ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr);
556da1bb401SStefano Zampini     pcbddc->ISForDofs[i]=ISForDofs[i];
5579c0446d6SStefano Zampini   }
5589c0446d6SStefano Zampini   pcbddc->n_ISForDofs=n_is;
55960d44989SStefano Zampini   pcbddc->user_provided_isfordofs = PETSC_TRUE;
5609c0446d6SStefano Zampini   PetscFunctionReturn(0);
5619c0446d6SStefano Zampini }
5621e6b0712SBarry Smith 
5639c0446d6SStefano Zampini #undef __FUNCT__
5649c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting"
5659c0446d6SStefano Zampini /*@
56628509bceSStefano Zampini  PCBDDCSetDofsSplitting - Set index sets defining fields of the local Neumann matrix
5679c0446d6SStefano Zampini 
5689c0446d6SStefano Zampini    Not collective
5699c0446d6SStefano Zampini 
5709c0446d6SStefano Zampini    Input Parameters:
5719c0446d6SStefano Zampini +  pc - the preconditioning context
57228509bceSStefano Zampini -  n_is - number of index sets defining the fields
57328509bceSStefano Zampini .  ISForDofs - array of IS describing the fields
5749c0446d6SStefano Zampini 
5759c0446d6SStefano Zampini    Level: intermediate
5769c0446d6SStefano Zampini 
5779c0446d6SStefano Zampini    Notes:
5789c0446d6SStefano Zampini 
5799c0446d6SStefano Zampini .seealso: PCBDDC
5809c0446d6SStefano Zampini @*/
5819c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[])
5829c0446d6SStefano Zampini {
5832b510759SStefano Zampini   PetscInt       i;
5849c0446d6SStefano Zampini   PetscErrorCode ierr;
5859c0446d6SStefano Zampini 
5869c0446d6SStefano Zampini   PetscFunctionBegin;
5879c0446d6SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
5882b510759SStefano Zampini   for (i=0;i<n_is;i++) {
5892b510759SStefano Zampini     PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,2);
5902b510759SStefano Zampini   }
5919c0446d6SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr);
5929c0446d6SStefano Zampini   PetscFunctionReturn(0);
5939c0446d6SStefano Zampini }
594da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */
595534831adSStefano Zampini #undef __FUNCT__
596534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC"
597534831adSStefano Zampini /* -------------------------------------------------------------------------- */
598534831adSStefano Zampini /*
599534831adSStefano Zampini    PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial
600534831adSStefano Zampini                      guess if a transformation of basis approach has been selected.
6019c0446d6SStefano Zampini 
602534831adSStefano Zampini    Input Parameter:
603534831adSStefano Zampini +  pc - the preconditioner contex
604534831adSStefano Zampini 
605534831adSStefano Zampini    Application Interface Routine: PCPreSolve()
606534831adSStefano Zampini 
607534831adSStefano Zampini    Notes:
608534831adSStefano Zampini    The interface routine PCPreSolve() is not usually called directly by
609534831adSStefano Zampini    the user, but instead is called by KSPSolve().
610534831adSStefano Zampini */
611534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x)
612534831adSStefano Zampini {
613534831adSStefano Zampini   PetscErrorCode ierr;
614534831adSStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
615534831adSStefano Zampini   PC_IS          *pcis = (PC_IS*)(pc->data);
616534831adSStefano Zampini   Mat_IS         *matis = (Mat_IS*)pc->pmat->data;
617534831adSStefano Zampini   Mat            temp_mat;
6183972b0daSStefano Zampini   IS             dirIS;
6193972b0daSStefano Zampini   PetscInt       dirsize,i,*is_indices;
6203972b0daSStefano Zampini   PetscScalar    *array_x,*array_diagonal;
6213972b0daSStefano Zampini   Vec            used_vec;
62292e3dcfbSStefano Zampini   PetscBool      guess_nonzero,flg,bddc_has_dirichlet_boundaries;
623534831adSStefano Zampini 
624534831adSStefano Zampini   PetscFunctionBegin;
62585c4d303SStefano Zampini   /* if we are working with cg, one dirichlet solve can be avoided during Krylov iterations */
62685c4d303SStefano Zampini   if (ksp) {
62785c4d303SStefano Zampini     PetscBool iscg;
62885c4d303SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr);
62985c4d303SStefano Zampini     if (!iscg) {
63085c4d303SStefano Zampini       ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr);
63185c4d303SStefano Zampini     }
63285c4d303SStefano Zampini   }
63385c4d303SStefano Zampini   /* Creates parallel work vectors used in presolve */
63462a6ff1dSStefano Zampini   if (!pcbddc->original_rhs) {
63562a6ff1dSStefano Zampini     ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr);
63662a6ff1dSStefano Zampini   }
63762a6ff1dSStefano Zampini   if (!pcbddc->temp_solution) {
63862a6ff1dSStefano Zampini     ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr);
63962a6ff1dSStefano Zampini   }
6403972b0daSStefano Zampini   if (x) {
6413972b0daSStefano Zampini     ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);
6423972b0daSStefano Zampini     used_vec = x;
6433972b0daSStefano Zampini   } else {
6443972b0daSStefano Zampini     ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr);
6453972b0daSStefano Zampini     used_vec = pcbddc->temp_solution;
6463972b0daSStefano Zampini     ierr = VecSet(used_vec,0.0);CHKERRQ(ierr);
6473972b0daSStefano Zampini   }
6483972b0daSStefano Zampini   /* hack into ksp data structure PCPreSolve comes earlier in src/ksp/ksp/interface/itfunc.c */
6493972b0daSStefano Zampini   if (ksp) {
6503972b0daSStefano Zampini     ierr = KSPGetInitialGuessNonzero(ksp,&guess_nonzero);CHKERRQ(ierr);
6513972b0daSStefano Zampini     if (!guess_nonzero) {
6523972b0daSStefano Zampini       ierr = VecSet(used_vec,0.0);CHKERRQ(ierr);
6533972b0daSStefano Zampini     }
6543972b0daSStefano Zampini   }
6553308cffdSStefano Zampini 
65692e3dcfbSStefano Zampini   /* TODO: remove when Dirichlet boundaries will be shared */
65792e3dcfbSStefano Zampini   ierr = PCBDDCGetDirichletBoundaries(pc,&dirIS);CHKERRQ(ierr);
65892e3dcfbSStefano Zampini   flg = PETSC_FALSE;
65992e3dcfbSStefano Zampini   if (dirIS) flg = PETSC_TRUE;
66092e3dcfbSStefano Zampini   ierr = MPI_Allreduce(&flg,&bddc_has_dirichlet_boundaries,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr);
66192e3dcfbSStefano Zampini 
6623972b0daSStefano Zampini   /* store the original rhs */
6633972b0daSStefano Zampini   ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr);
6643972b0daSStefano Zampini 
6653972b0daSStefano Zampini   /* Take into account zeroed rows -> change rhs and store solution removed */
66692e3dcfbSStefano Zampini   if (rhs && bddc_has_dirichlet_boundaries) {
6673972b0daSStefano Zampini     ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr);
6683972b0daSStefano Zampini     ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr);
6693972b0daSStefano Zampini     ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
6703972b0daSStefano Zampini     ierr = VecScatterEnd(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
6713972b0daSStefano Zampini     ierr = VecScatterBegin(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
6723972b0daSStefano Zampini     ierr = VecScatterEnd(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
6733972b0daSStefano Zampini     if (dirIS) {
6743972b0daSStefano Zampini       ierr = ISGetSize(dirIS,&dirsize);CHKERRQ(ierr);
6753972b0daSStefano Zampini       ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr);
6763972b0daSStefano Zampini       ierr = VecGetArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr);
6773972b0daSStefano Zampini       ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr);
6782fa5cd67SKarl Rupp       for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]];
6793972b0daSStefano Zampini       ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr);
6803972b0daSStefano Zampini       ierr = VecRestoreArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr);
6813972b0daSStefano Zampini       ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr);
6823972b0daSStefano Zampini     }
6833972b0daSStefano Zampini     ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
6843972b0daSStefano Zampini     ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
685b76ba322SStefano Zampini 
6863972b0daSStefano Zampini     /* remove the computed solution from the rhs */
6873972b0daSStefano Zampini     ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr);
6883972b0daSStefano Zampini     ierr = MatMultAdd(pc->pmat,used_vec,rhs,rhs);CHKERRQ(ierr);
6893972b0daSStefano Zampini     ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr);
6903308cffdSStefano Zampini   }
691b76ba322SStefano Zampini 
692b76ba322SStefano Zampini   /* store partially computed solution and set initial guess */
6933972b0daSStefano Zampini   if (x) {
6943972b0daSStefano Zampini     ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr);
6953972b0daSStefano Zampini     ierr = VecSet(used_vec,0.0);CHKERRQ(ierr);
69685c4d303SStefano Zampini     if (pcbddc->use_exact_dirichlet_trick) {
697b76ba322SStefano Zampini       ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
698b76ba322SStefano Zampini       ierr = VecScatterEnd  (pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
699b76ba322SStefano Zampini       ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr);
700b76ba322SStefano Zampini       ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
701b76ba322SStefano Zampini       ierr = VecScatterEnd  (pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
702b76ba322SStefano Zampini       if (ksp) {
703b76ba322SStefano Zampini         ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr);
704b76ba322SStefano Zampini       }
705b76ba322SStefano Zampini     }
7063972b0daSStefano Zampini   }
707b76ba322SStefano Zampini 
70892e3dcfbSStefano Zampini   /* prepare MatMult and rhs for solver */
709674ae819SStefano Zampini   if (pcbddc->use_change_of_basis) {
710b76ba322SStefano Zampini     /* swap pointers for local matrices */
711b76ba322SStefano Zampini     temp_mat = matis->A;
712b76ba322SStefano Zampini     matis->A = pcbddc->local_mat;
713b76ba322SStefano Zampini     pcbddc->local_mat = temp_mat;
71492e3dcfbSStefano Zampini     if (rhs) {
715b76ba322SStefano Zampini       /* Get local rhs and apply transformation of basis */
716b76ba322SStefano Zampini       ierr = VecScatterBegin(pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
717b76ba322SStefano Zampini       ierr = VecScatterEnd  (pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
718b76ba322SStefano Zampini       /* from original basis to modified basis */
719b76ba322SStefano Zampini       ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr);
720b76ba322SStefano Zampini       /* put back modified values into the global vec using INSERT_VALUES copy mode */
721b76ba322SStefano Zampini       ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
722b76ba322SStefano Zampini       ierr = VecScatterEnd  (pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
723674ae819SStefano Zampini     }
72492e3dcfbSStefano Zampini   }
72592e3dcfbSStefano Zampini 
72692e3dcfbSStefano Zampini   /* remove nullspace if present */
7270bdf917eSStefano Zampini   if (ksp && pcbddc->NullSpace) {
728d0195637SJed Brown     ierr = MatNullSpaceRemove(pcbddc->NullSpace,used_vec);CHKERRQ(ierr);
729d0195637SJed Brown     ierr = MatNullSpaceRemove(pcbddc->NullSpace,rhs);CHKERRQ(ierr);
730b76ba322SStefano Zampini   }
7310bdf917eSStefano Zampini   ierr = VecDestroy(&used_vec);CHKERRQ(ierr);
732534831adSStefano Zampini   PetscFunctionReturn(0);
733534831adSStefano Zampini }
734534831adSStefano Zampini /* -------------------------------------------------------------------------- */
735534831adSStefano Zampini #undef __FUNCT__
736534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC"
737534831adSStefano Zampini /* -------------------------------------------------------------------------- */
738534831adSStefano Zampini /*
739534831adSStefano Zampini    PCPostSolve_BDDC - Changes the computed solution if a transformation of basis
740534831adSStefano Zampini                      approach has been selected. Also, restores rhs to its original state.
741534831adSStefano Zampini 
742534831adSStefano Zampini    Input Parameter:
743534831adSStefano Zampini +  pc - the preconditioner contex
744534831adSStefano Zampini 
745534831adSStefano Zampini    Application Interface Routine: PCPostSolve()
746534831adSStefano Zampini 
747534831adSStefano Zampini    Notes:
748534831adSStefano Zampini    The interface routine PCPostSolve() is not usually called directly by
749534831adSStefano Zampini    the user, but instead is called by KSPSolve().
750534831adSStefano Zampini */
751534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x)
752534831adSStefano Zampini {
753534831adSStefano Zampini   PetscErrorCode ierr;
754534831adSStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
755534831adSStefano Zampini   PC_IS          *pcis   = (PC_IS*)(pc->data);
756534831adSStefano Zampini   Mat_IS         *matis = (Mat_IS*)pc->pmat->data;
757534831adSStefano Zampini   Mat            temp_mat;
758534831adSStefano Zampini 
759534831adSStefano Zampini   PetscFunctionBegin;
760674ae819SStefano Zampini   if (pcbddc->use_change_of_basis) {
761534831adSStefano Zampini     /* swap pointers for local matrices */
762534831adSStefano Zampini     temp_mat = matis->A;
763534831adSStefano Zampini     matis->A = pcbddc->local_mat;
764534831adSStefano Zampini     pcbddc->local_mat = temp_mat;
7653425bc38SStefano Zampini   }
7663308cffdSStefano Zampini   if (pcbddc->use_change_of_basis && x) {
767534831adSStefano Zampini     /* Get Local boundary and apply transformation of basis to solution vector */
768534831adSStefano Zampini     ierr = VecScatterBegin(pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
769534831adSStefano Zampini     ierr = VecScatterEnd  (pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
770534831adSStefano Zampini     /* from modified basis to original basis */
771534831adSStefano Zampini     ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr);
772534831adSStefano Zampini     /* put back modified values into the global vec using INSERT_VALUES copy mode */
773534831adSStefano Zampini     ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
774534831adSStefano Zampini     ierr = VecScatterEnd  (pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
775534831adSStefano Zampini   }
7763972b0daSStefano Zampini   /* add solution removed in presolve */
7773425bc38SStefano Zampini   if (x) {
7783425bc38SStefano Zampini     ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr);
7793425bc38SStefano Zampini   }
780fb223d50SStefano Zampini   /* restore rhs to its original state */
781fb223d50SStefano Zampini   if (rhs) {
782fb223d50SStefano Zampini     ierr = VecCopy(pcbddc->original_rhs,rhs);CHKERRQ(ierr);
783fb223d50SStefano Zampini   }
784534831adSStefano Zampini   PetscFunctionReturn(0);
785534831adSStefano Zampini }
786534831adSStefano Zampini /* -------------------------------------------------------------------------- */
78753cdbc3dSStefano Zampini #undef __FUNCT__
78853cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC"
7890c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
7900c7d97c5SJed Brown /*
7910c7d97c5SJed Brown    PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner
7920c7d97c5SJed Brown                   by setting data structures and options.
7930c7d97c5SJed Brown 
7940c7d97c5SJed Brown    Input Parameter:
79553cdbc3dSStefano Zampini +  pc - the preconditioner context
7960c7d97c5SJed Brown 
7970c7d97c5SJed Brown    Application Interface Routine: PCSetUp()
7980c7d97c5SJed Brown 
7990c7d97c5SJed Brown    Notes:
8000c7d97c5SJed Brown    The interface routine PCSetUp() is not usually called directly by
8010c7d97c5SJed Brown    the user, but instead is called by PCApply() if necessary.
8020c7d97c5SJed Brown */
80353cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc)
8040c7d97c5SJed Brown {
8050c7d97c5SJed Brown   PetscErrorCode ierr;
8060c7d97c5SJed Brown   PC_BDDC*       pcbddc = (PC_BDDC*)pc->data;
807674ae819SStefano Zampini   MatStructure   flag;
808674ae819SStefano Zampini   PetscBool      computeis,computetopography,computesolvers;
8090c7d97c5SJed Brown 
8100c7d97c5SJed Brown   PetscFunctionBegin;
811674ae819SStefano Zampini   /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other nonoverlapping preconditioners */
812fcd409f5SStefano Zampini   /* PCIS does not support MatStructures different from SAME_PRECONDITIONER */
8133b03a366Sstefano_zampini   /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup
814fcd409f5SStefano Zampini      Also, BDDC directly build the Dirichlet problem */
8153b03a366Sstefano_zampini   /* Get stdout for dbg */
816674ae819SStefano Zampini   if (pcbddc->dbg_flag && !pcbddc->dbg_viewer) {
817ce94432eSBarry Smith     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pc),&pcbddc->dbg_viewer);CHKERRQ(ierr);
818e269702eSStefano Zampini     ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr);
8192b510759SStefano Zampini     if (pcbddc->current_level) {
8202b510759SStefano Zampini       ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2);CHKERRQ(ierr);
8212b510759SStefano Zampini     }
822e269702eSStefano Zampini   }
823674ae819SStefano Zampini   /* first attempt to split work */
824674ae819SStefano Zampini   if (pc->setupcalled) {
825674ae819SStefano Zampini     computeis = PETSC_FALSE;
826674ae819SStefano Zampini     ierr = PCGetOperators(pc,NULL,NULL,&flag);CHKERRQ(ierr);
827674ae819SStefano Zampini     if (flag == SAME_PRECONDITIONER) {
828674ae819SStefano Zampini       computetopography = PETSC_FALSE;
829674ae819SStefano Zampini       computesolvers = PETSC_FALSE;
830674ae819SStefano Zampini     } else if (flag == SAME_NONZERO_PATTERN) {
831674ae819SStefano Zampini       computetopography = PETSC_FALSE;
832674ae819SStefano Zampini       computesolvers = PETSC_TRUE;
833674ae819SStefano Zampini     } else { /* DIFFERENT_NONZERO_PATTERN */
834674ae819SStefano Zampini       computetopography = PETSC_TRUE;
835674ae819SStefano Zampini       computesolvers = PETSC_TRUE;
836674ae819SStefano Zampini     }
837674ae819SStefano Zampini   } else {
838674ae819SStefano Zampini     computeis = PETSC_TRUE;
839674ae819SStefano Zampini     computetopography = PETSC_TRUE;
840674ae819SStefano Zampini     computesolvers = PETSC_TRUE;
841674ae819SStefano Zampini   }
842fcd409f5SStefano Zampini   /* Set up all the "iterative substructuring" common block without computing solvers */
843674ae819SStefano Zampini   if (computeis) {
844fcd409f5SStefano Zampini     /* HACK INTO PCIS */
845fcd409f5SStefano Zampini     PC_IS* pcis = (PC_IS*)pc->data;
846fcd409f5SStefano Zampini     pcis->computesolvers = PETSC_FALSE;
847674ae819SStefano Zampini     ierr = PCISSetUp(pc);CHKERRQ(ierr);
848674ae819SStefano Zampini   }
849674ae819SStefano Zampini   /* Analyze interface and set up local constraint and change of basis matrices */
850674ae819SStefano Zampini   if (computetopography) {
851674ae819SStefano Zampini     /* reset data */
852674ae819SStefano Zampini     ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr);
853674ae819SStefano Zampini     ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr);
854674ae819SStefano Zampini     ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr);
855674ae819SStefano Zampini   }
856674ae819SStefano Zampini   if (computesolvers) {
857674ae819SStefano Zampini     /* reset data */
858674ae819SStefano Zampini     ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr);
859674ae819SStefano Zampini     ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr);
86099cc7994SStefano Zampini     /* Create coarse and local stuffs */
86199cc7994SStefano Zampini     ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr);
862674ae819SStefano Zampini     ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr);
8630c7d97c5SJed Brown   }
8642b510759SStefano Zampini   if (pcbddc->dbg_flag && pcbddc->current_level) {
8652b510759SStefano Zampini     ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2);CHKERRQ(ierr);
8662b510759SStefano Zampini   }
8670c7d97c5SJed Brown   PetscFunctionReturn(0);
8680c7d97c5SJed Brown }
8690c7d97c5SJed Brown 
8700c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
8710c7d97c5SJed Brown /*
87250efa1b5SStefano Zampini    PCApply_BDDC - Applies the BDDC operator to a vector.
8730c7d97c5SJed Brown 
8740c7d97c5SJed Brown    Input Parameters:
8750c7d97c5SJed Brown .  pc - the preconditioner context
8760c7d97c5SJed Brown .  r - input vector (global)
8770c7d97c5SJed Brown 
8780c7d97c5SJed Brown    Output Parameter:
8790c7d97c5SJed Brown .  z - output vector (global)
8800c7d97c5SJed Brown 
8810c7d97c5SJed Brown    Application Interface Routine: PCApply()
8820c7d97c5SJed Brown  */
8830c7d97c5SJed Brown #undef __FUNCT__
8840c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC"
88553cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z)
8860c7d97c5SJed Brown {
8870c7d97c5SJed Brown   PC_IS             *pcis = (PC_IS*)(pc->data);
8880c7d97c5SJed Brown   PC_BDDC           *pcbddc = (PC_BDDC*)(pc->data);
8890c7d97c5SJed Brown   PetscErrorCode    ierr;
8903b03a366Sstefano_zampini   const PetscScalar one = 1.0;
8913b03a366Sstefano_zampini   const PetscScalar m_one = -1.0;
8922617d88aSStefano Zampini   const PetscScalar zero = 0.0;
8930c7d97c5SJed Brown 
8940c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN
8950c7d97c5SJed Brown    NN interface preconditioner changed to BDDC
8968eeda7d8SStefano Zampini    Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static = PETSC_TRUE) */
8970c7d97c5SJed Brown 
8980c7d97c5SJed Brown   PetscFunctionBegin;
89985c4d303SStefano Zampini   if (!pcbddc->use_exact_dirichlet_trick) {
9000c7d97c5SJed Brown     /* First Dirichlet solve */
9010c7d97c5SJed Brown     ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
9020c7d97c5SJed Brown     ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
90353cdbc3dSStefano Zampini     ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr);
9040c7d97c5SJed Brown     /*
9050c7d97c5SJed Brown       Assembling right hand side for BDDC operator
906674ae819SStefano Zampini       - pcis->vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE)
907674ae819SStefano Zampini       - pcis->vec1_B the interface part of the global vector z
9080c7d97c5SJed Brown     */
9090c7d97c5SJed Brown     ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr);
9100c7d97c5SJed Brown     ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr);
9118eeda7d8SStefano Zampini     if (pcbddc->switch_static) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); }
9120c7d97c5SJed Brown     ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr);
9130c7d97c5SJed Brown     ierr = VecCopy(r,z);CHKERRQ(ierr);
9140c7d97c5SJed Brown     ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
9150c7d97c5SJed Brown     ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
916674ae819SStefano Zampini     ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr);
917b76ba322SStefano Zampini   } else {
9180bdf917eSStefano Zampini     ierr = VecSet(pcis->vec1_D,zero);CHKERRQ(ierr);
919b76ba322SStefano Zampini     ierr = VecSet(pcis->vec2_D,zero);CHKERRQ(ierr);
920674ae819SStefano Zampini     ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr);
921b76ba322SStefano Zampini   }
922b76ba322SStefano Zampini 
9232617d88aSStefano Zampini   /* Apply interface preconditioner
9242617d88aSStefano Zampini      input/output vecs: pcis->vec1_B and pcis->vec1_D */
925dc359a40SStefano Zampini   ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr);
9262617d88aSStefano Zampini 
927674ae819SStefano Zampini   /* Apply transpose of partition of unity operator */
928674ae819SStefano Zampini   ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr);
9290c7d97c5SJed Brown 
9303b03a366Sstefano_zampini   /* Second Dirichlet solve and assembling of output */
9310c7d97c5SJed Brown   ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
9320c7d97c5SJed Brown   ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
9330c7d97c5SJed Brown   ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr);
9348eeda7d8SStefano Zampini   if (pcbddc->switch_static) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); }
93553cdbc3dSStefano Zampini   ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr);
9360c7d97c5SJed Brown   ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr);
9378eeda7d8SStefano Zampini   if (pcbddc->switch_static) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); }
9380c7d97c5SJed Brown   ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr);
9390c7d97c5SJed Brown   ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
9400c7d97c5SJed Brown   ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
9410c7d97c5SJed Brown   PetscFunctionReturn(0);
9420c7d97c5SJed Brown }
94350efa1b5SStefano Zampini 
94450efa1b5SStefano Zampini /* -------------------------------------------------------------------------- */
94550efa1b5SStefano Zampini /*
94650efa1b5SStefano Zampini    PCApplyTranspose_BDDC - Applies the transpose of the BDDC operator to a vector.
94750efa1b5SStefano Zampini 
94850efa1b5SStefano Zampini    Input Parameters:
94950efa1b5SStefano Zampini .  pc - the preconditioner context
95050efa1b5SStefano Zampini .  r - input vector (global)
95150efa1b5SStefano Zampini 
95250efa1b5SStefano Zampini    Output Parameter:
95350efa1b5SStefano Zampini .  z - output vector (global)
95450efa1b5SStefano Zampini 
95550efa1b5SStefano Zampini    Application Interface Routine: PCApplyTranspose()
95650efa1b5SStefano Zampini  */
95750efa1b5SStefano Zampini #undef __FUNCT__
95850efa1b5SStefano Zampini #define __FUNCT__ "PCApplyTranspose_BDDC"
95950efa1b5SStefano Zampini PetscErrorCode PCApplyTranspose_BDDC(PC pc,Vec r,Vec z)
96050efa1b5SStefano Zampini {
96150efa1b5SStefano Zampini   PC_IS             *pcis = (PC_IS*)(pc->data);
96250efa1b5SStefano Zampini   PC_BDDC           *pcbddc = (PC_BDDC*)(pc->data);
96350efa1b5SStefano Zampini   PetscErrorCode    ierr;
96450efa1b5SStefano Zampini   const PetscScalar one = 1.0;
96550efa1b5SStefano Zampini   const PetscScalar m_one = -1.0;
96650efa1b5SStefano Zampini   const PetscScalar zero = 0.0;
96750efa1b5SStefano Zampini 
96850efa1b5SStefano Zampini   PetscFunctionBegin;
96950efa1b5SStefano Zampini   if (!pcbddc->use_exact_dirichlet_trick) {
97050efa1b5SStefano Zampini     /* First Dirichlet solve */
97150efa1b5SStefano Zampini     ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
97250efa1b5SStefano Zampini     ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
97350efa1b5SStefano Zampini     ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr);
97450efa1b5SStefano Zampini     /*
97550efa1b5SStefano Zampini       Assembling right hand side for BDDC operator
97650efa1b5SStefano Zampini       - pcis->vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE)
97750efa1b5SStefano Zampini       - pcis->vec1_B the interface part of the global vector z
97850efa1b5SStefano Zampini     */
97950efa1b5SStefano Zampini     ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr);
98050efa1b5SStefano Zampini     ierr = MatMultTranspose(pcis->A_IB,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr);
98150efa1b5SStefano Zampini     if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); }
98250efa1b5SStefano Zampini     ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr);
98350efa1b5SStefano Zampini     ierr = VecCopy(r,z);CHKERRQ(ierr);
98450efa1b5SStefano Zampini     ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
98550efa1b5SStefano Zampini     ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
98650efa1b5SStefano Zampini     ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr);
98750efa1b5SStefano Zampini   } else {
98850efa1b5SStefano Zampini     ierr = VecSet(pcis->vec1_D,zero);CHKERRQ(ierr);
98950efa1b5SStefano Zampini     ierr = VecSet(pcis->vec2_D,zero);CHKERRQ(ierr);
99050efa1b5SStefano Zampini     ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr);
99150efa1b5SStefano Zampini   }
99250efa1b5SStefano Zampini 
99350efa1b5SStefano Zampini   /* Apply interface preconditioner
99450efa1b5SStefano Zampini      input/output vecs: pcis->vec1_B and pcis->vec1_D */
995dc359a40SStefano Zampini   ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_TRUE);CHKERRQ(ierr);
99650efa1b5SStefano Zampini 
99750efa1b5SStefano Zampini   /* Apply transpose of partition of unity operator */
99850efa1b5SStefano Zampini   ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr);
99950efa1b5SStefano Zampini 
100050efa1b5SStefano Zampini   /* Second Dirichlet solve and assembling of output */
100150efa1b5SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
100250efa1b5SStefano Zampini   ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
100350efa1b5SStefano Zampini   ierr = MatMultTranspose(pcis->A_BI,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr);
100450efa1b5SStefano Zampini   if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); }
100550efa1b5SStefano Zampini   ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr);
100650efa1b5SStefano Zampini   ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr);
100750efa1b5SStefano Zampini   if (pcbddc->switch_static) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); }
100850efa1b5SStefano Zampini   ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr);
100950efa1b5SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
101050efa1b5SStefano Zampini   ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
101150efa1b5SStefano Zampini   PetscFunctionReturn(0);
101250efa1b5SStefano Zampini }
1013da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */
1014674ae819SStefano Zampini 
1015da1bb401SStefano Zampini #undef __FUNCT__
1016da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC"
1017da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc)
1018da1bb401SStefano Zampini {
1019da1bb401SStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
1020da1bb401SStefano Zampini   PetscErrorCode ierr;
1021da1bb401SStefano Zampini 
1022da1bb401SStefano Zampini   PetscFunctionBegin;
1023da1bb401SStefano Zampini   /* free data created by PCIS */
1024da1bb401SStefano Zampini   ierr = PCISDestroy(pc);CHKERRQ(ierr);
1025674ae819SStefano Zampini   /* free BDDC custom data  */
1026674ae819SStefano Zampini   ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr);
1027674ae819SStefano Zampini   /* destroy objects related to topography */
1028674ae819SStefano Zampini   ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr);
1029674ae819SStefano Zampini   /* free allocated graph structure */
1030da1bb401SStefano Zampini   ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr);
1031674ae819SStefano Zampini   /* free data for scaling operator */
1032674ae819SStefano Zampini   ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr);
1033674ae819SStefano Zampini   /* free solvers stuff */
1034674ae819SStefano Zampini   ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr);
103533bc96a4SStefano Zampini   ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr);
103633bc96a4SStefano Zampini   ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr);
10379881197aSStefano Zampini   ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr);
1038ac78edfcSStefano Zampini   ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr);
103962a6ff1dSStefano Zampini   /* free global vectors needed in presolve */
104062a6ff1dSStefano Zampini   ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr);
104162a6ff1dSStefano Zampini   ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr);
10423425bc38SStefano Zampini   /* remove functions */
1043674ae819SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr);
1044bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr);
10452b510759SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr);
1046b8ffe317SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr);
10472b510759SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr);
1048bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",NULL);CHKERRQ(ierr);
1049bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr);
1050bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr);
1051bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr);
1052bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr);
1053bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr);
1054bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr);
1055bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr);
1056bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr);
1057bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr);
1058674ae819SStefano Zampini   /* Free the private data structure */
1059674ae819SStefano Zampini   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1060da1bb401SStefano Zampini   PetscFunctionReturn(0);
1061da1bb401SStefano Zampini }
10623425bc38SStefano Zampini /* -------------------------------------------------------------------------- */
10631e6b0712SBarry Smith 
10643425bc38SStefano Zampini #undef __FUNCT__
10653425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC"
10663425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs)
10673425bc38SStefano Zampini {
1068674ae819SStefano Zampini   FETIDPMat_ctx  mat_ctx;
10693425bc38SStefano Zampini   PC_IS*         pcis;
10703425bc38SStefano Zampini   PC_BDDC*       pcbddc;
10713425bc38SStefano Zampini   PetscErrorCode ierr;
10720c7d97c5SJed Brown 
10733425bc38SStefano Zampini   PetscFunctionBegin;
10743425bc38SStefano Zampini   ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr);
10753425bc38SStefano Zampini   pcis = (PC_IS*)mat_ctx->pc->data;
10763425bc38SStefano Zampini   pcbddc = (PC_BDDC*)mat_ctx->pc->data;
10773425bc38SStefano Zampini 
10783425bc38SStefano Zampini   /* change of basis for physical rhs if needed
10793425bc38SStefano Zampini      It also changes the rhs in case of dirichlet boundaries */
10803308cffdSStefano Zampini   ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,standard_rhs,NULL);CHKERRQ(ierr);
10813425bc38SStefano Zampini   /* store vectors for computation of fetidp final solution */
10823425bc38SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
10833425bc38SStefano Zampini   ierr = VecScatterEnd(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1084fb223d50SStefano Zampini   /* scale rhs since it should be unassembled */
1085fb223d50SStefano Zampini   /* TODO use counter scaling? (also below) */
10863425bc38SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
10873425bc38SStefano Zampini   ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1088674ae819SStefano Zampini   /* Apply partition of unity */
10893425bc38SStefano Zampini   ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr);
1090674ae819SStefano Zampini   /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */
10918eeda7d8SStefano Zampini   if (!pcbddc->switch_static) {
10923425bc38SStefano Zampini     /* compute partially subassembled Schur complement right-hand side */
10933425bc38SStefano Zampini     ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr);
10943425bc38SStefano Zampini     ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr);
10953425bc38SStefano Zampini     ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr);
10963425bc38SStefano Zampini     ierr = VecSet(standard_rhs,0.0);CHKERRQ(ierr);
10973425bc38SStefano Zampini     ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
10983425bc38SStefano Zampini     ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1099674ae819SStefano Zampini     /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */
11003425bc38SStefano Zampini     ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
11013425bc38SStefano Zampini     ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
11023425bc38SStefano Zampini     ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr);
11033425bc38SStefano Zampini   }
11043425bc38SStefano Zampini   /* BDDC rhs */
11053425bc38SStefano Zampini   ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr);
11068eeda7d8SStefano Zampini   if (pcbddc->switch_static) {
11073425bc38SStefano Zampini     ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr);
11083425bc38SStefano Zampini   }
11093425bc38SStefano Zampini   /* apply BDDC */
1110dc359a40SStefano Zampini   ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr);
11113425bc38SStefano Zampini   /* Application of B_delta and assembling of rhs for fetidp fluxes */
11123425bc38SStefano Zampini   ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr);
11133425bc38SStefano Zampini   ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr);
11143425bc38SStefano Zampini   ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
11153425bc38SStefano Zampini   ierr = VecScatterEnd  (mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
11163425bc38SStefano Zampini   /* restore original rhs */
11173425bc38SStefano Zampini   ierr = VecCopy(pcbddc->original_rhs,standard_rhs);CHKERRQ(ierr);
11183425bc38SStefano Zampini   PetscFunctionReturn(0);
11193425bc38SStefano Zampini }
11201e6b0712SBarry Smith 
11213425bc38SStefano Zampini #undef __FUNCT__
11223425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS"
11233425bc38SStefano Zampini /*@
112428509bceSStefano Zampini  PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETIDP linear system
11253425bc38SStefano Zampini 
11263425bc38SStefano Zampini    Collective
11273425bc38SStefano Zampini 
11283425bc38SStefano Zampini    Input Parameters:
112928509bceSStefano Zampini +  fetidp_mat   - the FETIDP matrix object obtained by calling PCBDDCCreateFETIDPOperators
113028509bceSStefano Zampini .  standard_rhs - the right-hand side for your linear system
11313425bc38SStefano Zampini 
11323425bc38SStefano Zampini    Output Parameters:
113328509bceSStefano Zampini -  fetidp_flux_rhs   - the right-hand side for the FETIDP linear system
11343425bc38SStefano Zampini 
11353425bc38SStefano Zampini    Level: developer
11363425bc38SStefano Zampini 
11373425bc38SStefano Zampini    Notes:
11383425bc38SStefano Zampini 
113928509bceSStefano Zampini .seealso: PCBDDC,PCBDDCCreateFETIDPOperators
11403425bc38SStefano Zampini @*/
11413425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs)
11423425bc38SStefano Zampini {
1143674ae819SStefano Zampini   FETIDPMat_ctx  mat_ctx;
11443425bc38SStefano Zampini   PetscErrorCode ierr;
11453425bc38SStefano Zampini 
11463425bc38SStefano Zampini   PetscFunctionBegin;
11473425bc38SStefano Zampini   ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr);
11483425bc38SStefano Zampini   ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr);
11493425bc38SStefano Zampini   PetscFunctionReturn(0);
11503425bc38SStefano Zampini }
11513425bc38SStefano Zampini /* -------------------------------------------------------------------------- */
11521e6b0712SBarry Smith 
11533425bc38SStefano Zampini #undef __FUNCT__
11543425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC"
11553425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol)
11563425bc38SStefano Zampini {
1157674ae819SStefano Zampini   FETIDPMat_ctx  mat_ctx;
11583425bc38SStefano Zampini   PC_IS*         pcis;
11593425bc38SStefano Zampini   PC_BDDC*       pcbddc;
11603425bc38SStefano Zampini   PetscErrorCode ierr;
11613425bc38SStefano Zampini 
11623425bc38SStefano Zampini   PetscFunctionBegin;
11633425bc38SStefano Zampini   ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr);
11643425bc38SStefano Zampini   pcis = (PC_IS*)mat_ctx->pc->data;
11653425bc38SStefano Zampini   pcbddc = (PC_BDDC*)mat_ctx->pc->data;
11663425bc38SStefano Zampini 
11673425bc38SStefano Zampini   /* apply B_delta^T */
11683425bc38SStefano Zampini   ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
11693425bc38SStefano Zampini   ierr = VecScatterEnd  (mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
11703425bc38SStefano Zampini   ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr);
11713425bc38SStefano Zampini   /* compute rhs for BDDC application */
11723425bc38SStefano Zampini   ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr);
11738eeda7d8SStefano Zampini   if (pcbddc->switch_static) {
11743425bc38SStefano Zampini     ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr);
11753425bc38SStefano Zampini   }
11763425bc38SStefano Zampini   /* apply BDDC */
1177dc359a40SStefano Zampini   ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr);
11783425bc38SStefano Zampini   /* put values into standard global vector */
11793425bc38SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
11803425bc38SStefano Zampini   ierr = VecScatterEnd  (pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
11818eeda7d8SStefano Zampini   if (!pcbddc->switch_static) {
11823425bc38SStefano Zampini     /* compute values into the interior if solved for the partially subassembled Schur complement */
11833425bc38SStefano Zampini     ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr);
11843425bc38SStefano Zampini     ierr = VecAXPY(mat_ctx->temp_solution_D,-1.0,pcis->vec1_D);CHKERRQ(ierr);
11853425bc38SStefano Zampini     ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr);
11863425bc38SStefano Zampini   }
11873425bc38SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
11883425bc38SStefano Zampini   ierr = VecScatterEnd  (pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
11893425bc38SStefano Zampini   /* final change of basis if needed
11903425bc38SStefano Zampini      Is also sums the dirichlet part removed during RHS assembling */
11913308cffdSStefano Zampini   ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr);
11923425bc38SStefano Zampini   PetscFunctionReturn(0);
11933425bc38SStefano Zampini }
11941e6b0712SBarry Smith 
11953425bc38SStefano Zampini #undef __FUNCT__
11963425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution"
11973425bc38SStefano Zampini /*@
119828509bceSStefano Zampini  PCBDDCMatFETIDPGetSolution - Compute the physical solution from the solution of the FETIDP linear system
11993425bc38SStefano Zampini 
12003425bc38SStefano Zampini    Collective
12013425bc38SStefano Zampini 
12023425bc38SStefano Zampini    Input Parameters:
120328509bceSStefano Zampini +  fetidp_mat        - the FETIDP matrix obtained by calling PCBDDCCreateFETIDPOperators
120428509bceSStefano Zampini .  fetidp_flux_sol - the solution of the FETIDP linear system
12053425bc38SStefano Zampini 
12063425bc38SStefano Zampini    Output Parameters:
120728509bceSStefano Zampini -  standard_sol      - the solution defined on the physical domain
12083425bc38SStefano Zampini 
12093425bc38SStefano Zampini    Level: developer
12103425bc38SStefano Zampini 
12113425bc38SStefano Zampini    Notes:
12123425bc38SStefano Zampini 
121328509bceSStefano Zampini .seealso: PCBDDC,PCBDDCCreateFETIDPOperators
12143425bc38SStefano Zampini @*/
12153425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol)
12163425bc38SStefano Zampini {
1217674ae819SStefano Zampini   FETIDPMat_ctx  mat_ctx;
12183425bc38SStefano Zampini   PetscErrorCode ierr;
12193425bc38SStefano Zampini 
12203425bc38SStefano Zampini   PetscFunctionBegin;
12213425bc38SStefano Zampini   ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr);
12223425bc38SStefano Zampini   ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr);
12233425bc38SStefano Zampini   PetscFunctionReturn(0);
12243425bc38SStefano Zampini }
12253425bc38SStefano Zampini /* -------------------------------------------------------------------------- */
12261e6b0712SBarry Smith 
1227f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec);
1228f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat);
1229f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec);
1230f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC);
1231674ae819SStefano Zampini 
12323425bc38SStefano Zampini #undef __FUNCT__
12333425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC"
12343425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, Mat *fetidp_mat, PC *fetidp_pc)
12353425bc38SStefano Zampini {
1236674ae819SStefano Zampini 
1237674ae819SStefano Zampini   FETIDPMat_ctx  fetidpmat_ctx;
12383425bc38SStefano Zampini   Mat            newmat;
1239674ae819SStefano Zampini   FETIDPPC_ctx   fetidppc_ctx;
12403425bc38SStefano Zampini   PC             newpc;
1241ce94432eSBarry Smith   MPI_Comm       comm;
12423425bc38SStefano Zampini   PetscErrorCode ierr;
12433425bc38SStefano Zampini 
12443425bc38SStefano Zampini   PetscFunctionBegin;
1245ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr);
12463425bc38SStefano Zampini   /* FETIDP linear matrix */
12473425bc38SStefano Zampini   ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr);
12483425bc38SStefano Zampini   ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr);
12493425bc38SStefano Zampini   ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr);
12503425bc38SStefano Zampini   ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr);
12513425bc38SStefano Zampini   ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr);
12523425bc38SStefano Zampini   ierr = MatSetUp(newmat);CHKERRQ(ierr);
12533425bc38SStefano Zampini   /* FETIDP preconditioner */
12543425bc38SStefano Zampini   ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr);
12553425bc38SStefano Zampini   ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr);
12563425bc38SStefano Zampini   ierr = PCCreate(comm,&newpc);CHKERRQ(ierr);
12573425bc38SStefano Zampini   ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr);
12583425bc38SStefano Zampini   ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr);
12593425bc38SStefano Zampini   ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr);
12603425bc38SStefano Zampini   ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr);
12613425bc38SStefano Zampini   ierr = PCSetOperators(newpc,newmat,newmat,SAME_PRECONDITIONER);CHKERRQ(ierr);
12623425bc38SStefano Zampini   ierr = PCSetUp(newpc);CHKERRQ(ierr);
12633425bc38SStefano Zampini   /* return pointers for objects created */
12643425bc38SStefano Zampini   *fetidp_mat=newmat;
12653425bc38SStefano Zampini   *fetidp_pc=newpc;
12663425bc38SStefano Zampini   PetscFunctionReturn(0);
12673425bc38SStefano Zampini }
12681e6b0712SBarry Smith 
12693425bc38SStefano Zampini #undef __FUNCT__
12703425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators"
12713425bc38SStefano Zampini /*@
127228509bceSStefano Zampini  PCBDDCCreateFETIDPOperators - Create operators for FETIDP
12733425bc38SStefano Zampini 
12743425bc38SStefano Zampini    Collective
12753425bc38SStefano Zampini 
12763425bc38SStefano Zampini    Input Parameters:
127728509bceSStefano Zampini +  pc - the BDDC preconditioning context already setup
127828509bceSStefano Zampini 
127928509bceSStefano Zampini    Output Parameters:
128028509bceSStefano Zampini .  fetidp_mat - shell FETIDP matrix object
128128509bceSStefano Zampini .  fetidp_pc  - shell Dirichlet preconditioner for FETIDP matrix
128228509bceSStefano Zampini 
128328509bceSStefano Zampini    Options Database Keys:
128428509bceSStefano Zampini -    -fetidp_fullyredundant: use or not a fully redundant set of Lagrange multipliers
12853425bc38SStefano Zampini 
12863425bc38SStefano Zampini    Level: developer
12873425bc38SStefano Zampini 
12883425bc38SStefano Zampini    Notes:
128928509bceSStefano Zampini      Currently the only operation provided for FETIDP matrix is MatMult
12903425bc38SStefano Zampini 
12913425bc38SStefano Zampini .seealso: PCBDDC
12923425bc38SStefano Zampini @*/
12933425bc38SStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, Mat *fetidp_mat, PC *fetidp_pc)
12943425bc38SStefano Zampini {
12953425bc38SStefano Zampini   PetscErrorCode ierr;
12963425bc38SStefano Zampini 
12973425bc38SStefano Zampini   PetscFunctionBegin;
12983425bc38SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12993425bc38SStefano Zampini   if (pc->setupcalled) {
1300516d51a7SStefano Zampini     ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,Mat*,PC*),(pc,fetidp_mat,fetidp_pc));CHKERRQ(ierr);
1301f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n");
13023425bc38SStefano Zampini   PetscFunctionReturn(0);
13033425bc38SStefano Zampini }
13040c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
1305da1bb401SStefano Zampini /*MC
1306da1bb401SStefano Zampini    PCBDDC - Balancing Domain Decomposition by Constraints.
13070c7d97c5SJed Brown 
130828509bceSStefano Zampini    An implementation of the BDDC preconditioner based on
130928509bceSStefano Zampini 
131028509bceSStefano Zampini .vb
131128509bceSStefano Zampini    [1] C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007
131228509bceSStefano 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
131328509bceSStefano Zampini    [3] J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", http://arxiv.org/abs/0712.3977
131428509bceSStefano Zampini .ve
131528509bceSStefano Zampini 
131628509bceSStefano Zampini    The matrix to be preconditioned (Pmat) must be of type MATIS.
131728509bceSStefano Zampini 
1318b6fdb6dfSStefano Zampini    Currently works with MATIS matrices with local Neumann matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers.
131928509bceSStefano Zampini 
132028509bceSStefano Zampini    It also works with unsymmetric and indefinite problems.
132128509bceSStefano Zampini 
1322b6fdb6dfSStefano 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.
1323b6fdb6dfSStefano Zampini 
132428509bceSStefano Zampini    Approximate local solvers are automatically adapted for singular linear problems (see [1]) if the user has provided the nullspace using PCBDDCSetNullSpace
132528509bceSStefano Zampini 
132628509bceSStefano 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
132728509bceSStefano Zampini 
132828509bceSStefano Zampini    Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace.
132928509bceSStefano Zampini 
1330b6fdb6dfSStefano 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.
133128509bceSStefano Zampini 
133228509bceSStefano Zampini    The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using MatPartitioning object.
133328509bceSStefano Zampini 
1334da1bb401SStefano Zampini    Options Database Keys:
133528509bceSStefano Zampini 
133628509bceSStefano Zampini .    -pc_bddc_use_vertices <1> - use or not vertices in primal space
133728509bceSStefano Zampini .    -pc_bddc_use_edges <1> - use or not edges in primal space
1338b6fdb6dfSStefano Zampini .    -pc_bddc_use_faces <0> - use or not faces in primal space
133928509bceSStefano Zampini .    -pc_bddc_use_change_of_basis <0> - use change of basis approach (on edges only)
134028509bceSStefano Zampini .    -pc_bddc_use_change_on_faces <0> - use change of basis approach on faces if change of basis has been requested
134128509bceSStefano Zampini .    -pc_bddc_switch_static <0> - switches from M_2 to M_3 operator (see reference article [1])
134228509bceSStefano Zampini .    -pc_bddc_levels <0> - maximum number of levels for multilevel
134328509bceSStefano Zampini .    -pc_bddc_coarsening_ratio - H/h ratio at the coarser level
134428509bceSStefano Zampini -    -pc_bddc_check_level <0> - set verbosity level of debugging output
134528509bceSStefano Zampini 
134628509bceSStefano Zampini    Options for Dirichlet, Neumann or coarse solver can be set with
134728509bceSStefano Zampini .vb
134828509bceSStefano Zampini       -pc_bddc_dirichlet_
134928509bceSStefano Zampini       -pc_bddc_neumann_
135028509bceSStefano Zampini       -pc_bddc_coarse_
135128509bceSStefano Zampini .ve
135228509bceSStefano Zampini    e.g -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg
135328509bceSStefano Zampini 
135428509bceSStefano Zampini    When using a multilevel approach, solvers' options at the N-th level can be specified as
135528509bceSStefano Zampini .vb
135628509bceSStefano Zampini       -pc_bddc_dirichlet_N_
135728509bceSStefano Zampini       -pc_bddc_neumann_N_
135828509bceSStefano Zampini       -pc_bddc_coarse_N_
135928509bceSStefano Zampini .ve
136028509bceSStefano Zampini    Note that level number ranges from the finest 0 to the coarsest N
1361da1bb401SStefano Zampini 
1362da1bb401SStefano Zampini    Level: intermediate
1363da1bb401SStefano Zampini 
1364b6fdb6dfSStefano Zampini    Developer notes:
1365da1bb401SStefano Zampini 
136628509bceSStefano Zampini    New deluxe scaling operator will be available soon.
1367da1bb401SStefano Zampini 
1368da1bb401SStefano Zampini    Contributed by Stefano Zampini
1369da1bb401SStefano Zampini 
1370da1bb401SStefano Zampini .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,  MATIS
1371da1bb401SStefano Zampini M*/
1372b2573a8aSBarry Smith 
1373da1bb401SStefano Zampini #undef __FUNCT__
1374da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC"
13758cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc)
1376da1bb401SStefano Zampini {
1377da1bb401SStefano Zampini   PetscErrorCode      ierr;
1378da1bb401SStefano Zampini   PC_BDDC             *pcbddc;
1379da1bb401SStefano Zampini 
1380da1bb401SStefano Zampini   PetscFunctionBegin;
1381da1bb401SStefano Zampini   /* Creates the private data structure for this preconditioner and attach it to the PC object. */
1382da1bb401SStefano Zampini   ierr      = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr);
1383da1bb401SStefano Zampini   pc->data  = (void*)pcbddc;
1384da1bb401SStefano Zampini 
1385da1bb401SStefano Zampini   /* create PCIS data structure */
1386da1bb401SStefano Zampini   ierr = PCISCreate(pc);CHKERRQ(ierr);
1387da1bb401SStefano Zampini 
138847d04d0dSStefano Zampini   /* BDDC customization */
138947d04d0dSStefano Zampini   pcbddc->use_vertices        = PETSC_TRUE;
139047d04d0dSStefano Zampini   pcbddc->use_edges           = PETSC_TRUE;
139147d04d0dSStefano Zampini   pcbddc->use_faces           = PETSC_FALSE;
139247d04d0dSStefano Zampini   pcbddc->use_change_of_basis = PETSC_FALSE;
139347d04d0dSStefano Zampini   pcbddc->use_change_on_faces = PETSC_FALSE;
139447d04d0dSStefano Zampini   pcbddc->switch_static       = PETSC_FALSE;
139547d04d0dSStefano Zampini   pcbddc->use_nnsp_true       = PETSC_FALSE; /* not yet exposed */
139647d04d0dSStefano Zampini   pcbddc->dbg_flag            = 0;
139747d04d0dSStefano Zampini 
1398674ae819SStefano Zampini   pcbddc->user_primal_vertices       = 0;
13990bdf917eSStefano Zampini   pcbddc->NullSpace                  = 0;
14003972b0daSStefano Zampini   pcbddc->temp_solution              = 0;
1401534831adSStefano Zampini   pcbddc->original_rhs               = 0;
1402534831adSStefano Zampini   pcbddc->local_mat                  = 0;
1403534831adSStefano Zampini   pcbddc->ChangeOfBasisMatrix        = 0;
1404da1bb401SStefano Zampini   pcbddc->coarse_vec                 = 0;
1405da1bb401SStefano Zampini   pcbddc->coarse_rhs                 = 0;
1406da1bb401SStefano Zampini   pcbddc->coarse_ksp                 = 0;
1407da1bb401SStefano Zampini   pcbddc->coarse_phi_B               = 0;
1408da1bb401SStefano Zampini   pcbddc->coarse_phi_D               = 0;
140915aaf578SStefano Zampini   pcbddc->coarse_psi_B               = 0;
141015aaf578SStefano Zampini   pcbddc->coarse_psi_D               = 0;
1411da1bb401SStefano Zampini   pcbddc->vec1_P                     = 0;
1412da1bb401SStefano Zampini   pcbddc->vec1_R                     = 0;
1413da1bb401SStefano Zampini   pcbddc->vec2_R                     = 0;
1414da1bb401SStefano Zampini   pcbddc->local_auxmat1              = 0;
1415da1bb401SStefano Zampini   pcbddc->local_auxmat2              = 0;
1416da1bb401SStefano Zampini   pcbddc->R_to_B                     = 0;
1417da1bb401SStefano Zampini   pcbddc->R_to_D                     = 0;
1418da1bb401SStefano Zampini   pcbddc->ksp_D                      = 0;
1419da1bb401SStefano Zampini   pcbddc->ksp_R                      = 0;
1420da1bb401SStefano Zampini   pcbddc->NeumannBoundaries          = 0;
142160d44989SStefano Zampini   pcbddc->user_provided_isfordofs    = PETSC_FALSE;
142260d44989SStefano Zampini   pcbddc->n_ISForDofs                = 0;
1423da1bb401SStefano Zampini   pcbddc->ISForDofs                  = 0;
1424da1bb401SStefano Zampini   pcbddc->ConstraintMatrix           = 0;
142585c4d303SStefano Zampini   pcbddc->use_exact_dirichlet_trick  = PETSC_TRUE;
142647d04d0dSStefano Zampini   pcbddc->coarse_loc_to_glob         = 0;
142747d04d0dSStefano Zampini   pcbddc->coarsening_ratio           = 8;
14284fad6a16SStefano Zampini   pcbddc->current_level              = 0;
14292b510759SStefano Zampini   pcbddc->max_levels                 = 0;
1430da1bb401SStefano Zampini 
1431674ae819SStefano Zampini   /* create local graph structure */
1432674ae819SStefano Zampini   ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr);
1433674ae819SStefano Zampini 
1434674ae819SStefano Zampini   /* scaling */
1435674ae819SStefano Zampini   pcbddc->use_deluxe_scaling         = PETSC_FALSE;
1436674ae819SStefano Zampini   pcbddc->work_scaling               = 0;
1437da1bb401SStefano Zampini 
1438da1bb401SStefano Zampini   /* function pointers */
1439da1bb401SStefano Zampini   pc->ops->apply               = PCApply_BDDC;
1440*93bd9ae7SStefano Zampini   pc->ops->applytranspose      = PCApplyTranspose_BDDC;
1441da1bb401SStefano Zampini   pc->ops->setup               = PCSetUp_BDDC;
1442da1bb401SStefano Zampini   pc->ops->destroy             = PCDestroy_BDDC;
1443da1bb401SStefano Zampini   pc->ops->setfromoptions      = PCSetFromOptions_BDDC;
1444da1bb401SStefano Zampini   pc->ops->view                = 0;
1445da1bb401SStefano Zampini   pc->ops->applyrichardson     = 0;
1446da1bb401SStefano Zampini   pc->ops->applysymmetricleft  = 0;
1447da1bb401SStefano Zampini   pc->ops->applysymmetricright = 0;
1448534831adSStefano Zampini   pc->ops->presolve            = PCPreSolve_BDDC;
1449534831adSStefano Zampini   pc->ops->postsolve           = PCPostSolve_BDDC;
1450da1bb401SStefano Zampini 
1451da1bb401SStefano Zampini   /* composing function */
1452674ae819SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr);
1453bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr);
14542b510759SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr);
1455b8ffe317SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr);
14562b510759SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr);
1457bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",PCBDDCSetNullSpace_BDDC);CHKERRQ(ierr);
1458bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr);
1459bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr);
1460bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr);
1461bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr);
1462bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr);
1463bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr);
1464bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr);
1465bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr);
1466bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr);
1467da1bb401SStefano Zampini   PetscFunctionReturn(0);
1468da1bb401SStefano Zampini }
14693425bc38SStefano Zampini 
1470