xref: /petsc/src/ksp/pc/impls/bddc/bddc.c (revision 82ba6b801c331e5ff5b2a0ac3057de94993d6952)
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
17*82ba6b80SStefano Zampini    - 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    - Provide PCApplyTranpose_BDDC
20eb97c9d2SStefano Zampini    - DofSplitting and DM attached to pc?
21eb97c9d2SStefano Zampini 
22eb97c9d2SStefano Zampini    Debugging output
23eb97c9d2SStefano Zampini    - Better management of verbosity levels of debugging output
24eb97c9d2SStefano Zampini    - Crashes on some architecture -> call SynchronizedAllow before every SynchronizedPrintf
25eb97c9d2SStefano Zampini 
26eb97c9d2SStefano Zampini    Build
27eb97c9d2SStefano Zampini    - make runexe59
28eb97c9d2SStefano Zampini 
29eb97c9d2SStefano Zampini    Extra
30eb97c9d2SStefano Zampini    - Is it possible to work with PCBDDCGraph on boundary indices only (less memory consumed)?
31eb97c9d2SStefano Zampini    - Why options for "pc_bddc_coarse" solver gets propagated to "pc_bddc_coarse_1" solver?
32eb97c9d2SStefano Zampini    - add support for computing h,H and related using coordinates?
33c0b83709SStefano Zampini    - Change of basis approach does not work with my nonlinear mechanics example. why? (seems not an issue with l2gmap)
34eb97c9d2SStefano Zampini    - Better management in PCIS code
35eb97c9d2SStefano Zampini    - BDDC with MG framework?
36eb97c9d2SStefano Zampini 
37eb97c9d2SStefano Zampini    FETIDP
38eb97c9d2SStefano Zampini    - Move FETIDP code to its own classes
39eb97c9d2SStefano Zampini 
40eb97c9d2SStefano Zampini    MATIS related operations contained in BDDC code
41eb97c9d2SStefano Zampini    - Provide general case for subassembling
42eb97c9d2SStefano Zampini    - Preallocation routines in MatConvert_IS_AIJ
43eb97c9d2SStefano Zampini 
4453cdbc3dSStefano Zampini */
450c7d97c5SJed Brown 
4653cdbc3dSStefano Zampini /* ----------------------------------------------------------------------------------------------------------------------------------------------
470c7d97c5SJed Brown    Implementation of BDDC preconditioner based on:
480c7d97c5SJed Brown    C. Dohrmann "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007
4953cdbc3dSStefano Zampini    ---------------------------------------------------------------------------------------------------------------------------------------------- */
5053cdbc3dSStefano Zampini 
51674ae819SStefano Zampini #include "bddc.h" /*I "petscpc.h" I*/  /* includes for fortran wrappers */
52674ae819SStefano Zampini #include "bddcprivate.h"
533b03a366Sstefano_zampini #include <petscblaslapack.h>
54674ae819SStefano Zampini 
550c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
560c7d97c5SJed Brown #undef __FUNCT__
570c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC"
580c7d97c5SJed Brown PetscErrorCode PCSetFromOptions_BDDC(PC pc)
590c7d97c5SJed Brown {
600c7d97c5SJed Brown   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
610c7d97c5SJed Brown   PetscErrorCode ierr;
620c7d97c5SJed Brown 
630c7d97c5SJed Brown   PetscFunctionBegin;
640c7d97c5SJed Brown   ierr = PetscOptionsHead("BDDC options");CHKERRQ(ierr);
658eeda7d8SStefano Zampini   /* Verbose debugging */
668eeda7d8SStefano Zampini   ierr = PetscOptionsInt("-pc_bddc_check_level","Verbose output for PCBDDC (intended for debug)","none",pcbddc->dbg_flag,&pcbddc->dbg_flag,NULL);CHKERRQ(ierr);
678eeda7d8SStefano Zampini   /* Primal space cumstomization */
688eeda7d8SStefano 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);
698eeda7d8SStefano 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);
708eeda7d8SStefano 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);
718eeda7d8SStefano Zampini   /* Change of basis */
728eeda7d8SStefano 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);
738eeda7d8SStefano 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);
74674ae819SStefano Zampini   if (!pcbddc->use_change_of_basis) {
75674ae819SStefano Zampini     pcbddc->use_change_on_faces = PETSC_FALSE;
76674ae819SStefano Zampini   }
778eeda7d8SStefano Zampini   /* Switch between M_2 (default) and M_3 preconditioners (as defined by C. Dohrmann in the ref. article) */
788eeda7d8SStefano 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);
790298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr);
802b510759SStefano Zampini   ierr = PetscOptionsInt("-pc_bddc_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr);
81674ae819SStefano 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);
820c7d97c5SJed Brown   ierr = PetscOptionsTail();CHKERRQ(ierr);
830c7d97c5SJed Brown   PetscFunctionReturn(0);
840c7d97c5SJed Brown }
850c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
86674ae819SStefano Zampini #undef __FUNCT__
87674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS_BDDC"
88674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices)
89674ae819SStefano Zampini {
90674ae819SStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
91674ae819SStefano Zampini   PetscErrorCode ierr;
921e6b0712SBarry Smith 
93674ae819SStefano Zampini   PetscFunctionBegin;
94674ae819SStefano Zampini   ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr);
95674ae819SStefano Zampini   ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr);
96674ae819SStefano Zampini   pcbddc->user_primal_vertices = PrimalVertices;
97674ae819SStefano Zampini   PetscFunctionReturn(0);
98674ae819SStefano Zampini }
99674ae819SStefano Zampini #undef __FUNCT__
100674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS"
101674ae819SStefano Zampini /*@
10228509bceSStefano Zampini  PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC
103674ae819SStefano Zampini 
104674ae819SStefano Zampini    Not collective
105674ae819SStefano Zampini 
106674ae819SStefano Zampini    Input Parameters:
107674ae819SStefano Zampini +  pc - the preconditioning context
10828509bceSStefano Zampini -  PrimalVertices - index set of primal vertices in local numbering
109674ae819SStefano Zampini 
110674ae819SStefano Zampini    Level: intermediate
111674ae819SStefano Zampini 
112674ae819SStefano Zampini    Notes:
113674ae819SStefano Zampini 
114674ae819SStefano Zampini .seealso: PCBDDC
115674ae819SStefano Zampini @*/
116674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices)
117674ae819SStefano Zampini {
118674ae819SStefano Zampini   PetscErrorCode ierr;
119674ae819SStefano Zampini 
120674ae819SStefano Zampini   PetscFunctionBegin;
121674ae819SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
122674ae819SStefano Zampini   PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2);
123674ae819SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr);
124674ae819SStefano Zampini   PetscFunctionReturn(0);
125674ae819SStefano Zampini }
126674ae819SStefano Zampini /* -------------------------------------------------------------------------- */
1270c7d97c5SJed Brown #undef __FUNCT__
1284fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio_BDDC"
1294fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k)
1304fad6a16SStefano Zampini {
1314fad6a16SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
1324fad6a16SStefano Zampini 
1334fad6a16SStefano Zampini   PetscFunctionBegin;
1344fad6a16SStefano Zampini   pcbddc->coarsening_ratio = k;
1354fad6a16SStefano Zampini   PetscFunctionReturn(0);
1364fad6a16SStefano Zampini }
1371e6b0712SBarry Smith 
1384fad6a16SStefano Zampini #undef __FUNCT__
1394fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio"
1404fad6a16SStefano Zampini /*@
14128509bceSStefano Zampini  PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel
1424fad6a16SStefano Zampini 
1434fad6a16SStefano Zampini    Logically collective on PC
1444fad6a16SStefano Zampini 
1454fad6a16SStefano Zampini    Input Parameters:
1464fad6a16SStefano Zampini +  pc - the preconditioning context
14728509bceSStefano Zampini -  k - coarsening ratio (H/h at the coarser level)
1484fad6a16SStefano Zampini 
14928509bceSStefano Zampini    Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level
1504fad6a16SStefano Zampini 
1514fad6a16SStefano Zampini    Level: intermediate
1524fad6a16SStefano Zampini 
1534fad6a16SStefano Zampini    Notes:
1544fad6a16SStefano Zampini 
1554fad6a16SStefano Zampini .seealso: PCBDDC
1564fad6a16SStefano Zampini @*/
1574fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k)
1584fad6a16SStefano Zampini {
1594fad6a16SStefano Zampini   PetscErrorCode ierr;
1604fad6a16SStefano Zampini 
1614fad6a16SStefano Zampini   PetscFunctionBegin;
1624fad6a16SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1632b510759SStefano Zampini   PetscValidLogicalCollectiveInt(pc,k,2);
1644fad6a16SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr);
1654fad6a16SStefano Zampini   PetscFunctionReturn(0);
1664fad6a16SStefano Zampini }
1672b510759SStefano Zampini 
168b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */
1692b510759SStefano Zampini #undef __FUNCT__
170b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet_BDDC"
171b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg)
172b8ffe317SStefano Zampini {
173b8ffe317SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
174b8ffe317SStefano Zampini 
175b8ffe317SStefano Zampini   PetscFunctionBegin;
17685c4d303SStefano Zampini   pcbddc->use_exact_dirichlet_trick = flg;
177b8ffe317SStefano Zampini   PetscFunctionReturn(0);
178b8ffe317SStefano Zampini }
179b8ffe317SStefano Zampini 
180b8ffe317SStefano Zampini #undef __FUNCT__
181b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet"
182b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg)
1832b510759SStefano Zampini {
1842b510759SStefano Zampini   PetscErrorCode ierr;
1852b510759SStefano Zampini 
1862b510759SStefano Zampini   PetscFunctionBegin;
1872b510759SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
188b8ffe317SStefano Zampini   PetscValidLogicalCollectiveBool(pc,flg,2);
189b8ffe317SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr);
1902b510759SStefano Zampini   PetscFunctionReturn(0);
1912b510759SStefano Zampini }
1921e6b0712SBarry Smith 
1934fad6a16SStefano Zampini #undef __FUNCT__
1942b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel_BDDC"
1952b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level)
1964fad6a16SStefano Zampini {
1974fad6a16SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
1984fad6a16SStefano Zampini 
1994fad6a16SStefano Zampini   PetscFunctionBegin;
2002b510759SStefano Zampini   pcbddc->current_level = level;
2014fad6a16SStefano Zampini   PetscFunctionReturn(0);
2024fad6a16SStefano Zampini }
2031e6b0712SBarry Smith 
2044fad6a16SStefano Zampini #undef __FUNCT__
205b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel"
206b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level)
207b8ffe317SStefano Zampini {
208b8ffe317SStefano Zampini   PetscErrorCode ierr;
209b8ffe317SStefano Zampini 
210b8ffe317SStefano Zampini   PetscFunctionBegin;
211b8ffe317SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
212b8ffe317SStefano Zampini   PetscValidLogicalCollectiveInt(pc,level,2);
213b8ffe317SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr);
214b8ffe317SStefano Zampini   PetscFunctionReturn(0);
215b8ffe317SStefano Zampini }
216b8ffe317SStefano Zampini 
217b8ffe317SStefano Zampini #undef __FUNCT__
2182b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels_BDDC"
2192b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels)
2202b510759SStefano Zampini {
2212b510759SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
2222b510759SStefano Zampini 
2232b510759SStefano Zampini   PetscFunctionBegin;
2242b510759SStefano Zampini   pcbddc->max_levels = levels;
2252b510759SStefano Zampini   PetscFunctionReturn(0);
2262b510759SStefano Zampini }
2272b510759SStefano Zampini 
2282b510759SStefano Zampini #undef __FUNCT__
2292b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels"
2304fad6a16SStefano Zampini /*@
23128509bceSStefano Zampini  PCBDDCSetLevels - Sets the maximum number of levels for multilevel
2324fad6a16SStefano Zampini 
2334fad6a16SStefano Zampini    Logically collective on PC
2344fad6a16SStefano Zampini 
2354fad6a16SStefano Zampini    Input Parameters:
2364fad6a16SStefano Zampini +  pc - the preconditioning context
23728509bceSStefano Zampini -  levels - the maximum number of levels (max 9)
2384fad6a16SStefano Zampini 
23928509bceSStefano Zampini    Default value is 0, i.e. traditional one-level BDDC
2404fad6a16SStefano Zampini 
2414fad6a16SStefano Zampini    Level: intermediate
2424fad6a16SStefano Zampini 
2434fad6a16SStefano Zampini    Notes:
2444fad6a16SStefano Zampini 
2454fad6a16SStefano Zampini .seealso: PCBDDC
2464fad6a16SStefano Zampini @*/
2472b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels)
2484fad6a16SStefano Zampini {
2494fad6a16SStefano Zampini   PetscErrorCode ierr;
2504fad6a16SStefano Zampini 
2514fad6a16SStefano Zampini   PetscFunctionBegin;
2524fad6a16SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2532b510759SStefano Zampini   PetscValidLogicalCollectiveInt(pc,levels,2);
2542b510759SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr);
2554fad6a16SStefano Zampini   PetscFunctionReturn(0);
2564fad6a16SStefano Zampini }
2574fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */
2581e6b0712SBarry Smith 
2594fad6a16SStefano Zampini #undef __FUNCT__
2600bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace_BDDC"
2610bdf917eSStefano Zampini static PetscErrorCode PCBDDCSetNullSpace_BDDC(PC pc,MatNullSpace NullSpace)
2620bdf917eSStefano Zampini {
2630bdf917eSStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
2640bdf917eSStefano Zampini   PetscErrorCode ierr;
2650bdf917eSStefano Zampini 
2660bdf917eSStefano Zampini   PetscFunctionBegin;
2670bdf917eSStefano Zampini   ierr = PetscObjectReference((PetscObject)NullSpace);CHKERRQ(ierr);
2680bdf917eSStefano Zampini   ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr);
2690bdf917eSStefano Zampini   pcbddc->NullSpace = NullSpace;
2700bdf917eSStefano Zampini   PetscFunctionReturn(0);
2710bdf917eSStefano Zampini }
2721e6b0712SBarry Smith 
2730bdf917eSStefano Zampini #undef __FUNCT__
2740bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace"
2750bdf917eSStefano Zampini /*@
27628509bceSStefano Zampini  PCBDDCSetNullSpace - Set nullspace for BDDC operator
2770bdf917eSStefano Zampini 
2780bdf917eSStefano Zampini    Logically collective on PC and MatNullSpace
2790bdf917eSStefano Zampini 
2800bdf917eSStefano Zampini    Input Parameters:
2810bdf917eSStefano Zampini +  pc - the preconditioning context
28228509bceSStefano Zampini -  NullSpace - Null space of the linear operator to be preconditioned (Pmat)
2830bdf917eSStefano Zampini 
2840bdf917eSStefano Zampini    Level: intermediate
2850bdf917eSStefano Zampini 
2860bdf917eSStefano Zampini    Notes:
2870bdf917eSStefano Zampini 
2880bdf917eSStefano Zampini .seealso: PCBDDC
2890bdf917eSStefano Zampini @*/
2900bdf917eSStefano Zampini PetscErrorCode PCBDDCSetNullSpace(PC pc,MatNullSpace NullSpace)
2910bdf917eSStefano Zampini {
2920bdf917eSStefano Zampini   PetscErrorCode ierr;
2930bdf917eSStefano Zampini 
2940bdf917eSStefano Zampini   PetscFunctionBegin;
2950bdf917eSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
296674ae819SStefano Zampini   PetscValidHeaderSpecific(NullSpace,MAT_NULLSPACE_CLASSID,2);
2972b510759SStefano Zampini   PetscCheckSameComm(pc,1,NullSpace,2);
2980bdf917eSStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetNullSpace_C",(PC,MatNullSpace),(pc,NullSpace));CHKERRQ(ierr);
2990bdf917eSStefano Zampini   PetscFunctionReturn(0);
3000bdf917eSStefano Zampini }
3010bdf917eSStefano Zampini /* -------------------------------------------------------------------------- */
3021e6b0712SBarry Smith 
3030bdf917eSStefano Zampini #undef __FUNCT__
304*82ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal_BDDC"
305*82ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries)
3063b03a366Sstefano_zampini {
3073b03a366Sstefano_zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
3083b03a366Sstefano_zampini   PetscErrorCode ierr;
3093b03a366Sstefano_zampini 
3103b03a366Sstefano_zampini   PetscFunctionBegin;
3113b03a366Sstefano_zampini   ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr);
31236e030ebSStefano Zampini   ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr);
31336e030ebSStefano Zampini   pcbddc->DirichletBoundaries = DirichletBoundaries;
3143b03a366Sstefano_zampini   PetscFunctionReturn(0);
3153b03a366Sstefano_zampini }
3161e6b0712SBarry Smith 
3173b03a366Sstefano_zampini #undef __FUNCT__
318*82ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal"
3193b03a366Sstefano_zampini /*@
320*82ba6b80SStefano Zampini  PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering.
3213b03a366Sstefano_zampini 
3223b03a366Sstefano_zampini    Not collective
3233b03a366Sstefano_zampini 
3243b03a366Sstefano_zampini    Input Parameters:
3253b03a366Sstefano_zampini +  pc - the preconditioning context
326*82ba6b80SStefano Zampini -  DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering)
3273b03a366Sstefano_zampini 
3283b03a366Sstefano_zampini    Level: intermediate
3293b03a366Sstefano_zampini 
3303b03a366Sstefano_zampini    Notes:
3313b03a366Sstefano_zampini 
3323b03a366Sstefano_zampini .seealso: PCBDDC
3333b03a366Sstefano_zampini @*/
334*82ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries)
3353b03a366Sstefano_zampini {
3363b03a366Sstefano_zampini   PetscErrorCode ierr;
3373b03a366Sstefano_zampini 
3383b03a366Sstefano_zampini   PetscFunctionBegin;
3393b03a366Sstefano_zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
340674ae819SStefano Zampini   PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2);
341*82ba6b80SStefano Zampini   PetscCheckSameComm(pc,1,DirichletBoundaries,2);
342*82ba6b80SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr);
3433b03a366Sstefano_zampini   PetscFunctionReturn(0);
3443b03a366Sstefano_zampini }
3453b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */
3461e6b0712SBarry Smith 
3473b03a366Sstefano_zampini #undef __FUNCT__
348*82ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal_BDDC"
349*82ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries)
3500c7d97c5SJed Brown {
3510c7d97c5SJed Brown   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
35253cdbc3dSStefano Zampini   PetscErrorCode ierr;
3530c7d97c5SJed Brown 
3540c7d97c5SJed Brown   PetscFunctionBegin;
35553cdbc3dSStefano Zampini   ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr);
35636e030ebSStefano Zampini   ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr);
35736e030ebSStefano Zampini   pcbddc->NeumannBoundaries = NeumannBoundaries;
3580c7d97c5SJed Brown   PetscFunctionReturn(0);
3590c7d97c5SJed Brown }
3601e6b0712SBarry Smith 
3610c7d97c5SJed Brown #undef __FUNCT__
362*82ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal"
36357527edcSJed Brown /*@
364*82ba6b80SStefano Zampini  PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering.
36557527edcSJed Brown 
3669c0446d6SStefano Zampini    Not collective
36757527edcSJed Brown 
36857527edcSJed Brown    Input Parameters:
36957527edcSJed Brown +  pc - the preconditioning context
370*82ba6b80SStefano Zampini -  NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering)
37157527edcSJed Brown 
37257527edcSJed Brown    Level: intermediate
37357527edcSJed Brown 
37457527edcSJed Brown    Notes:
37557527edcSJed Brown 
37657527edcSJed Brown .seealso: PCBDDC
37757527edcSJed Brown @*/
378*82ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries)
3790c7d97c5SJed Brown {
3800c7d97c5SJed Brown   PetscErrorCode ierr;
3810c7d97c5SJed Brown 
3820c7d97c5SJed Brown   PetscFunctionBegin;
3830c7d97c5SJed Brown   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
384674ae819SStefano Zampini   PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2);
385*82ba6b80SStefano Zampini   PetscCheckSameComm(pc,1,NeumannBoundaries,2);
386*82ba6b80SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr);
38753cdbc3dSStefano Zampini   PetscFunctionReturn(0);
38853cdbc3dSStefano Zampini }
38953cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */
3901e6b0712SBarry Smith 
39153cdbc3dSStefano Zampini #undef __FUNCT__
392*82ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal_BDDC"
393*82ba6b80SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries)
394da1bb401SStefano Zampini {
395da1bb401SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
396da1bb401SStefano Zampini 
397da1bb401SStefano Zampini   PetscFunctionBegin;
398da1bb401SStefano Zampini   *DirichletBoundaries = pcbddc->DirichletBoundaries;
399da1bb401SStefano Zampini   PetscFunctionReturn(0);
400da1bb401SStefano Zampini }
4011e6b0712SBarry Smith 
402da1bb401SStefano Zampini #undef __FUNCT__
403*82ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal"
404da1bb401SStefano Zampini /*@
405*82ba6b80SStefano Zampini  PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering)
406da1bb401SStefano Zampini 
407da1bb401SStefano Zampini    Not collective
408da1bb401SStefano Zampini 
409da1bb401SStefano Zampini    Input Parameters:
41028509bceSStefano Zampini .  pc - the preconditioning context
411da1bb401SStefano Zampini 
412da1bb401SStefano Zampini    Output Parameters:
41328509bceSStefano Zampini .  DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries
414da1bb401SStefano Zampini 
415da1bb401SStefano Zampini    Level: intermediate
416da1bb401SStefano Zampini 
417da1bb401SStefano Zampini    Notes:
418da1bb401SStefano Zampini 
419da1bb401SStefano Zampini .seealso: PCBDDC
420da1bb401SStefano Zampini @*/
421*82ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries)
422da1bb401SStefano Zampini {
423da1bb401SStefano Zampini   PetscErrorCode ierr;
424da1bb401SStefano Zampini 
425da1bb401SStefano Zampini   PetscFunctionBegin;
426da1bb401SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
427*82ba6b80SStefano Zampini   ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr);
428da1bb401SStefano Zampini   PetscFunctionReturn(0);
429da1bb401SStefano Zampini }
430da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */
4311e6b0712SBarry Smith 
432da1bb401SStefano Zampini #undef __FUNCT__
433*82ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal_BDDC"
434*82ba6b80SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries)
43553cdbc3dSStefano Zampini {
43653cdbc3dSStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
43753cdbc3dSStefano Zampini 
43853cdbc3dSStefano Zampini   PetscFunctionBegin;
43953cdbc3dSStefano Zampini   *NeumannBoundaries = pcbddc->NeumannBoundaries;
44053cdbc3dSStefano Zampini   PetscFunctionReturn(0);
44153cdbc3dSStefano Zampini }
4421e6b0712SBarry Smith 
44353cdbc3dSStefano Zampini #undef __FUNCT__
444*82ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal"
44553cdbc3dSStefano Zampini /*@
446*82ba6b80SStefano Zampini  PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering)
44753cdbc3dSStefano Zampini 
4489c0446d6SStefano Zampini    Not collective
44953cdbc3dSStefano Zampini 
45053cdbc3dSStefano Zampini    Input Parameters:
45128509bceSStefano Zampini .  pc - the preconditioning context
45253cdbc3dSStefano Zampini 
45353cdbc3dSStefano Zampini    Output Parameters:
45428509bceSStefano Zampini .  NeumannBoundaries - index set defining the subdomain part of Neumann boundaries
45553cdbc3dSStefano Zampini 
45653cdbc3dSStefano Zampini    Level: intermediate
45753cdbc3dSStefano Zampini 
45853cdbc3dSStefano Zampini    Notes:
45953cdbc3dSStefano Zampini 
46053cdbc3dSStefano Zampini .seealso: PCBDDC
46153cdbc3dSStefano Zampini @*/
462*82ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries)
46353cdbc3dSStefano Zampini {
46453cdbc3dSStefano Zampini   PetscErrorCode ierr;
46553cdbc3dSStefano Zampini 
46653cdbc3dSStefano Zampini   PetscFunctionBegin;
46753cdbc3dSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
468*82ba6b80SStefano Zampini   ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr);
4690c7d97c5SJed Brown   PetscFunctionReturn(0);
4700c7d97c5SJed Brown }
47136e030ebSStefano Zampini /* -------------------------------------------------------------------------- */
4721e6b0712SBarry Smith 
47336e030ebSStefano Zampini #undef __FUNCT__
474da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC"
4751a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode)
47636e030ebSStefano Zampini {
47736e030ebSStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
478da1bb401SStefano Zampini   PCBDDCGraph    mat_graph = pcbddc->mat_graph;
479da1bb401SStefano Zampini   PetscErrorCode ierr;
48036e030ebSStefano Zampini 
48136e030ebSStefano Zampini   PetscFunctionBegin;
482674ae819SStefano Zampini   /* free old CSR */
483674ae819SStefano Zampini   ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr);
484fb223d50SStefano Zampini   /* TODO: PCBDDCGraphSetAdjacency */
485674ae819SStefano Zampini   /* get CSR into graph structure */
486da1bb401SStefano Zampini   if (copymode == PETSC_COPY_VALUES) {
487674ae819SStefano Zampini     ierr = PetscMalloc((nvtxs+1)*sizeof(PetscInt),&mat_graph->xadj);CHKERRQ(ierr);
488674ae819SStefano Zampini     ierr = PetscMalloc(xadj[nvtxs]*sizeof(PetscInt),&mat_graph->adjncy);CHKERRQ(ierr);
489674ae819SStefano Zampini     ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr);
490674ae819SStefano Zampini     ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr);
491da1bb401SStefano Zampini   } else if (copymode == PETSC_OWN_POINTER) {
4921a83f524SJed Brown     mat_graph->xadj = (PetscInt*)xadj;
4931a83f524SJed Brown     mat_graph->adjncy = (PetscInt*)adjncy;
494674ae819SStefano Zampini   }
495575ad6abSStefano Zampini   mat_graph->nvtxs_csr = nvtxs;
49636e030ebSStefano Zampini   PetscFunctionReturn(0);
49736e030ebSStefano Zampini }
4981e6b0712SBarry Smith 
49936e030ebSStefano Zampini #undef __FUNCT__
500da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph"
50136e030ebSStefano Zampini /*@
50228509bceSStefano Zampini  PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local Neumann matrix
50336e030ebSStefano Zampini 
50436e030ebSStefano Zampini    Not collective
50536e030ebSStefano Zampini 
50636e030ebSStefano Zampini    Input Parameters:
50736e030ebSStefano Zampini +  pc - the preconditioning context
50828509bceSStefano Zampini .  nvtxs - number of local vertices of the graph (i.e., the local size of your problem)
50928509bceSStefano Zampini .  xadj, adjncy - the CSR graph
51028509bceSStefano Zampini -  copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER.
51136e030ebSStefano Zampini 
51236e030ebSStefano Zampini    Level: intermediate
51336e030ebSStefano Zampini 
51436e030ebSStefano Zampini    Notes:
51536e030ebSStefano Zampini 
51628509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode
51736e030ebSStefano Zampini @*/
5181a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode)
51936e030ebSStefano Zampini {
520575ad6abSStefano Zampini   void (*f)(void) = 0;
52136e030ebSStefano Zampini   PetscErrorCode ierr;
52236e030ebSStefano Zampini 
52336e030ebSStefano Zampini   PetscFunctionBegin;
52436e030ebSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
525674ae819SStefano Zampini   PetscValidIntPointer(xadj,3);
526674ae819SStefano Zampini   PetscValidIntPointer(xadj,4);
527674ae819SStefano Zampini   if (copymode != PETSC_COPY_VALUES && copymode != PETSC_OWN_POINTER) {
528674ae819SStefano Zampini     SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d in %s\n",copymode,__FUNCT__);
529da1bb401SStefano Zampini   }
53036e030ebSStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr);
531575ad6abSStefano Zampini   /* free arrays if PCBDDC is not the PC type */
532575ad6abSStefano Zampini   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr);
533575ad6abSStefano Zampini   if (!f && copymode == PETSC_OWN_POINTER) {
534575ad6abSStefano Zampini     ierr = PetscFree(xadj);CHKERRQ(ierr);
535575ad6abSStefano Zampini     ierr = PetscFree(adjncy);CHKERRQ(ierr);
53636e030ebSStefano Zampini   }
53736e030ebSStefano Zampini   PetscFunctionReturn(0);
53836e030ebSStefano Zampini }
5399c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */
5401e6b0712SBarry Smith 
5419c0446d6SStefano Zampini #undef __FUNCT__
5429c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC"
5439c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[])
5449c0446d6SStefano Zampini {
5459c0446d6SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
5469c0446d6SStefano Zampini   PetscInt i;
5479c0446d6SStefano Zampini   PetscErrorCode ierr;
5489c0446d6SStefano Zampini 
5499c0446d6SStefano Zampini   PetscFunctionBegin;
550da1bb401SStefano Zampini   /* Destroy ISes if they were already set */
5519c0446d6SStefano Zampini   for (i=0;i<pcbddc->n_ISForDofs;i++) {
5529c0446d6SStefano Zampini     ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr);
5539c0446d6SStefano Zampini   }
554d11ae9bbSstefano_zampini   ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr);
555da1bb401SStefano Zampini   /* allocate space then set */
5569c0446d6SStefano Zampini   ierr = PetscMalloc(n_is*sizeof(IS),&pcbddc->ISForDofs);CHKERRQ(ierr);
5579c0446d6SStefano Zampini   for (i=0;i<n_is;i++) {
558da1bb401SStefano Zampini     ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr);
559da1bb401SStefano Zampini     pcbddc->ISForDofs[i]=ISForDofs[i];
5609c0446d6SStefano Zampini   }
5619c0446d6SStefano Zampini   pcbddc->n_ISForDofs=n_is;
56260d44989SStefano Zampini   pcbddc->user_provided_isfordofs = PETSC_TRUE;
5639c0446d6SStefano Zampini   PetscFunctionReturn(0);
5649c0446d6SStefano Zampini }
5651e6b0712SBarry Smith 
5669c0446d6SStefano Zampini #undef __FUNCT__
5679c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting"
5689c0446d6SStefano Zampini /*@
56928509bceSStefano Zampini  PCBDDCSetDofsSplitting - Set index sets defining fields of the local Neumann matrix
5709c0446d6SStefano Zampini 
5719c0446d6SStefano Zampini    Not collective
5729c0446d6SStefano Zampini 
5739c0446d6SStefano Zampini    Input Parameters:
5749c0446d6SStefano Zampini +  pc - the preconditioning context
57528509bceSStefano Zampini -  n_is - number of index sets defining the fields
57628509bceSStefano Zampini .  ISForDofs - array of IS describing the fields
5779c0446d6SStefano Zampini 
5789c0446d6SStefano Zampini    Level: intermediate
5799c0446d6SStefano Zampini 
5809c0446d6SStefano Zampini    Notes:
5819c0446d6SStefano Zampini 
5829c0446d6SStefano Zampini .seealso: PCBDDC
5839c0446d6SStefano Zampini @*/
5849c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[])
5859c0446d6SStefano Zampini {
5862b510759SStefano Zampini   PetscInt       i;
5879c0446d6SStefano Zampini   PetscErrorCode ierr;
5889c0446d6SStefano Zampini 
5899c0446d6SStefano Zampini   PetscFunctionBegin;
5909c0446d6SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
5912b510759SStefano Zampini   for (i=0;i<n_is;i++) {
5922b510759SStefano Zampini     PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,2);
5932b510759SStefano Zampini   }
5949c0446d6SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr);
5959c0446d6SStefano Zampini   PetscFunctionReturn(0);
5969c0446d6SStefano Zampini }
597da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */
598534831adSStefano Zampini #undef __FUNCT__
599534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC"
600534831adSStefano Zampini /* -------------------------------------------------------------------------- */
601534831adSStefano Zampini /*
602534831adSStefano Zampini    PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial
603534831adSStefano Zampini                      guess if a transformation of basis approach has been selected.
6049c0446d6SStefano Zampini 
605534831adSStefano Zampini    Input Parameter:
606534831adSStefano Zampini +  pc - the preconditioner contex
607534831adSStefano Zampini 
608534831adSStefano Zampini    Application Interface Routine: PCPreSolve()
609534831adSStefano Zampini 
610534831adSStefano Zampini    Notes:
611534831adSStefano Zampini    The interface routine PCPreSolve() is not usually called directly by
612534831adSStefano Zampini    the user, but instead is called by KSPSolve().
613534831adSStefano Zampini */
614534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x)
615534831adSStefano Zampini {
616534831adSStefano Zampini   PetscErrorCode ierr;
617534831adSStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
618534831adSStefano Zampini   PC_IS          *pcis = (PC_IS*)(pc->data);
619534831adSStefano Zampini   Mat_IS         *matis = (Mat_IS*)pc->pmat->data;
620534831adSStefano Zampini   Mat            temp_mat;
6213972b0daSStefano Zampini   IS             dirIS;
6223972b0daSStefano Zampini   PetscInt       dirsize,i,*is_indices;
6233972b0daSStefano Zampini   PetscScalar    *array_x,*array_diagonal;
6243972b0daSStefano Zampini   Vec            used_vec;
625*82ba6b80SStefano Zampini   PetscBool      guess_nonzero;
626534831adSStefano Zampini 
627534831adSStefano Zampini   PetscFunctionBegin;
62885c4d303SStefano Zampini   /* if we are working with cg, one dirichlet solve can be avoided during Krylov iterations */
62985c4d303SStefano Zampini   if (ksp) {
63085c4d303SStefano Zampini     PetscBool iscg;
63185c4d303SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr);
63285c4d303SStefano Zampini     if (!iscg) {
63385c4d303SStefano Zampini       ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr);
63485c4d303SStefano Zampini     }
63585c4d303SStefano Zampini   }
63685c4d303SStefano Zampini   /* Creates parallel work vectors used in presolve */
63762a6ff1dSStefano Zampini   if (!pcbddc->original_rhs) {
63862a6ff1dSStefano Zampini     ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr);
63962a6ff1dSStefano Zampini   }
64062a6ff1dSStefano Zampini   if (!pcbddc->temp_solution) {
64162a6ff1dSStefano Zampini     ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr);
64262a6ff1dSStefano Zampini   }
6433972b0daSStefano Zampini   if (x) {
6443972b0daSStefano Zampini     ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);
6453972b0daSStefano Zampini     used_vec = x;
6463972b0daSStefano Zampini   } else {
6473972b0daSStefano Zampini     ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr);
6483972b0daSStefano Zampini     used_vec = pcbddc->temp_solution;
6493972b0daSStefano Zampini     ierr = VecSet(used_vec,0.0);CHKERRQ(ierr);
6503972b0daSStefano Zampini   }
6513972b0daSStefano Zampini   /* hack into ksp data structure PCPreSolve comes earlier in src/ksp/ksp/interface/itfunc.c */
6523972b0daSStefano Zampini   if (ksp) {
6533972b0daSStefano Zampini     ierr = KSPGetInitialGuessNonzero(ksp,&guess_nonzero);CHKERRQ(ierr);
6543972b0daSStefano Zampini     if (!guess_nonzero) {
6553972b0daSStefano Zampini       ierr = VecSet(used_vec,0.0);CHKERRQ(ierr);
6563972b0daSStefano Zampini     }
6573972b0daSStefano Zampini   }
6583308cffdSStefano Zampini 
6593972b0daSStefano Zampini   /* store the original rhs */
6603972b0daSStefano Zampini   ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr);
6613972b0daSStefano Zampini 
6623972b0daSStefano Zampini   /* Take into account zeroed rows -> change rhs and store solution removed */
663*82ba6b80SStefano Zampini   ierr = PCBDDCGetDirichletBoundariesLocal(pc,&dirIS);CHKERRQ(ierr);
664*82ba6b80SStefano Zampini   if (rhs && dirIS) {
6653972b0daSStefano Zampini     ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr);
6663972b0daSStefano Zampini     ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr);
6673972b0daSStefano Zampini     ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
6683972b0daSStefano Zampini     ierr = VecScatterEnd(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
6693972b0daSStefano Zampini     ierr = VecScatterBegin(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
6703972b0daSStefano Zampini     ierr = VecScatterEnd(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
671*82ba6b80SStefano Zampini     ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr);
6723972b0daSStefano Zampini     ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr);
6733972b0daSStefano Zampini     ierr = VecGetArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr);
6743972b0daSStefano Zampini     ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr);
6752fa5cd67SKarl Rupp     for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]];
6763972b0daSStefano Zampini     ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr);
6773972b0daSStefano Zampini     ierr = VecRestoreArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr);
6783972b0daSStefano Zampini     ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr);
6793972b0daSStefano Zampini     ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
6803972b0daSStefano Zampini     ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
681b76ba322SStefano Zampini 
6823972b0daSStefano Zampini     /* remove the computed solution from the rhs */
6833972b0daSStefano Zampini     ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr);
6843972b0daSStefano Zampini     ierr = MatMultAdd(pc->pmat,used_vec,rhs,rhs);CHKERRQ(ierr);
6853972b0daSStefano Zampini     ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr);
6863308cffdSStefano Zampini   }
687b76ba322SStefano Zampini 
688b76ba322SStefano Zampini   /* store partially computed solution and set initial guess */
6893972b0daSStefano Zampini   if (x) {
6903972b0daSStefano Zampini     ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr);
6913972b0daSStefano Zampini     ierr = VecSet(used_vec,0.0);CHKERRQ(ierr);
69285c4d303SStefano Zampini     if (pcbddc->use_exact_dirichlet_trick) {
693b76ba322SStefano Zampini       ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
694b76ba322SStefano Zampini       ierr = VecScatterEnd  (pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
695b76ba322SStefano Zampini       ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr);
696b76ba322SStefano Zampini       ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
697b76ba322SStefano Zampini       ierr = VecScatterEnd  (pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
698b76ba322SStefano Zampini       if (ksp) {
699b76ba322SStefano Zampini         ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr);
700b76ba322SStefano Zampini       }
701b76ba322SStefano Zampini     }
7023972b0daSStefano Zampini   }
703b76ba322SStefano Zampini 
70492e3dcfbSStefano Zampini   /* prepare MatMult and rhs for solver */
705674ae819SStefano Zampini   if (pcbddc->use_change_of_basis) {
706b76ba322SStefano Zampini     /* swap pointers for local matrices */
707b76ba322SStefano Zampini     temp_mat = matis->A;
708b76ba322SStefano Zampini     matis->A = pcbddc->local_mat;
709b76ba322SStefano Zampini     pcbddc->local_mat = temp_mat;
71092e3dcfbSStefano Zampini     if (rhs) {
711b76ba322SStefano Zampini       /* Get local rhs and apply transformation of basis */
712b76ba322SStefano Zampini       ierr = VecScatterBegin(pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
713b76ba322SStefano Zampini       ierr = VecScatterEnd  (pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
714b76ba322SStefano Zampini       /* from original basis to modified basis */
715b76ba322SStefano Zampini       ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr);
716b76ba322SStefano Zampini       /* put back modified values into the global vec using INSERT_VALUES copy mode */
717b76ba322SStefano Zampini       ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
718b76ba322SStefano Zampini       ierr = VecScatterEnd  (pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
719674ae819SStefano Zampini     }
72092e3dcfbSStefano Zampini   }
72192e3dcfbSStefano Zampini 
72292e3dcfbSStefano Zampini   /* remove nullspace if present */
7230bdf917eSStefano Zampini   if (ksp && pcbddc->NullSpace) {
724d0195637SJed Brown     ierr = MatNullSpaceRemove(pcbddc->NullSpace,used_vec);CHKERRQ(ierr);
725d0195637SJed Brown     ierr = MatNullSpaceRemove(pcbddc->NullSpace,rhs);CHKERRQ(ierr);
726b76ba322SStefano Zampini   }
7270bdf917eSStefano Zampini   ierr = VecDestroy(&used_vec);CHKERRQ(ierr);
728534831adSStefano Zampini   PetscFunctionReturn(0);
729534831adSStefano Zampini }
730534831adSStefano Zampini /* -------------------------------------------------------------------------- */
731534831adSStefano Zampini #undef __FUNCT__
732534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC"
733534831adSStefano Zampini /* -------------------------------------------------------------------------- */
734534831adSStefano Zampini /*
735534831adSStefano Zampini    PCPostSolve_BDDC - Changes the computed solution if a transformation of basis
736534831adSStefano Zampini                      approach has been selected. Also, restores rhs to its original state.
737534831adSStefano Zampini 
738534831adSStefano Zampini    Input Parameter:
739534831adSStefano Zampini +  pc - the preconditioner contex
740534831adSStefano Zampini 
741534831adSStefano Zampini    Application Interface Routine: PCPostSolve()
742534831adSStefano Zampini 
743534831adSStefano Zampini    Notes:
744534831adSStefano Zampini    The interface routine PCPostSolve() is not usually called directly by
745534831adSStefano Zampini    the user, but instead is called by KSPSolve().
746534831adSStefano Zampini */
747534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x)
748534831adSStefano Zampini {
749534831adSStefano Zampini   PetscErrorCode ierr;
750534831adSStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
751534831adSStefano Zampini   PC_IS          *pcis   = (PC_IS*)(pc->data);
752534831adSStefano Zampini   Mat_IS         *matis = (Mat_IS*)pc->pmat->data;
753534831adSStefano Zampini   Mat            temp_mat;
754534831adSStefano Zampini 
755534831adSStefano Zampini   PetscFunctionBegin;
756674ae819SStefano Zampini   if (pcbddc->use_change_of_basis) {
757534831adSStefano Zampini     /* swap pointers for local matrices */
758534831adSStefano Zampini     temp_mat = matis->A;
759534831adSStefano Zampini     matis->A = pcbddc->local_mat;
760534831adSStefano Zampini     pcbddc->local_mat = temp_mat;
7613425bc38SStefano Zampini   }
7623308cffdSStefano Zampini   if (pcbddc->use_change_of_basis && x) {
763534831adSStefano Zampini     /* Get Local boundary and apply transformation of basis to solution vector */
764534831adSStefano Zampini     ierr = VecScatterBegin(pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
765534831adSStefano Zampini     ierr = VecScatterEnd  (pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
766534831adSStefano Zampini     /* from modified basis to original basis */
767534831adSStefano Zampini     ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr);
768534831adSStefano Zampini     /* put back modified values into the global vec using INSERT_VALUES copy mode */
769534831adSStefano Zampini     ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
770534831adSStefano Zampini     ierr = VecScatterEnd  (pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
771534831adSStefano Zampini   }
7723972b0daSStefano Zampini   /* add solution removed in presolve */
7733425bc38SStefano Zampini   if (x) {
7743425bc38SStefano Zampini     ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr);
7753425bc38SStefano Zampini   }
776fb223d50SStefano Zampini   /* restore rhs to its original state */
777fb223d50SStefano Zampini   if (rhs) {
778fb223d50SStefano Zampini     ierr = VecCopy(pcbddc->original_rhs,rhs);CHKERRQ(ierr);
779fb223d50SStefano Zampini   }
780534831adSStefano Zampini   PetscFunctionReturn(0);
781534831adSStefano Zampini }
782534831adSStefano Zampini /* -------------------------------------------------------------------------- */
78353cdbc3dSStefano Zampini #undef __FUNCT__
78453cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC"
7850c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
7860c7d97c5SJed Brown /*
7870c7d97c5SJed Brown    PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner
7880c7d97c5SJed Brown                   by setting data structures and options.
7890c7d97c5SJed Brown 
7900c7d97c5SJed Brown    Input Parameter:
79153cdbc3dSStefano Zampini +  pc - the preconditioner context
7920c7d97c5SJed Brown 
7930c7d97c5SJed Brown    Application Interface Routine: PCSetUp()
7940c7d97c5SJed Brown 
7950c7d97c5SJed Brown    Notes:
7960c7d97c5SJed Brown    The interface routine PCSetUp() is not usually called directly by
7970c7d97c5SJed Brown    the user, but instead is called by PCApply() if necessary.
7980c7d97c5SJed Brown */
79953cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc)
8000c7d97c5SJed Brown {
8010c7d97c5SJed Brown   PetscErrorCode ierr;
8020c7d97c5SJed Brown   PC_BDDC*       pcbddc = (PC_BDDC*)pc->data;
803674ae819SStefano Zampini   MatStructure   flag;
804674ae819SStefano Zampini   PetscBool      computeis,computetopography,computesolvers;
8050c7d97c5SJed Brown 
8060c7d97c5SJed Brown   PetscFunctionBegin;
807674ae819SStefano Zampini   /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other nonoverlapping preconditioners */
808fcd409f5SStefano Zampini   /* PCIS does not support MatStructures different from SAME_PRECONDITIONER */
8093b03a366Sstefano_zampini   /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup
810fcd409f5SStefano Zampini      Also, BDDC directly build the Dirichlet problem */
8113b03a366Sstefano_zampini   /* Get stdout for dbg */
812674ae819SStefano Zampini   if (pcbddc->dbg_flag && !pcbddc->dbg_viewer) {
813ce94432eSBarry Smith     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pc),&pcbddc->dbg_viewer);CHKERRQ(ierr);
814e269702eSStefano Zampini     ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr);
8152b510759SStefano Zampini     if (pcbddc->current_level) {
8162b510759SStefano Zampini       ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2);CHKERRQ(ierr);
8172b510759SStefano Zampini     }
818e269702eSStefano Zampini   }
819674ae819SStefano Zampini   /* first attempt to split work */
820674ae819SStefano Zampini   if (pc->setupcalled) {
821674ae819SStefano Zampini     computeis = PETSC_FALSE;
822674ae819SStefano Zampini     ierr = PCGetOperators(pc,NULL,NULL,&flag);CHKERRQ(ierr);
823674ae819SStefano Zampini     if (flag == SAME_PRECONDITIONER) {
824674ae819SStefano Zampini       computetopography = PETSC_FALSE;
825674ae819SStefano Zampini       computesolvers = PETSC_FALSE;
826674ae819SStefano Zampini     } else if (flag == SAME_NONZERO_PATTERN) {
827674ae819SStefano Zampini       computetopography = PETSC_FALSE;
828674ae819SStefano Zampini       computesolvers = PETSC_TRUE;
829674ae819SStefano Zampini     } else { /* DIFFERENT_NONZERO_PATTERN */
830674ae819SStefano Zampini       computetopography = PETSC_TRUE;
831674ae819SStefano Zampini       computesolvers = PETSC_TRUE;
832674ae819SStefano Zampini     }
833674ae819SStefano Zampini   } else {
834674ae819SStefano Zampini     computeis = PETSC_TRUE;
835674ae819SStefano Zampini     computetopography = PETSC_TRUE;
836674ae819SStefano Zampini     computesolvers = PETSC_TRUE;
837674ae819SStefano Zampini   }
838fcd409f5SStefano Zampini   /* Set up all the "iterative substructuring" common block without computing solvers */
839674ae819SStefano Zampini   if (computeis) {
840fcd409f5SStefano Zampini     /* HACK INTO PCIS */
841fcd409f5SStefano Zampini     PC_IS* pcis = (PC_IS*)pc->data;
842fcd409f5SStefano Zampini     pcis->computesolvers = PETSC_FALSE;
843674ae819SStefano Zampini     ierr = PCISSetUp(pc);CHKERRQ(ierr);
844674ae819SStefano Zampini   }
845674ae819SStefano Zampini   /* Analyze interface and set up local constraint and change of basis matrices */
846674ae819SStefano Zampini   if (computetopography) {
847674ae819SStefano Zampini     /* reset data */
848674ae819SStefano Zampini     ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr);
849674ae819SStefano Zampini     ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr);
850674ae819SStefano Zampini     ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr);
851674ae819SStefano Zampini   }
852674ae819SStefano Zampini   if (computesolvers) {
853674ae819SStefano Zampini     /* reset data */
854674ae819SStefano Zampini     ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr);
855674ae819SStefano Zampini     ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr);
85699cc7994SStefano Zampini     /* Create coarse and local stuffs */
85799cc7994SStefano Zampini     ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr);
858674ae819SStefano Zampini     ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr);
8590c7d97c5SJed Brown   }
8602b510759SStefano Zampini   if (pcbddc->dbg_flag && pcbddc->current_level) {
8612b510759SStefano Zampini     ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2);CHKERRQ(ierr);
8622b510759SStefano Zampini   }
8630c7d97c5SJed Brown   PetscFunctionReturn(0);
8640c7d97c5SJed Brown }
8650c7d97c5SJed Brown 
8660c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
8670c7d97c5SJed Brown /*
8680c7d97c5SJed Brown    PCApply_BDDC - Applies the BDDC preconditioner to a vector.
8690c7d97c5SJed Brown 
8700c7d97c5SJed Brown    Input Parameters:
8710c7d97c5SJed Brown .  pc - the preconditioner context
8720c7d97c5SJed Brown .  r - input vector (global)
8730c7d97c5SJed Brown 
8740c7d97c5SJed Brown    Output Parameter:
8750c7d97c5SJed Brown .  z - output vector (global)
8760c7d97c5SJed Brown 
8770c7d97c5SJed Brown    Application Interface Routine: PCApply()
8780c7d97c5SJed Brown  */
8790c7d97c5SJed Brown #undef __FUNCT__
8800c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC"
88153cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z)
8820c7d97c5SJed Brown {
8830c7d97c5SJed Brown   PC_IS             *pcis = (PC_IS*)(pc->data);
8840c7d97c5SJed Brown   PC_BDDC           *pcbddc = (PC_BDDC*)(pc->data);
8850c7d97c5SJed Brown   PetscErrorCode    ierr;
8863b03a366Sstefano_zampini   const PetscScalar one = 1.0;
8873b03a366Sstefano_zampini   const PetscScalar m_one = -1.0;
8882617d88aSStefano Zampini   const PetscScalar zero = 0.0;
8890c7d97c5SJed Brown 
8900c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN
8910c7d97c5SJed Brown    NN interface preconditioner changed to BDDC
8928eeda7d8SStefano Zampini    Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static = PETSC_TRUE) */
8930c7d97c5SJed Brown 
8940c7d97c5SJed Brown   PetscFunctionBegin;
89585c4d303SStefano Zampini   if (!pcbddc->use_exact_dirichlet_trick) {
8960c7d97c5SJed Brown     /* First Dirichlet solve */
8970c7d97c5SJed Brown     ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
8980c7d97c5SJed Brown     ierr = VecScatterEnd  (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
89953cdbc3dSStefano Zampini     ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr);
9000c7d97c5SJed Brown     /*
9010c7d97c5SJed Brown       Assembling right hand side for BDDC operator
902674ae819SStefano Zampini       - pcis->vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE)
903674ae819SStefano Zampini       - pcis->vec1_B the interface part of the global vector z
9040c7d97c5SJed Brown     */
9050c7d97c5SJed Brown     ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr);
9060c7d97c5SJed Brown     ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr);
9078eeda7d8SStefano Zampini     if (pcbddc->switch_static) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); }
9080c7d97c5SJed Brown     ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr);
9090c7d97c5SJed Brown     ierr = VecCopy(r,z);CHKERRQ(ierr);
9100c7d97c5SJed Brown     ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
9110c7d97c5SJed Brown     ierr = VecScatterEnd  (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
912674ae819SStefano Zampini     ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr);
913b76ba322SStefano Zampini   } else {
9140bdf917eSStefano Zampini     ierr = VecSet(pcis->vec1_D,zero);CHKERRQ(ierr);
915b76ba322SStefano Zampini     ierr = VecSet(pcis->vec2_D,zero);CHKERRQ(ierr);
916674ae819SStefano Zampini     ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr);
917b76ba322SStefano Zampini   }
918b76ba322SStefano Zampini 
9192617d88aSStefano Zampini   /* Apply interface preconditioner
9202617d88aSStefano Zampini      input/output vecs: pcis->vec1_B and pcis->vec1_D */
9212617d88aSStefano Zampini   ierr = PCBDDCApplyInterfacePreconditioner(pc);CHKERRQ(ierr);
9222617d88aSStefano Zampini 
923674ae819SStefano Zampini   /* Apply transpose of partition of unity operator */
924674ae819SStefano Zampini   ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr);
9250c7d97c5SJed Brown 
9263b03a366Sstefano_zampini   /* Second Dirichlet solve and assembling of output */
9270c7d97c5SJed Brown   ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
9280c7d97c5SJed Brown   ierr = VecScatterEnd  (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
9290c7d97c5SJed Brown   ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr);
9308eeda7d8SStefano Zampini   if (pcbddc->switch_static) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); }
93153cdbc3dSStefano Zampini   ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr);
9320c7d97c5SJed Brown   ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr);
9338eeda7d8SStefano Zampini   if (pcbddc->switch_static) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); }
9340c7d97c5SJed Brown   ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr);
9350c7d97c5SJed Brown   ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
9360c7d97c5SJed Brown   ierr = VecScatterEnd  (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
9370c7d97c5SJed Brown   PetscFunctionReturn(0);
9380c7d97c5SJed Brown }
939da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */
940674ae819SStefano Zampini 
941da1bb401SStefano Zampini #undef __FUNCT__
942da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC"
943da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc)
944da1bb401SStefano Zampini {
945da1bb401SStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
946da1bb401SStefano Zampini   PetscErrorCode ierr;
947da1bb401SStefano Zampini 
948da1bb401SStefano Zampini   PetscFunctionBegin;
949da1bb401SStefano Zampini   /* free data created by PCIS */
950da1bb401SStefano Zampini   ierr = PCISDestroy(pc);CHKERRQ(ierr);
951674ae819SStefano Zampini   /* free BDDC custom data  */
952674ae819SStefano Zampini   ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr);
953674ae819SStefano Zampini   /* destroy objects related to topography */
954674ae819SStefano Zampini   ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr);
955674ae819SStefano Zampini   /* free allocated graph structure */
956da1bb401SStefano Zampini   ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr);
957674ae819SStefano Zampini   /* free data for scaling operator */
958674ae819SStefano Zampini   ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr);
959674ae819SStefano Zampini   /* free solvers stuff */
960674ae819SStefano Zampini   ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr);
96133bc96a4SStefano Zampini   ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr);
96233bc96a4SStefano Zampini   ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr);
9639881197aSStefano Zampini   ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr);
964ac78edfcSStefano Zampini   ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr);
96562a6ff1dSStefano Zampini   /* free global vectors needed in presolve */
96662a6ff1dSStefano Zampini   ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr);
96762a6ff1dSStefano Zampini   ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr);
9683425bc38SStefano Zampini   /* remove functions */
969674ae819SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr);
970bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr);
9712b510759SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr);
972b8ffe317SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr);
9732b510759SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr);
974bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",NULL);CHKERRQ(ierr);
975*82ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr);
976*82ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr);
977*82ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr);
978*82ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_LocalC",NULL);CHKERRQ(ierr);
979bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr);
980bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr);
981bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr);
982bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr);
983bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr);
984674ae819SStefano Zampini   /* Free the private data structure */
985674ae819SStefano Zampini   ierr = PetscFree(pc->data);CHKERRQ(ierr);
986da1bb401SStefano Zampini   PetscFunctionReturn(0);
987da1bb401SStefano Zampini }
9883425bc38SStefano Zampini /* -------------------------------------------------------------------------- */
9891e6b0712SBarry Smith 
9903425bc38SStefano Zampini #undef __FUNCT__
9913425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC"
9923425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs)
9933425bc38SStefano Zampini {
994674ae819SStefano Zampini   FETIDPMat_ctx  mat_ctx;
9953425bc38SStefano Zampini   PC_IS*         pcis;
9963425bc38SStefano Zampini   PC_BDDC*       pcbddc;
9973425bc38SStefano Zampini   PetscErrorCode ierr;
9980c7d97c5SJed Brown 
9993425bc38SStefano Zampini   PetscFunctionBegin;
10003425bc38SStefano Zampini   ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr);
10013425bc38SStefano Zampini   pcis = (PC_IS*)mat_ctx->pc->data;
10023425bc38SStefano Zampini   pcbddc = (PC_BDDC*)mat_ctx->pc->data;
10033425bc38SStefano Zampini 
10043425bc38SStefano Zampini   /* change of basis for physical rhs if needed
10053425bc38SStefano Zampini      It also changes the rhs in case of dirichlet boundaries */
10063308cffdSStefano Zampini   ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,standard_rhs,NULL);CHKERRQ(ierr);
10073425bc38SStefano Zampini   /* store vectors for computation of fetidp final solution */
10083425bc38SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
10093425bc38SStefano Zampini   ierr = VecScatterEnd(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1010fb223d50SStefano Zampini   /* scale rhs since it should be unassembled */
1011fb223d50SStefano Zampini   /* TODO use counter scaling? (also below) */
10123425bc38SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
10133425bc38SStefano Zampini   ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1014674ae819SStefano Zampini   /* Apply partition of unity */
10153425bc38SStefano Zampini   ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr);
1016674ae819SStefano Zampini   /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */
10178eeda7d8SStefano Zampini   if (!pcbddc->switch_static) {
10183425bc38SStefano Zampini     /* compute partially subassembled Schur complement right-hand side */
10193425bc38SStefano Zampini     ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr);
10203425bc38SStefano Zampini     ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr);
10213425bc38SStefano Zampini     ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr);
10223425bc38SStefano Zampini     ierr = VecSet(standard_rhs,0.0);CHKERRQ(ierr);
10233425bc38SStefano Zampini     ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
10243425bc38SStefano Zampini     ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1025674ae819SStefano Zampini     /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */
10263425bc38SStefano Zampini     ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
10273425bc38SStefano Zampini     ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
10283425bc38SStefano Zampini     ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr);
10293425bc38SStefano Zampini   }
10303425bc38SStefano Zampini   /* BDDC rhs */
10313425bc38SStefano Zampini   ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr);
10328eeda7d8SStefano Zampini   if (pcbddc->switch_static) {
10333425bc38SStefano Zampini     ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr);
10343425bc38SStefano Zampini   }
10353425bc38SStefano Zampini   /* apply BDDC */
10363425bc38SStefano Zampini   ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr);
10373425bc38SStefano Zampini   /* Application of B_delta and assembling of rhs for fetidp fluxes */
10383425bc38SStefano Zampini   ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr);
10393425bc38SStefano Zampini   ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr);
10403425bc38SStefano Zampini   ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
10413425bc38SStefano Zampini   ierr = VecScatterEnd  (mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
10423425bc38SStefano Zampini   /* restore original rhs */
10433425bc38SStefano Zampini   ierr = VecCopy(pcbddc->original_rhs,standard_rhs);CHKERRQ(ierr);
10443425bc38SStefano Zampini   PetscFunctionReturn(0);
10453425bc38SStefano Zampini }
10461e6b0712SBarry Smith 
10473425bc38SStefano Zampini #undef __FUNCT__
10483425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS"
10493425bc38SStefano Zampini /*@
105028509bceSStefano Zampini  PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETIDP linear system
10513425bc38SStefano Zampini 
10523425bc38SStefano Zampini    Collective
10533425bc38SStefano Zampini 
10543425bc38SStefano Zampini    Input Parameters:
105528509bceSStefano Zampini +  fetidp_mat   - the FETIDP matrix object obtained by calling PCBDDCCreateFETIDPOperators
105628509bceSStefano Zampini .  standard_rhs - the right-hand side for your linear system
10573425bc38SStefano Zampini 
10583425bc38SStefano Zampini    Output Parameters:
105928509bceSStefano Zampini -  fetidp_flux_rhs   - the right-hand side for the FETIDP linear system
10603425bc38SStefano Zampini 
10613425bc38SStefano Zampini    Level: developer
10623425bc38SStefano Zampini 
10633425bc38SStefano Zampini    Notes:
10643425bc38SStefano Zampini 
106528509bceSStefano Zampini .seealso: PCBDDC,PCBDDCCreateFETIDPOperators
10663425bc38SStefano Zampini @*/
10673425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs)
10683425bc38SStefano Zampini {
1069674ae819SStefano Zampini   FETIDPMat_ctx  mat_ctx;
10703425bc38SStefano Zampini   PetscErrorCode ierr;
10713425bc38SStefano Zampini 
10723425bc38SStefano Zampini   PetscFunctionBegin;
10733425bc38SStefano Zampini   ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr);
10743425bc38SStefano Zampini   ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr);
10753425bc38SStefano Zampini   PetscFunctionReturn(0);
10763425bc38SStefano Zampini }
10773425bc38SStefano Zampini /* -------------------------------------------------------------------------- */
10781e6b0712SBarry Smith 
10793425bc38SStefano Zampini #undef __FUNCT__
10803425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC"
10813425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol)
10823425bc38SStefano Zampini {
1083674ae819SStefano Zampini   FETIDPMat_ctx  mat_ctx;
10843425bc38SStefano Zampini   PC_IS*         pcis;
10853425bc38SStefano Zampini   PC_BDDC*       pcbddc;
10863425bc38SStefano Zampini   PetscErrorCode ierr;
10873425bc38SStefano Zampini 
10883425bc38SStefano Zampini   PetscFunctionBegin;
10893425bc38SStefano Zampini   ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr);
10903425bc38SStefano Zampini   pcis = (PC_IS*)mat_ctx->pc->data;
10913425bc38SStefano Zampini   pcbddc = (PC_BDDC*)mat_ctx->pc->data;
10923425bc38SStefano Zampini 
10933425bc38SStefano Zampini   /* apply B_delta^T */
10943425bc38SStefano Zampini   ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
10953425bc38SStefano Zampini   ierr = VecScatterEnd  (mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
10963425bc38SStefano Zampini   ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr);
10973425bc38SStefano Zampini   /* compute rhs for BDDC application */
10983425bc38SStefano Zampini   ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr);
10998eeda7d8SStefano Zampini   if (pcbddc->switch_static) {
11003425bc38SStefano Zampini     ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr);
11013425bc38SStefano Zampini   }
11023425bc38SStefano Zampini   /* apply BDDC */
11033425bc38SStefano Zampini   ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr);
11043425bc38SStefano Zampini   /* put values into standard global vector */
11053425bc38SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
11063425bc38SStefano Zampini   ierr = VecScatterEnd  (pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
11078eeda7d8SStefano Zampini   if (!pcbddc->switch_static) {
11083425bc38SStefano Zampini     /* compute values into the interior if solved for the partially subassembled Schur complement */
11093425bc38SStefano Zampini     ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr);
11103425bc38SStefano Zampini     ierr = VecAXPY(mat_ctx->temp_solution_D,-1.0,pcis->vec1_D);CHKERRQ(ierr);
11113425bc38SStefano Zampini     ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr);
11123425bc38SStefano Zampini   }
11133425bc38SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
11143425bc38SStefano Zampini   ierr = VecScatterEnd  (pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
11153425bc38SStefano Zampini   /* final change of basis if needed
11163425bc38SStefano Zampini      Is also sums the dirichlet part removed during RHS assembling */
11173308cffdSStefano Zampini   ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr);
11183425bc38SStefano Zampini   PetscFunctionReturn(0);
11193425bc38SStefano Zampini }
11201e6b0712SBarry Smith 
11213425bc38SStefano Zampini #undef __FUNCT__
11223425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution"
11233425bc38SStefano Zampini /*@
112428509bceSStefano Zampini  PCBDDCMatFETIDPGetSolution - Compute the physical solution from the solution of the FETIDP linear system
11253425bc38SStefano Zampini 
11263425bc38SStefano Zampini    Collective
11273425bc38SStefano Zampini 
11283425bc38SStefano Zampini    Input Parameters:
112928509bceSStefano Zampini +  fetidp_mat        - the FETIDP matrix obtained by calling PCBDDCCreateFETIDPOperators
113028509bceSStefano Zampini .  fetidp_flux_sol - the solution of the FETIDP linear system
11313425bc38SStefano Zampini 
11323425bc38SStefano Zampini    Output Parameters:
113328509bceSStefano Zampini -  standard_sol      - the solution defined on the physical domain
11343425bc38SStefano Zampini 
11353425bc38SStefano Zampini    Level: developer
11363425bc38SStefano Zampini 
11373425bc38SStefano Zampini    Notes:
11383425bc38SStefano Zampini 
113928509bceSStefano Zampini .seealso: PCBDDC,PCBDDCCreateFETIDPOperators
11403425bc38SStefano Zampini @*/
11413425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol)
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,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr);
11493425bc38SStefano Zampini   PetscFunctionReturn(0);
11503425bc38SStefano Zampini }
11513425bc38SStefano Zampini /* -------------------------------------------------------------------------- */
11521e6b0712SBarry Smith 
1153f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec);
1154f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat);
1155f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec);
1156f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC);
1157674ae819SStefano Zampini 
11583425bc38SStefano Zampini #undef __FUNCT__
11593425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC"
11603425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, Mat *fetidp_mat, PC *fetidp_pc)
11613425bc38SStefano Zampini {
1162674ae819SStefano Zampini 
1163674ae819SStefano Zampini   FETIDPMat_ctx  fetidpmat_ctx;
11643425bc38SStefano Zampini   Mat            newmat;
1165674ae819SStefano Zampini   FETIDPPC_ctx   fetidppc_ctx;
11663425bc38SStefano Zampini   PC             newpc;
1167ce94432eSBarry Smith   MPI_Comm       comm;
11683425bc38SStefano Zampini   PetscErrorCode ierr;
11693425bc38SStefano Zampini 
11703425bc38SStefano Zampini   PetscFunctionBegin;
1171ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr);
11723425bc38SStefano Zampini   /* FETIDP linear matrix */
11733425bc38SStefano Zampini   ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr);
11743425bc38SStefano Zampini   ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr);
11753425bc38SStefano Zampini   ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr);
11763425bc38SStefano Zampini   ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr);
11773425bc38SStefano Zampini   ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr);
11783425bc38SStefano Zampini   ierr = MatSetUp(newmat);CHKERRQ(ierr);
11793425bc38SStefano Zampini   /* FETIDP preconditioner */
11803425bc38SStefano Zampini   ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr);
11813425bc38SStefano Zampini   ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr);
11823425bc38SStefano Zampini   ierr = PCCreate(comm,&newpc);CHKERRQ(ierr);
11833425bc38SStefano Zampini   ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr);
11843425bc38SStefano Zampini   ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr);
11853425bc38SStefano Zampini   ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr);
11863425bc38SStefano Zampini   ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr);
11873425bc38SStefano Zampini   ierr = PCSetOperators(newpc,newmat,newmat,SAME_PRECONDITIONER);CHKERRQ(ierr);
11883425bc38SStefano Zampini   ierr = PCSetUp(newpc);CHKERRQ(ierr);
11893425bc38SStefano Zampini   /* return pointers for objects created */
11903425bc38SStefano Zampini   *fetidp_mat=newmat;
11913425bc38SStefano Zampini   *fetidp_pc=newpc;
11923425bc38SStefano Zampini   PetscFunctionReturn(0);
11933425bc38SStefano Zampini }
11941e6b0712SBarry Smith 
11953425bc38SStefano Zampini #undef __FUNCT__
11963425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators"
11973425bc38SStefano Zampini /*@
119828509bceSStefano Zampini  PCBDDCCreateFETIDPOperators - Create operators for FETIDP
11993425bc38SStefano Zampini 
12003425bc38SStefano Zampini    Collective
12013425bc38SStefano Zampini 
12023425bc38SStefano Zampini    Input Parameters:
120328509bceSStefano Zampini +  pc - the BDDC preconditioning context already setup
120428509bceSStefano Zampini 
120528509bceSStefano Zampini    Output Parameters:
120628509bceSStefano Zampini .  fetidp_mat - shell FETIDP matrix object
120728509bceSStefano Zampini .  fetidp_pc  - shell Dirichlet preconditioner for FETIDP matrix
120828509bceSStefano Zampini 
120928509bceSStefano Zampini    Options Database Keys:
121028509bceSStefano Zampini -    -fetidp_fullyredundant: use or not a fully redundant set of Lagrange multipliers
12113425bc38SStefano Zampini 
12123425bc38SStefano Zampini    Level: developer
12133425bc38SStefano Zampini 
12143425bc38SStefano Zampini    Notes:
121528509bceSStefano Zampini      Currently the only operation provided for FETIDP matrix is MatMult
12163425bc38SStefano Zampini 
12173425bc38SStefano Zampini .seealso: PCBDDC
12183425bc38SStefano Zampini @*/
12193425bc38SStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, Mat *fetidp_mat, PC *fetidp_pc)
12203425bc38SStefano Zampini {
12213425bc38SStefano Zampini   PetscErrorCode ierr;
12223425bc38SStefano Zampini 
12233425bc38SStefano Zampini   PetscFunctionBegin;
12243425bc38SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12253425bc38SStefano Zampini   if (pc->setupcalled) {
1226516d51a7SStefano Zampini     ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,Mat*,PC*),(pc,fetidp_mat,fetidp_pc));CHKERRQ(ierr);
1227f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n");
12283425bc38SStefano Zampini   PetscFunctionReturn(0);
12293425bc38SStefano Zampini }
12300c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
1231da1bb401SStefano Zampini /*MC
1232da1bb401SStefano Zampini    PCBDDC - Balancing Domain Decomposition by Constraints.
12330c7d97c5SJed Brown 
123428509bceSStefano Zampini    An implementation of the BDDC preconditioner based on
123528509bceSStefano Zampini 
123628509bceSStefano Zampini .vb
123728509bceSStefano Zampini    [1] C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007
123828509bceSStefano 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
123928509bceSStefano Zampini    [3] J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", http://arxiv.org/abs/0712.3977
124028509bceSStefano Zampini .ve
124128509bceSStefano Zampini 
124228509bceSStefano Zampini    The matrix to be preconditioned (Pmat) must be of type MATIS.
124328509bceSStefano Zampini 
1244b6fdb6dfSStefano Zampini    Currently works with MATIS matrices with local Neumann matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers.
124528509bceSStefano Zampini 
124628509bceSStefano Zampini    It also works with unsymmetric and indefinite problems.
124728509bceSStefano Zampini 
1248b6fdb6dfSStefano 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.
1249b6fdb6dfSStefano Zampini 
125028509bceSStefano Zampini    Approximate local solvers are automatically adapted for singular linear problems (see [1]) if the user has provided the nullspace using PCBDDCSetNullSpace
125128509bceSStefano Zampini 
125228509bceSStefano 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
125328509bceSStefano Zampini 
125428509bceSStefano Zampini    Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace.
125528509bceSStefano Zampini 
1256b6fdb6dfSStefano 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.
125728509bceSStefano Zampini 
125828509bceSStefano Zampini    The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using MatPartitioning object.
125928509bceSStefano Zampini 
1260da1bb401SStefano Zampini    Options Database Keys:
126128509bceSStefano Zampini 
126228509bceSStefano Zampini .    -pc_bddc_use_vertices <1> - use or not vertices in primal space
126328509bceSStefano Zampini .    -pc_bddc_use_edges <1> - use or not edges in primal space
1264b6fdb6dfSStefano Zampini .    -pc_bddc_use_faces <0> - use or not faces in primal space
126528509bceSStefano Zampini .    -pc_bddc_use_change_of_basis <0> - use change of basis approach (on edges only)
126628509bceSStefano Zampini .    -pc_bddc_use_change_on_faces <0> - use change of basis approach on faces if change of basis has been requested
126728509bceSStefano Zampini .    -pc_bddc_switch_static <0> - switches from M_2 to M_3 operator (see reference article [1])
126828509bceSStefano Zampini .    -pc_bddc_levels <0> - maximum number of levels for multilevel
126928509bceSStefano Zampini .    -pc_bddc_coarsening_ratio - H/h ratio at the coarser level
127028509bceSStefano Zampini -    -pc_bddc_check_level <0> - set verbosity level of debugging output
127128509bceSStefano Zampini 
127228509bceSStefano Zampini    Options for Dirichlet, Neumann or coarse solver can be set with
127328509bceSStefano Zampini .vb
127428509bceSStefano Zampini       -pc_bddc_dirichlet_
127528509bceSStefano Zampini       -pc_bddc_neumann_
127628509bceSStefano Zampini       -pc_bddc_coarse_
127728509bceSStefano Zampini .ve
127828509bceSStefano Zampini    e.g -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg
127928509bceSStefano Zampini 
128028509bceSStefano Zampini    When using a multilevel approach, solvers' options at the N-th level can be specified as
128128509bceSStefano Zampini .vb
128228509bceSStefano Zampini       -pc_bddc_dirichlet_N_
128328509bceSStefano Zampini       -pc_bddc_neumann_N_
128428509bceSStefano Zampini       -pc_bddc_coarse_N_
128528509bceSStefano Zampini .ve
128628509bceSStefano Zampini    Note that level number ranges from the finest 0 to the coarsest N
1287da1bb401SStefano Zampini 
1288da1bb401SStefano Zampini    Level: intermediate
1289da1bb401SStefano Zampini 
1290b6fdb6dfSStefano Zampini    Developer notes:
129128509bceSStefano Zampini      Currently does not work with KSPBCGS and other KSPs requiring the specialization of PCApplyTranspose
1292da1bb401SStefano Zampini 
129328509bceSStefano Zampini      New deluxe scaling operator will be available soon.
1294da1bb401SStefano Zampini 
1295da1bb401SStefano Zampini    Contributed by Stefano Zampini
1296da1bb401SStefano Zampini 
1297da1bb401SStefano Zampini .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,  MATIS
1298da1bb401SStefano Zampini M*/
1299b2573a8aSBarry Smith 
1300da1bb401SStefano Zampini #undef __FUNCT__
1301da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC"
13028cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc)
1303da1bb401SStefano Zampini {
1304da1bb401SStefano Zampini   PetscErrorCode      ierr;
1305da1bb401SStefano Zampini   PC_BDDC             *pcbddc;
1306da1bb401SStefano Zampini 
1307da1bb401SStefano Zampini   PetscFunctionBegin;
1308da1bb401SStefano Zampini   /* Creates the private data structure for this preconditioner and attach it to the PC object. */
1309da1bb401SStefano Zampini   ierr      = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr);
1310da1bb401SStefano Zampini   pc->data  = (void*)pcbddc;
1311da1bb401SStefano Zampini 
1312da1bb401SStefano Zampini   /* create PCIS data structure */
1313da1bb401SStefano Zampini   ierr = PCISCreate(pc);CHKERRQ(ierr);
1314da1bb401SStefano Zampini 
131547d04d0dSStefano Zampini   /* BDDC customization */
131647d04d0dSStefano Zampini   pcbddc->use_vertices        = PETSC_TRUE;
131747d04d0dSStefano Zampini   pcbddc->use_edges           = PETSC_TRUE;
131847d04d0dSStefano Zampini   pcbddc->use_faces           = PETSC_FALSE;
131947d04d0dSStefano Zampini   pcbddc->use_change_of_basis = PETSC_FALSE;
132047d04d0dSStefano Zampini   pcbddc->use_change_on_faces = PETSC_FALSE;
132147d04d0dSStefano Zampini   pcbddc->switch_static       = PETSC_FALSE;
132247d04d0dSStefano Zampini   pcbddc->use_nnsp_true       = PETSC_FALSE; /* not yet exposed */
132347d04d0dSStefano Zampini   pcbddc->dbg_flag            = 0;
132447d04d0dSStefano Zampini 
1325674ae819SStefano Zampini   pcbddc->user_primal_vertices       = 0;
13260bdf917eSStefano Zampini   pcbddc->NullSpace                  = 0;
13273972b0daSStefano Zampini   pcbddc->temp_solution              = 0;
1328534831adSStefano Zampini   pcbddc->original_rhs               = 0;
1329534831adSStefano Zampini   pcbddc->local_mat                  = 0;
1330534831adSStefano Zampini   pcbddc->ChangeOfBasisMatrix        = 0;
1331da1bb401SStefano Zampini   pcbddc->coarse_vec                 = 0;
1332da1bb401SStefano Zampini   pcbddc->coarse_rhs                 = 0;
1333da1bb401SStefano Zampini   pcbddc->coarse_ksp                 = 0;
1334da1bb401SStefano Zampini   pcbddc->coarse_phi_B               = 0;
1335da1bb401SStefano Zampini   pcbddc->coarse_phi_D               = 0;
133615aaf578SStefano Zampini   pcbddc->coarse_psi_B               = 0;
133715aaf578SStefano Zampini   pcbddc->coarse_psi_D               = 0;
1338da1bb401SStefano Zampini   pcbddc->vec1_P                     = 0;
1339da1bb401SStefano Zampini   pcbddc->vec1_R                     = 0;
1340da1bb401SStefano Zampini   pcbddc->vec2_R                     = 0;
1341da1bb401SStefano Zampini   pcbddc->local_auxmat1              = 0;
1342da1bb401SStefano Zampini   pcbddc->local_auxmat2              = 0;
1343da1bb401SStefano Zampini   pcbddc->R_to_B                     = 0;
1344da1bb401SStefano Zampini   pcbddc->R_to_D                     = 0;
1345da1bb401SStefano Zampini   pcbddc->ksp_D                      = 0;
1346da1bb401SStefano Zampini   pcbddc->ksp_R                      = 0;
1347da1bb401SStefano Zampini   pcbddc->NeumannBoundaries          = 0;
134860d44989SStefano Zampini   pcbddc->user_provided_isfordofs    = PETSC_FALSE;
134960d44989SStefano Zampini   pcbddc->n_ISForDofs                = 0;
1350da1bb401SStefano Zampini   pcbddc->ISForDofs                  = 0;
1351da1bb401SStefano Zampini   pcbddc->ConstraintMatrix           = 0;
135285c4d303SStefano Zampini   pcbddc->use_exact_dirichlet_trick  = PETSC_TRUE;
135347d04d0dSStefano Zampini   pcbddc->coarse_loc_to_glob         = 0;
135447d04d0dSStefano Zampini   pcbddc->coarsening_ratio           = 8;
13554fad6a16SStefano Zampini   pcbddc->current_level              = 0;
13562b510759SStefano Zampini   pcbddc->max_levels                 = 0;
1357da1bb401SStefano Zampini 
1358674ae819SStefano Zampini   /* create local graph structure */
1359674ae819SStefano Zampini   ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr);
1360674ae819SStefano Zampini 
1361674ae819SStefano Zampini   /* scaling */
1362674ae819SStefano Zampini   pcbddc->use_deluxe_scaling         = PETSC_FALSE;
1363674ae819SStefano Zampini   pcbddc->work_scaling               = 0;
1364da1bb401SStefano Zampini 
1365da1bb401SStefano Zampini   /* function pointers */
1366da1bb401SStefano Zampini   pc->ops->apply               = PCApply_BDDC;
1367da1bb401SStefano Zampini   pc->ops->applytranspose      = 0;
1368da1bb401SStefano Zampini   pc->ops->setup               = PCSetUp_BDDC;
1369da1bb401SStefano Zampini   pc->ops->destroy             = PCDestroy_BDDC;
1370da1bb401SStefano Zampini   pc->ops->setfromoptions      = PCSetFromOptions_BDDC;
1371da1bb401SStefano Zampini   pc->ops->view                = 0;
1372da1bb401SStefano Zampini   pc->ops->applyrichardson     = 0;
1373da1bb401SStefano Zampini   pc->ops->applysymmetricleft  = 0;
1374da1bb401SStefano Zampini   pc->ops->applysymmetricright = 0;
1375534831adSStefano Zampini   pc->ops->presolve            = PCPreSolve_BDDC;
1376534831adSStefano Zampini   pc->ops->postsolve           = PCPostSolve_BDDC;
1377da1bb401SStefano Zampini 
1378da1bb401SStefano Zampini   /* composing function */
1379674ae819SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr);
1380bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr);
13812b510759SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr);
1382b8ffe317SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr);
13832b510759SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr);
1384bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",PCBDDCSetNullSpace_BDDC);CHKERRQ(ierr);
1385*82ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr);
1386*82ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr);
1387*82ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr);
1388*82ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr);
1389bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr);
1390bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr);
1391bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr);
1392bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr);
1393bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr);
1394da1bb401SStefano Zampini   PetscFunctionReturn(0);
1395da1bb401SStefano Zampini }
13963425bc38SStefano Zampini 
1397