xref: /petsc/src/ksp/pc/impls/bddc/bddc.c (revision e9627c491338d5e26d4843e57a28c2c93564984d)
153cdbc3dSStefano Zampini /* TODOLIST
2eb97c9d2SStefano Zampini 
3eb97c9d2SStefano Zampini    Solvers
4a0d3c3abSStefano Zampini    - Add support for cholesky for coarse solver (similar to local solvers)
5eb97c9d2SStefano Zampini    - Propagate ksp prefixes for solvers to mat objects?
6eb97c9d2SStefano Zampini 
7eb97c9d2SStefano Zampini    User interface
80f202f7eSStefano Zampini    - ** DM attached to pc?
9eb97c9d2SStefano Zampini 
10eb97c9d2SStefano Zampini    Debugging output
11b9b85e73SStefano Zampini    - * Better management of verbosity levels of debugging output
12eb97c9d2SStefano Zampini 
13eb97c9d2SStefano Zampini    Extra
14b9b85e73SStefano Zampini    - *** Is it possible to work with PCBDDCGraph on boundary indices only (less memory consumed)?
15eb97c9d2SStefano Zampini    - BDDC with MG framework?
16eb97c9d2SStefano Zampini 
17eb97c9d2SStefano Zampini    FETIDP
18eb97c9d2SStefano Zampini    - Move FETIDP code to its own classes
19eb97c9d2SStefano Zampini 
20eb97c9d2SStefano Zampini    MATIS related operations contained in BDDC code
21eb97c9d2SStefano Zampini    - Provide general case for subassembling
22eb97c9d2SStefano Zampini 
2353cdbc3dSStefano Zampini */
240c7d97c5SJed Brown 
25ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> /*I "petscpc.h" I*/  /* includes for fortran wrappers */
26ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h>
273b03a366Sstefano_zampini #include <petscblaslapack.h>
28674ae819SStefano Zampini 
290369aaf7SStefano Zampini /* temporarily declare it */
300369aaf7SStefano Zampini PetscErrorCode PCApply_BDDC(PC,Vec,Vec);
310369aaf7SStefano Zampini 
320c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
330c7d97c5SJed Brown #undef __FUNCT__
340c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC"
354416b707SBarry Smith PetscErrorCode PCSetFromOptions_BDDC(PetscOptionItems *PetscOptionsObject,PC pc)
360c7d97c5SJed Brown {
370c7d97c5SJed Brown   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
380c7d97c5SJed Brown   PetscErrorCode ierr;
390c7d97c5SJed Brown 
400c7d97c5SJed Brown   PetscFunctionBegin;
41e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"BDDC options");CHKERRQ(ierr);
428eeda7d8SStefano Zampini   /* Verbose debugging */
438eeda7d8SStefano Zampini   ierr = PetscOptionsInt("-pc_bddc_check_level","Verbose output for PCBDDC (intended for debug)","none",pcbddc->dbg_flag,&pcbddc->dbg_flag,NULL);CHKERRQ(ierr);
446b78500eSPatrick Sanan   /* Primal space customization */
4508a5cf49SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_use_local_mat_graph","Use or not adjacency graph of local mat for interface analysis","none",pcbddc->use_local_adj,&pcbddc->use_local_adj,NULL);CHKERRQ(ierr);
468eeda7d8SStefano 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);
478eeda7d8SStefano 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);
488eeda7d8SStefano 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);
4914f95afaSStefano Zampini   ierr = PetscOptionsInt("-pc_bddc_vertex_size","Connected components smaller or equal to vertex size will be considered as primal vertices","none",pcbddc->vertex_size,&pcbddc->vertex_size,NULL);CHKERRQ(ierr);
506661aa1dSStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_use_true_nnsp","Use near null space attached to the matrix without modifications","none",pcbddc->use_nnsp_true,&pcbddc->use_nnsp_true,NULL);CHKERRQ(ierr);
5114f95afaSStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_use_qr_single","Use QR factorization for single constraints on cc (QR is always used when multiple constraints are present)","none",pcbddc->use_qr_single,&pcbddc->use_qr_single,NULL);CHKERRQ(ierr);
528eeda7d8SStefano Zampini   /* Change of basis */
53b9b85e73SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_use_change_of_basis","Use or not internal change of basis on local edge nodes","none",pcbddc->use_change_of_basis,&pcbddc->use_change_of_basis,NULL);CHKERRQ(ierr);
54b9b85e73SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_use_change_on_faces","Use or not internal change of basis on local face nodes","none",pcbddc->use_change_on_faces,&pcbddc->use_change_on_faces,NULL);CHKERRQ(ierr);
55674ae819SStefano Zampini   if (!pcbddc->use_change_of_basis) {
56674ae819SStefano Zampini     pcbddc->use_change_on_faces = PETSC_FALSE;
57674ae819SStefano Zampini   }
588eeda7d8SStefano Zampini   /* Switch between M_2 (default) and M_3 preconditioners (as defined by C. Dohrmann in the ref. article) */
598eeda7d8SStefano 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);
6057de7509SStefano Zampini   ierr = PetscOptionsInt("-pc_bddc_coarse_eqs_per_proc","Number of equations per process for coarse problem redistribution (significant only at the coarsest level)","none",pcbddc->coarse_eqs_per_proc,&pcbddc->coarse_eqs_per_proc,NULL);CHKERRQ(ierr);
610298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr);
622b510759SStefano Zampini   ierr = PetscOptionsInt("-pc_bddc_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr);
63323d395dSStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_use_coarse_estimates","Use estimated eigenvalues for coarse problem","none",pcbddc->use_coarse_estimates,&pcbddc->use_coarse_estimates,NULL);CHKERRQ(ierr);
64674ae819SStefano 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);
65b96c3477SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_schur_rebuild","Whether or not the interface graph for Schur principal minors has to be rebuilt (i.e. define the interface without any adjacency)","none",pcbddc->sub_schurs_rebuild,&pcbddc->sub_schurs_rebuild,NULL);CHKERRQ(ierr);
66b96c3477SStefano Zampini   ierr = PetscOptionsInt("-pc_bddc_schur_layers","Number of dofs' layers for the computation of principal minors (i.e. -1 uses all dofs)","none",pcbddc->sub_schurs_layers,&pcbddc->sub_schurs_layers,NULL);CHKERRQ(ierr);
67b96c3477SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_schur_use_useradj","Whether or not the CSR graph specified by the user should be used for computing successive layers (default is to use adj of local mat)","none",pcbddc->sub_schurs_use_useradj,&pcbddc->sub_schurs_use_useradj,NULL);CHKERRQ(ierr);
68683d3df6SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_schur_exact","Whether or not to use the exact Schur complement instead of the reduced one (which excludes size 1 cc)","none",pcbddc->sub_schurs_exact_schur,&pcbddc->sub_schurs_exact_schur,NULL);CHKERRQ(ierr);
69bf3a8328SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_deluxe_zerorows","Zero rows and columns of deluxe operators associated with primal dofs","none",pcbddc->deluxe_zerorows,&pcbddc->deluxe_zerorows,NULL);CHKERRQ(ierr);
70bf3a8328SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_adaptive_userdefined","Use user-defined constraints (should be attached via MatSetNearNullSpace to pmat) in addition to those adaptively generated","none",pcbddc->adaptive_userdefined,&pcbddc->adaptive_userdefined,NULL);CHKERRQ(ierr);
714c6709b3SStefano Zampini   ierr = PetscOptionsReal("-pc_bddc_adaptive_threshold","Threshold to be used for adaptive selection of constraints","none",pcbddc->adaptive_threshold,&pcbddc->adaptive_threshold,NULL);CHKERRQ(ierr);
7208122e43SStefano Zampini   ierr = PetscOptionsInt("-pc_bddc_adaptive_nmin","Minimum number of constraints per connected components","none",pcbddc->adaptive_nmin,&pcbddc->adaptive_nmin,NULL);CHKERRQ(ierr);
7308122e43SStefano Zampini   ierr = PetscOptionsInt("-pc_bddc_adaptive_nmax","Maximum number of constraints per connected components","none",pcbddc->adaptive_nmax,&pcbddc->adaptive_nmax,NULL);CHKERRQ(ierr);
743301b35fSStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_symmetric","Symmetric computation of primal basis functions","none",pcbddc->symmetric_primal,&pcbddc->symmetric_primal,NULL);CHKERRQ(ierr);
75b0c7d250SStefano Zampini   ierr = PetscOptionsInt("-pc_bddc_coarse_adj","Number of processors where to map the coarse adjacency list","none",pcbddc->coarse_adj_red,&pcbddc->coarse_adj_red,NULL);CHKERRQ(ierr);
76b3afcdbeSStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_benign_trick","Apply the benign subspace trick to saddle point problems with discontinuous pressures","none",pcbddc->benign_saddle_point,&pcbddc->benign_saddle_point,NULL);CHKERRQ(ierr);
77b3afcdbeSStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_benign_nonetflux","Automatic computation of no-net-flux quadrature weights","none",pcbddc->benign_compute_nonetflux,&pcbddc->benign_compute_nonetflux,NULL);CHKERRQ(ierr);
78*e9627c49SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_benign_change","Compute the pressure change of basis explicitly","none",pcbddc->benign_change_explicit,&pcbddc->benign_change_explicit,NULL);CHKERRQ(ierr);
794f1b2e48SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_detect_disconnected","Detects disconnected subdomains","none",pcbddc->detect_disconnected,&pcbddc->detect_disconnected,NULL);CHKERRQ(ierr);
8070c64980SStefano Zampini   ierr = PetscOptionsBool("-pc_bddc_eliminate_dirichlet","Whether or not we want to eliminate dirichlet dofs during presolve","none",pcbddc->eliminate_dirdofs,&pcbddc->eliminate_dirdofs,NULL);CHKERRQ(ierr);
810c7d97c5SJed Brown   ierr = PetscOptionsTail();CHKERRQ(ierr);
820c7d97c5SJed Brown   PetscFunctionReturn(0);
830c7d97c5SJed Brown }
846b78500eSPatrick Sanan 
856b78500eSPatrick Sanan /* -------------------------------------------------------------------------- */
866b78500eSPatrick Sanan #undef __FUNCT__
876b78500eSPatrick Sanan #define __FUNCT__ "PCView_BDDC"
886b78500eSPatrick Sanan static PetscErrorCode PCView_BDDC(PC pc,PetscViewer viewer)
896b78500eSPatrick Sanan {
906b78500eSPatrick Sanan   PC_BDDC              *pcbddc = (PC_BDDC*)pc->data;
91*e9627c49SStefano Zampini   PC_IS                *pcis = (PC_IS*)pc->data;
926b78500eSPatrick Sanan   PetscErrorCode       ierr;
936b78500eSPatrick Sanan   PetscBool            isascii,isstring;
94*e9627c49SStefano Zampini   PetscSubcomm         subcomm;
95*e9627c49SStefano Zampini   PetscViewer          subviewer;
966b78500eSPatrick Sanan 
976b78500eSPatrick Sanan   PetscFunctionBegin;
986b78500eSPatrick Sanan   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
996b78500eSPatrick Sanan   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
1006b78500eSPatrick Sanan   /* Nothing printed for the String viewer */
1016b78500eSPatrick Sanan   /* ASCII viewer */
1026b78500eSPatrick Sanan   if (isascii) {
103*e9627c49SStefano Zampini     PetscMPIInt   color,rank;
104*e9627c49SStefano Zampini     Petsc64bitInt loc[4],gsum[4],gmax[4],gmin[4];
105*e9627c49SStefano Zampini     PetscScalar   interface_size;
106*e9627c49SStefano Zampini     PetscReal     ratio1=0.,ratio2=0.;
107*e9627c49SStefano Zampini     Vec           counter;
1086b78500eSPatrick Sanan 
109*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Use verbose output: %d\n",pcbddc->dbg_flag);CHKERRQ(ierr);
110*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Use user-defined CSR: %d\n",!!pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr);
1116b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Use local mat graph: %d\n",pcbddc->use_local_adj);CHKERRQ(ierr);
112*e9627c49SStefano Zampini     if (pcbddc->mat_graph->twodim) {
113*e9627c49SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Connectivity graph topological dimension: 2\n");CHKERRQ(ierr);
114*e9627c49SStefano Zampini     } else {
115*e9627c49SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Connectivity graph topological dimension: 3\n");CHKERRQ(ierr);
116*e9627c49SStefano Zampini     }
117*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Use vertices: %d (vertext size %d)\n",pcbddc->use_vertices,pcbddc->vertex_size);CHKERRQ(ierr);
1186b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Use edges: %d\n",pcbddc->use_edges);CHKERRQ(ierr);
1196b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Use faces: %d\n",pcbddc->use_faces);CHKERRQ(ierr);
1206b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Use true near null space: %d\n",pcbddc->use_nnsp_true);CHKERRQ(ierr);
1216b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Use QR for single constraints on cc: %d\n",pcbddc->use_qr_single);CHKERRQ(ierr);
1226b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Use change of basis on local edge nodes: %d\n",pcbddc->use_change_of_basis);CHKERRQ(ierr);
1236b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Use change of basis on local face nodes: %d\n",pcbddc->use_change_on_faces);CHKERRQ(ierr);
12470c64980SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Eliminate dirichlet dofs: %d\n",pcbddc->eliminate_dirdofs);CHKERRQ(ierr);
1256b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Switch on static condensation ops around the interface preconditioner: %d\n",pcbddc->switch_static);CHKERRQ(ierr);
1266b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Multilevel max levels: %d\n",pcbddc->max_levels);CHKERRQ(ierr);
127*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Multilevel coarsening ratio: %d\n",pcbddc->coarsening_ratio);CHKERRQ(ierr);
1286b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Use estimated eigs for coarse problem: %d\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr);
1296b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Use deluxe scaling: %d\n",pcbddc->use_deluxe_scaling);CHKERRQ(ierr);
130*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Use deluxe zerorows: %d\n",pcbddc->deluxe_zerorows);CHKERRQ(ierr);
1316b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Rebuild interface graph for Schur principal minors: %d\n",pcbddc->sub_schurs_rebuild);CHKERRQ(ierr);
1326b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Number of dofs' layers for the computation of principal minors: %d\n",pcbddc->sub_schurs_layers);CHKERRQ(ierr);
1336b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Use user CSR graph to compute successive layers: %d\n",pcbddc->sub_schurs_use_useradj);CHKERRQ(ierr);
134*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Adaptive constraint selection threshold (active %d, userdefined %d): %g\n",pcbddc->adaptive_threshold,pcbddc->adaptive_selection,pcbddc->adaptive_userdefined);CHKERRQ(ierr);
1356b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Min constraints / connected component: %d\n",pcbddc->adaptive_nmin);CHKERRQ(ierr);
1366b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Max constraints / connected component: %d\n",pcbddc->adaptive_nmax);CHKERRQ(ierr);
137*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Invert exact Schur complement for adaptive selection: %d\n",pcbddc->sub_schurs_exact_schur);CHKERRQ(ierr);
1386b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Symmetric computation of primal basis functions: %d\n",pcbddc->symmetric_primal);CHKERRQ(ierr);
1396b78500eSPatrick Sanan     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Num. Procs. to map coarse adjacency list: %d\n",pcbddc->coarse_adj_red);CHKERRQ(ierr);
140*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Coarse eqs per proc (significant at the coarsest level): %d\n",pcbddc->coarse_eqs_per_proc);CHKERRQ(ierr);
141*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Detect disconnected: %d\n",pcbddc->detect_disconnected);CHKERRQ(ierr);
142*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Benign subspace trick: %d (algebraic computation of no-net-flux %d)\n",pcbddc->benign_saddle_point,pcbddc->benign_compute_nonetflux);CHKERRQ(ierr);
143*e9627c49SStefano Zampini     ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
1446b78500eSPatrick Sanan 
145*e9627c49SStefano Zampini     /* compute some number on the domain decomposition */
146*e9627c49SStefano Zampini     ierr = VecSet(pcis->vec1_B,1.0);CHKERRQ(ierr);
147*e9627c49SStefano Zampini     ierr = MatCreateVecs(pc->pmat,&counter,0);CHKERRQ(ierr);
148*e9627c49SStefano Zampini     ierr = VecSet(counter,0.0);CHKERRQ(ierr);
149*e9627c49SStefano Zampini     ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
150*e9627c49SStefano Zampini     ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
151*e9627c49SStefano Zampini     ierr = VecSum(counter,&interface_size);CHKERRQ(ierr);
152*e9627c49SStefano Zampini     ierr = VecDestroy(&counter);CHKERRQ(ierr);
153*e9627c49SStefano Zampini     gsum[0] = 1;
154*e9627c49SStefano Zampini     gsum[1] = gsum[2] = gsum[3] = 0;
155*e9627c49SStefano Zampini     loc[0] = !!pcis->n;
156*e9627c49SStefano Zampini     loc[1] = pcis->n - pcis->n_B;
157*e9627c49SStefano Zampini     loc[2] = pcis->n_B;
158*e9627c49SStefano Zampini     loc[3] = pcbddc->local_primal_size;
159*e9627c49SStefano Zampini     ierr = MPI_Reduce(loc,gsum,4,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr);
160*e9627c49SStefano Zampini     if (!loc[0]) loc[1] = loc[2] = loc[3] = -1;
161*e9627c49SStefano Zampini     ierr = MPI_Reduce(loc,gmax,4,MPIU_INT64,MPI_MAX,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr);
162*e9627c49SStefano Zampini     if (!loc[0]) loc[1] = loc[2] = loc[3] = PETSC_MAX_INT;
163*e9627c49SStefano Zampini     ierr = MPI_Reduce(loc,gmin,4,MPIU_INT64,MPI_MIN,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr);
164*e9627c49SStefano Zampini     if (pcbddc->coarse_size) {
165*e9627c49SStefano Zampini       ratio1 = pc->pmat->rmap->N/(1.*pcbddc->coarse_size);
166*e9627c49SStefano Zampini       ratio2 = PetscRealPart(interface_size)/pcbddc->coarse_size;
167*e9627c49SStefano Zampini     }
168*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: ********************************** STATISTICS AT LEVEL %d **********************************\n",pcbddc->current_level);CHKERRQ(ierr);
169*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Global dofs sizes: all %d interface %d coarse %d\n",pc->pmat->rmap->N,(PetscInt)PetscRealPart(interface_size),pcbddc->coarse_size);CHKERRQ(ierr);
170*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Coarsening ratios: all/coarse %d interface/coarse %d\n",(PetscInt)ratio1,(PetscInt)ratio2);CHKERRQ(ierr);
171*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Active processes : %d\n",(PetscInt)gsum[0]);CHKERRQ(ierr);
172*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Dofs type        :\tMIN\tMAX\tMEAN\n",(PetscInt)gmin[1],(PetscInt)gmax[1],(PetscInt)(gsum[1]/gsum[0]));CHKERRQ(ierr);
173*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Interior  dofs   :\t%d\t%d\t%d\n",(PetscInt)gmin[1],(PetscInt)gmax[1],(PetscInt)(gsum[1]/gsum[0]));CHKERRQ(ierr);
174*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Interface dofs   :\t%d\t%d\t%d\n",(PetscInt)gmin[2],(PetscInt)gmax[2],(PetscInt)(gsum[2]/gsum[0]));CHKERRQ(ierr);
175*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: Primal    dofs   :\t%d\t%d\t%d\n",(PetscInt)gmin[3],(PetscInt)gmax[3],(PetscInt)(gsum[3]/gsum[0]));CHKERRQ(ierr);
176*e9627c49SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  BDDC: *******************************************************************************************\n");CHKERRQ(ierr);
177*e9627c49SStefano Zampini 
178*e9627c49SStefano Zampini     /* the coarse problem can be handled with a different communicator */
179*e9627c49SStefano Zampini     if (pcbddc->coarse_ksp) color = 1;
180*e9627c49SStefano Zampini     else color = 0;
181*e9627c49SStefano Zampini     ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr);
182*e9627c49SStefano Zampini     ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)pc),&subcomm);CHKERRQ(ierr);
183*e9627c49SStefano Zampini     ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr);
184*e9627c49SStefano Zampini     ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr);
185*e9627c49SStefano Zampini     ierr = PetscViewerGetSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr);
186*e9627c49SStefano Zampini     if (color == 1) {
187*e9627c49SStefano Zampini       ierr = KSPView(pcbddc->coarse_ksp,subviewer);CHKERRQ(ierr);
188*e9627c49SStefano Zampini       ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr);
189*e9627c49SStefano Zampini     }
190*e9627c49SStefano Zampini     ierr = PetscViewerRestoreSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr);
191*e9627c49SStefano Zampini     ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr);
192*e9627c49SStefano Zampini     ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
193*e9627c49SStefano Zampini   }
1946b78500eSPatrick Sanan   PetscFunctionReturn(0);
1956b78500eSPatrick Sanan }
1966b78500eSPatrick Sanan 
1970c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
198674ae819SStefano Zampini #undef __FUNCT__
199906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCSetChangeOfBasisMat_BDDC"
2001dd7afcfSStefano Zampini static PetscErrorCode PCBDDCSetChangeOfBasisMat_BDDC(PC pc, Mat change, PetscBool interior)
201b9b85e73SStefano Zampini {
202b9b85e73SStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
203b9b85e73SStefano Zampini   PetscErrorCode ierr;
204b9b85e73SStefano Zampini 
205b9b85e73SStefano Zampini   PetscFunctionBegin;
206b9b85e73SStefano Zampini   ierr = PetscObjectReference((PetscObject)change);CHKERRQ(ierr);
20756282151SStefano Zampini   ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr);
208b9b85e73SStefano Zampini   pcbddc->user_ChangeOfBasisMatrix = change;
2091dd7afcfSStefano Zampini   pcbddc->change_interior = interior;
210b9b85e73SStefano Zampini   PetscFunctionReturn(0);
211b9b85e73SStefano Zampini }
212b9b85e73SStefano Zampini #undef __FUNCT__
213906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCSetChangeOfBasisMat"
214b9b85e73SStefano Zampini /*@
215906d46d4SStefano Zampini  PCBDDCSetChangeOfBasisMat - Set user defined change of basis for dofs
216b9b85e73SStefano Zampini 
217b9b85e73SStefano Zampini    Collective on PC
218b9b85e73SStefano Zampini 
219b9b85e73SStefano Zampini    Input Parameters:
220b9b85e73SStefano Zampini +  pc - the preconditioning context
2211dd7afcfSStefano Zampini .  change - the change of basis matrix
2221dd7afcfSStefano Zampini -  interior - whether or not the change of basis modifies interior dofs
223b9b85e73SStefano Zampini 
224b9b85e73SStefano Zampini    Level: intermediate
225b9b85e73SStefano Zampini 
226b9b85e73SStefano Zampini    Notes:
227b9b85e73SStefano Zampini 
228b9b85e73SStefano Zampini .seealso: PCBDDC
229b9b85e73SStefano Zampini @*/
2301dd7afcfSStefano Zampini PetscErrorCode PCBDDCSetChangeOfBasisMat(PC pc, Mat change, PetscBool interior)
231b9b85e73SStefano Zampini {
232b9b85e73SStefano Zampini   PetscErrorCode ierr;
233b9b85e73SStefano Zampini 
234b9b85e73SStefano Zampini   PetscFunctionBegin;
235b9b85e73SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
236b9b85e73SStefano Zampini   PetscValidHeaderSpecific(change,MAT_CLASSID,2);
237906d46d4SStefano Zampini   PetscCheckSameComm(pc,1,change,2);
238906d46d4SStefano Zampini   if (pc->mat) {
239906d46d4SStefano Zampini     PetscInt rows_c,cols_c,rows,cols;
240906d46d4SStefano Zampini     ierr = MatGetSize(pc->mat,&rows,&cols);CHKERRQ(ierr);
241906d46d4SStefano Zampini     ierr = MatGetSize(change,&rows_c,&cols_c);CHKERRQ(ierr);
2426c4ed002SBarry Smith     if (rows_c != rows) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of rows for change of basis matrix! %d != %d",rows_c,rows);
2436c4ed002SBarry Smith     if (cols_c != cols) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of columns for change of basis matrix! %d != %d",cols_c,cols);
244906d46d4SStefano Zampini     ierr = MatGetLocalSize(pc->mat,&rows,&cols);CHKERRQ(ierr);
245906d46d4SStefano Zampini     ierr = MatGetLocalSize(change,&rows_c,&cols_c);CHKERRQ(ierr);
2466c4ed002SBarry Smith     if (rows_c != rows) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of local rows for change of basis matrix! %d != %d",rows_c,rows);
2476c4ed002SBarry Smith     if (cols_c != cols) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of local columns for change of basis matrix! %d != %d",cols_c,cols);
248906d46d4SStefano Zampini   }
2491dd7afcfSStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetChangeOfBasisMat_C",(PC,Mat,PetscBool),(pc,change,interior));CHKERRQ(ierr);
250b9b85e73SStefano Zampini   PetscFunctionReturn(0);
251b9b85e73SStefano Zampini }
252b9b85e73SStefano Zampini /* -------------------------------------------------------------------------- */
253b9b85e73SStefano Zampini #undef __FUNCT__
25430368db7SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesIS_BDDC"
25530368db7SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesIS_BDDC(PC pc, IS PrimalVertices)
25630368db7SStefano Zampini {
25730368db7SStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
25856282151SStefano Zampini   PetscBool      isequal = PETSC_FALSE;
25930368db7SStefano Zampini   PetscErrorCode ierr;
26030368db7SStefano Zampini 
26130368db7SStefano Zampini   PetscFunctionBegin;
26256282151SStefano Zampini   ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr);
26356282151SStefano Zampini   if (pcbddc->user_primal_vertices) {
26456282151SStefano Zampini     ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices,&isequal);CHKERRQ(ierr);
26556282151SStefano Zampini   }
26630368db7SStefano Zampini   ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr);
26730368db7SStefano Zampini   ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr);
26830368db7SStefano Zampini   pcbddc->user_primal_vertices = PrimalVertices;
26956282151SStefano Zampini   if (!isequal) pcbddc->recompute_topography = PETSC_TRUE;
27030368db7SStefano Zampini   PetscFunctionReturn(0);
27130368db7SStefano Zampini }
27230368db7SStefano Zampini #undef __FUNCT__
27330368db7SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesIS"
27430368db7SStefano Zampini /*@
27530368db7SStefano Zampini  PCBDDCSetPrimalVerticesIS - Set additional user defined primal vertices in PCBDDC
27630368db7SStefano Zampini 
27730368db7SStefano Zampini    Collective
27830368db7SStefano Zampini 
27930368db7SStefano Zampini    Input Parameters:
28030368db7SStefano Zampini +  pc - the preconditioning context
28130368db7SStefano Zampini -  PrimalVertices - index set of primal vertices in global numbering (can be empty)
28230368db7SStefano Zampini 
28330368db7SStefano Zampini    Level: intermediate
28430368db7SStefano Zampini 
28530368db7SStefano Zampini    Notes:
28630368db7SStefano Zampini      Any process can list any global node
28730368db7SStefano Zampini 
28830368db7SStefano Zampini .seealso: PCBDDC
28930368db7SStefano Zampini @*/
29030368db7SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesIS(PC pc, IS PrimalVertices)
29130368db7SStefano Zampini {
29230368db7SStefano Zampini   PetscErrorCode ierr;
29330368db7SStefano Zampini 
29430368db7SStefano Zampini   PetscFunctionBegin;
29530368db7SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
29630368db7SStefano Zampini   PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2);
29730368db7SStefano Zampini   PetscCheckSameComm(pc,1,PrimalVertices,2);
29830368db7SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr);
29930368db7SStefano Zampini   PetscFunctionReturn(0);
30030368db7SStefano Zampini }
30130368db7SStefano Zampini /* -------------------------------------------------------------------------- */
30230368db7SStefano Zampini #undef __FUNCT__
303674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS_BDDC"
304674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices)
305674ae819SStefano Zampini {
306674ae819SStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
30756282151SStefano Zampini   PetscBool      isequal = PETSC_FALSE;
308674ae819SStefano Zampini   PetscErrorCode ierr;
3091e6b0712SBarry Smith 
310674ae819SStefano Zampini   PetscFunctionBegin;
31156282151SStefano Zampini   ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr);
31256282151SStefano Zampini   if (pcbddc->user_primal_vertices_local) {
31356282151SStefano Zampini     ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices_local,&isequal);CHKERRQ(ierr);
31456282151SStefano Zampini   }
315674ae819SStefano Zampini   ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr);
31630368db7SStefano Zampini   ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr);
31730368db7SStefano Zampini   pcbddc->user_primal_vertices_local = PrimalVertices;
31856282151SStefano Zampini   if (!isequal) pcbddc->recompute_topography = PETSC_TRUE;
319674ae819SStefano Zampini   PetscFunctionReturn(0);
320674ae819SStefano Zampini }
321674ae819SStefano Zampini #undef __FUNCT__
322674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS"
323674ae819SStefano Zampini /*@
32428509bceSStefano Zampini  PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC
325674ae819SStefano Zampini 
32617eb1463SStefano Zampini    Collective
327674ae819SStefano Zampini 
328674ae819SStefano Zampini    Input Parameters:
329674ae819SStefano Zampini +  pc - the preconditioning context
33017eb1463SStefano Zampini -  PrimalVertices - index set of primal vertices in local numbering (can be empty)
331674ae819SStefano Zampini 
332674ae819SStefano Zampini    Level: intermediate
333674ae819SStefano Zampini 
334674ae819SStefano Zampini    Notes:
335674ae819SStefano Zampini 
336674ae819SStefano Zampini .seealso: PCBDDC
337674ae819SStefano Zampini @*/
338674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices)
339674ae819SStefano Zampini {
340674ae819SStefano Zampini   PetscErrorCode ierr;
341674ae819SStefano Zampini 
342674ae819SStefano Zampini   PetscFunctionBegin;
343674ae819SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
344674ae819SStefano Zampini   PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2);
34517eb1463SStefano Zampini   PetscCheckSameComm(pc,1,PrimalVertices,2);
346674ae819SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr);
347674ae819SStefano Zampini   PetscFunctionReturn(0);
348674ae819SStefano Zampini }
349674ae819SStefano Zampini /* -------------------------------------------------------------------------- */
3500c7d97c5SJed Brown #undef __FUNCT__
3514fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio_BDDC"
3524fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k)
3534fad6a16SStefano Zampini {
3544fad6a16SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
3554fad6a16SStefano Zampini 
3564fad6a16SStefano Zampini   PetscFunctionBegin;
3574fad6a16SStefano Zampini   pcbddc->coarsening_ratio = k;
3584fad6a16SStefano Zampini   PetscFunctionReturn(0);
3594fad6a16SStefano Zampini }
3601e6b0712SBarry Smith 
3614fad6a16SStefano Zampini #undef __FUNCT__
3624fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio"
3634fad6a16SStefano Zampini /*@
36428509bceSStefano Zampini  PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel
3654fad6a16SStefano Zampini 
3664fad6a16SStefano Zampini    Logically collective on PC
3674fad6a16SStefano Zampini 
3684fad6a16SStefano Zampini    Input Parameters:
3694fad6a16SStefano Zampini +  pc - the preconditioning context
37028509bceSStefano Zampini -  k - coarsening ratio (H/h at the coarser level)
3714fad6a16SStefano Zampini 
3720f202f7eSStefano Zampini    Options Database Keys:
3730f202f7eSStefano Zampini .    -pc_bddc_coarsening_ratio
3744fad6a16SStefano Zampini 
3754fad6a16SStefano Zampini    Level: intermediate
3764fad6a16SStefano Zampini 
3774fad6a16SStefano Zampini    Notes:
3780f202f7eSStefano Zampini      Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level
3794fad6a16SStefano Zampini 
3800f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetLevels()
3814fad6a16SStefano Zampini @*/
3824fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k)
3834fad6a16SStefano Zampini {
3844fad6a16SStefano Zampini   PetscErrorCode ierr;
3854fad6a16SStefano Zampini 
3864fad6a16SStefano Zampini   PetscFunctionBegin;
3874fad6a16SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
3882b510759SStefano Zampini   PetscValidLogicalCollectiveInt(pc,k,2);
3894fad6a16SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr);
3904fad6a16SStefano Zampini   PetscFunctionReturn(0);
3914fad6a16SStefano Zampini }
3922b510759SStefano Zampini 
393b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */
3942b510759SStefano Zampini #undef __FUNCT__
395b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet_BDDC"
396b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg)
397b8ffe317SStefano Zampini {
398b8ffe317SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
399b8ffe317SStefano Zampini 
400b8ffe317SStefano Zampini   PetscFunctionBegin;
40185c4d303SStefano Zampini   pcbddc->use_exact_dirichlet_trick = flg;
402b8ffe317SStefano Zampini   PetscFunctionReturn(0);
403b8ffe317SStefano Zampini }
404b8ffe317SStefano Zampini 
405b8ffe317SStefano Zampini #undef __FUNCT__
406b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet"
407b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg)
4082b510759SStefano Zampini {
4092b510759SStefano Zampini   PetscErrorCode ierr;
4102b510759SStefano Zampini 
4112b510759SStefano Zampini   PetscFunctionBegin;
4122b510759SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
413b8ffe317SStefano Zampini   PetscValidLogicalCollectiveBool(pc,flg,2);
414b8ffe317SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr);
4152b510759SStefano Zampini   PetscFunctionReturn(0);
4162b510759SStefano Zampini }
4171e6b0712SBarry Smith 
4184fad6a16SStefano Zampini #undef __FUNCT__
4192b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel_BDDC"
4202b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level)
4214fad6a16SStefano Zampini {
4224fad6a16SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
4234fad6a16SStefano Zampini 
4244fad6a16SStefano Zampini   PetscFunctionBegin;
4252b510759SStefano Zampini   pcbddc->current_level = level;
4264fad6a16SStefano Zampini   PetscFunctionReturn(0);
4274fad6a16SStefano Zampini }
4281e6b0712SBarry Smith 
4294fad6a16SStefano Zampini #undef __FUNCT__
430b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel"
431b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level)
432b8ffe317SStefano Zampini {
433b8ffe317SStefano Zampini   PetscErrorCode ierr;
434b8ffe317SStefano Zampini 
435b8ffe317SStefano Zampini   PetscFunctionBegin;
436b8ffe317SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
437b8ffe317SStefano Zampini   PetscValidLogicalCollectiveInt(pc,level,2);
438b8ffe317SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr);
439b8ffe317SStefano Zampini   PetscFunctionReturn(0);
440b8ffe317SStefano Zampini }
441b8ffe317SStefano Zampini 
442b8ffe317SStefano Zampini #undef __FUNCT__
4432b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels_BDDC"
4442b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels)
4452b510759SStefano Zampini {
4462b510759SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
4472b510759SStefano Zampini 
4482b510759SStefano Zampini   PetscFunctionBegin;
4492b510759SStefano Zampini   pcbddc->max_levels = levels;
4502b510759SStefano Zampini   PetscFunctionReturn(0);
4512b510759SStefano Zampini }
4522b510759SStefano Zampini 
4532b510759SStefano Zampini #undef __FUNCT__
4542b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels"
4554fad6a16SStefano Zampini /*@
45628509bceSStefano Zampini  PCBDDCSetLevels - Sets the maximum number of levels for multilevel
4574fad6a16SStefano Zampini 
4584fad6a16SStefano Zampini    Logically collective on PC
4594fad6a16SStefano Zampini 
4604fad6a16SStefano Zampini    Input Parameters:
4614fad6a16SStefano Zampini +  pc - the preconditioning context
46228509bceSStefano Zampini -  levels - the maximum number of levels (max 9)
4634fad6a16SStefano Zampini 
4640f202f7eSStefano Zampini    Options Database Keys:
4650f202f7eSStefano Zampini .    -pc_bddc_levels
4664fad6a16SStefano Zampini 
4674fad6a16SStefano Zampini    Level: intermediate
4684fad6a16SStefano Zampini 
4694fad6a16SStefano Zampini    Notes:
4700f202f7eSStefano Zampini      Default value is 0, i.e. traditional one-level BDDC
4714fad6a16SStefano Zampini 
4720f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetCoarseningRatio()
4734fad6a16SStefano Zampini @*/
4742b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels)
4754fad6a16SStefano Zampini {
4764fad6a16SStefano Zampini   PetscErrorCode ierr;
4774fad6a16SStefano Zampini 
4784fad6a16SStefano Zampini   PetscFunctionBegin;
4794fad6a16SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
4802b510759SStefano Zampini   PetscValidLogicalCollectiveInt(pc,levels,2);
481312be037SStefano Zampini   if (levels > 99) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Maximum number of levels for bddc is 99\n");
4822b510759SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr);
4834fad6a16SStefano Zampini   PetscFunctionReturn(0);
4844fad6a16SStefano Zampini }
4854fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */
4861e6b0712SBarry Smith 
4874fad6a16SStefano Zampini #undef __FUNCT__
4880bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace_BDDC"
4890bdf917eSStefano Zampini static PetscErrorCode PCBDDCSetNullSpace_BDDC(PC pc,MatNullSpace NullSpace)
4900bdf917eSStefano Zampini {
4910bdf917eSStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
4920bdf917eSStefano Zampini   PetscErrorCode ierr;
4930bdf917eSStefano Zampini 
4940bdf917eSStefano Zampini   PetscFunctionBegin;
4950bdf917eSStefano Zampini   ierr = PetscObjectReference((PetscObject)NullSpace);CHKERRQ(ierr);
4960bdf917eSStefano Zampini   ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr);
4970bdf917eSStefano Zampini   pcbddc->NullSpace = NullSpace;
4980bdf917eSStefano Zampini   PetscFunctionReturn(0);
4990bdf917eSStefano Zampini }
5001e6b0712SBarry Smith 
5010bdf917eSStefano Zampini #undef __FUNCT__
5020bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace"
5030bdf917eSStefano Zampini /*@
50428509bceSStefano Zampini  PCBDDCSetNullSpace - Set nullspace for BDDC operator
5050bdf917eSStefano Zampini 
5060bdf917eSStefano Zampini    Logically collective on PC and MatNullSpace
5070bdf917eSStefano Zampini 
5080bdf917eSStefano Zampini    Input Parameters:
5090bdf917eSStefano Zampini +  pc - the preconditioning context
51028509bceSStefano Zampini -  NullSpace - Null space of the linear operator to be preconditioned (Pmat)
5110bdf917eSStefano Zampini 
5120bdf917eSStefano Zampini    Level: intermediate
5130bdf917eSStefano Zampini 
5140bdf917eSStefano Zampini    Notes:
5150bdf917eSStefano Zampini 
5160bdf917eSStefano Zampini .seealso: PCBDDC
5170bdf917eSStefano Zampini @*/
5180bdf917eSStefano Zampini PetscErrorCode PCBDDCSetNullSpace(PC pc,MatNullSpace NullSpace)
5190bdf917eSStefano Zampini {
5200bdf917eSStefano Zampini   PetscErrorCode ierr;
5210bdf917eSStefano Zampini 
5220bdf917eSStefano Zampini   PetscFunctionBegin;
5230bdf917eSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
524674ae819SStefano Zampini   PetscValidHeaderSpecific(NullSpace,MAT_NULLSPACE_CLASSID,2);
5252b510759SStefano Zampini   PetscCheckSameComm(pc,1,NullSpace,2);
5260bdf917eSStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetNullSpace_C",(PC,MatNullSpace),(pc,NullSpace));CHKERRQ(ierr);
5270bdf917eSStefano Zampini   PetscFunctionReturn(0);
5280bdf917eSStefano Zampini }
5290bdf917eSStefano Zampini /* -------------------------------------------------------------------------- */
5301e6b0712SBarry Smith 
5310bdf917eSStefano Zampini #undef __FUNCT__
5323b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC"
5333b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries)
5343b03a366Sstefano_zampini {
5353b03a366Sstefano_zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
53656282151SStefano Zampini   PetscBool      isequal = PETSC_FALSE;
5373b03a366Sstefano_zampini   PetscErrorCode ierr;
5383b03a366Sstefano_zampini 
5393b03a366Sstefano_zampini   PetscFunctionBegin;
54056282151SStefano Zampini   ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr);
54156282151SStefano Zampini   if (pcbddc->DirichletBoundaries) {
54256282151SStefano Zampini     ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundaries,&isequal);CHKERRQ(ierr);
54356282151SStefano Zampini   }
544785d1243SStefano Zampini   /* last user setting takes precendence -> destroy any other customization */
545785d1243SStefano Zampini   ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr);
5463b03a366Sstefano_zampini   ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr);
54736e030ebSStefano Zampini   pcbddc->DirichletBoundaries = DirichletBoundaries;
54856282151SStefano Zampini   if (!isequal) pcbddc->recompute_topography = PETSC_TRUE;
5493b03a366Sstefano_zampini   PetscFunctionReturn(0);
5503b03a366Sstefano_zampini }
5511e6b0712SBarry Smith 
5523b03a366Sstefano_zampini #undef __FUNCT__
5533b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries"
5543b03a366Sstefano_zampini /*@
55528509bceSStefano Zampini  PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem.
5563b03a366Sstefano_zampini 
557785d1243SStefano Zampini    Collective
5583b03a366Sstefano_zampini 
5593b03a366Sstefano_zampini    Input Parameters:
5603b03a366Sstefano_zampini +  pc - the preconditioning context
561785d1243SStefano Zampini -  DirichletBoundaries - parallel IS defining the Dirichlet boundaries
5623b03a366Sstefano_zampini 
5633b03a366Sstefano_zampini    Level: intermediate
5643b03a366Sstefano_zampini 
5650f202f7eSStefano Zampini    Notes:
5660f202f7eSStefano Zampini      Provide the information if you used MatZeroRows/Columns routines. Any process can list any global node
5673b03a366Sstefano_zampini 
5680f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundariesLocal(), MatZeroRows(), MatZeroRowsColumns()
5693b03a366Sstefano_zampini @*/
5703b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries)
5713b03a366Sstefano_zampini {
5723b03a366Sstefano_zampini   PetscErrorCode ierr;
5733b03a366Sstefano_zampini 
5743b03a366Sstefano_zampini   PetscFunctionBegin;
5753b03a366Sstefano_zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
576674ae819SStefano Zampini   PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2);
577785d1243SStefano Zampini   PetscCheckSameComm(pc,1,DirichletBoundaries,2);
5783b03a366Sstefano_zampini   ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr);
5793b03a366Sstefano_zampini   PetscFunctionReturn(0);
5803b03a366Sstefano_zampini }
5813b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */
5821e6b0712SBarry Smith 
5833b03a366Sstefano_zampini #undef __FUNCT__
58482ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal_BDDC"
58582ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries)
5860c7d97c5SJed Brown {
5870c7d97c5SJed Brown   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
58856282151SStefano Zampini   PetscBool      isequal = PETSC_FALSE;
5890c7d97c5SJed Brown   PetscErrorCode ierr;
5900c7d97c5SJed Brown 
5910c7d97c5SJed Brown   PetscFunctionBegin;
59256282151SStefano Zampini   ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr);
59356282151SStefano Zampini   if (pcbddc->DirichletBoundariesLocal) {
59456282151SStefano Zampini     ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundariesLocal,&isequal);CHKERRQ(ierr);
59556282151SStefano Zampini   }
596785d1243SStefano Zampini   /* last user setting takes precendence -> destroy any other customization */
597785d1243SStefano Zampini   ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr);
5980c7d97c5SJed Brown   ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr);
599785d1243SStefano Zampini   pcbddc->DirichletBoundariesLocal = DirichletBoundaries;
60056282151SStefano Zampini   if (!isequal) pcbddc->recompute_topography = PETSC_TRUE;
6010c7d97c5SJed Brown   PetscFunctionReturn(0);
6020c7d97c5SJed Brown }
6030c7d97c5SJed Brown 
6040c7d97c5SJed Brown #undef __FUNCT__
60582ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal"
6069c0446d6SStefano Zampini /*@
60782ba6b80SStefano Zampini  PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering.
6089c0446d6SStefano Zampini 
609785d1243SStefano Zampini    Collective
61053cdbc3dSStefano Zampini 
61153cdbc3dSStefano Zampini    Input Parameters:
61253cdbc3dSStefano Zampini +  pc - the preconditioning context
61382ba6b80SStefano Zampini -  DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering)
61453cdbc3dSStefano Zampini 
61553cdbc3dSStefano Zampini    Level: intermediate
61653cdbc3dSStefano Zampini 
6179c0446d6SStefano Zampini    Notes:
61853cdbc3dSStefano Zampini 
6190f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundaries(), MatZeroRows(), MatZeroRowsColumns()
62053cdbc3dSStefano Zampini @*/
62182ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries)
6220c7d97c5SJed Brown {
6230c7d97c5SJed Brown   PetscErrorCode ierr;
6240c7d97c5SJed Brown 
6250c7d97c5SJed Brown   PetscFunctionBegin;
6260c7d97c5SJed Brown   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
6270c7d97c5SJed Brown   PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2);
62882ba6b80SStefano Zampini   PetscCheckSameComm(pc,1,DirichletBoundaries,2);
62982ba6b80SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr);
6300c7d97c5SJed Brown   PetscFunctionReturn(0);
6310c7d97c5SJed Brown }
6320c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
6330c7d97c5SJed Brown 
6340c7d97c5SJed Brown #undef __FUNCT__
6350c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC"
63653cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries)
6370c7d97c5SJed Brown {
6380c7d97c5SJed Brown   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
63956282151SStefano Zampini   PetscBool      isequal = PETSC_FALSE;
64053cdbc3dSStefano Zampini   PetscErrorCode ierr;
6410c7d97c5SJed Brown 
6420c7d97c5SJed Brown   PetscFunctionBegin;
64356282151SStefano Zampini   ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr);
64456282151SStefano Zampini   if (pcbddc->NeumannBoundaries) {
64556282151SStefano Zampini     ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundaries,&isequal);CHKERRQ(ierr);
64656282151SStefano Zampini   }
647785d1243SStefano Zampini   /* last user setting takes precendence -> destroy any other customization */
648785d1243SStefano Zampini   ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr);
64953cdbc3dSStefano Zampini   ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr);
65036e030ebSStefano Zampini   pcbddc->NeumannBoundaries = NeumannBoundaries;
65156282151SStefano Zampini   if (!isequal) pcbddc->recompute_topography = PETSC_TRUE;
6520c7d97c5SJed Brown   PetscFunctionReturn(0);
6530c7d97c5SJed Brown }
6541e6b0712SBarry Smith 
6550c7d97c5SJed Brown #undef __FUNCT__
6560c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries"
65757527edcSJed Brown /*@
65828509bceSStefano Zampini  PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem.
65957527edcSJed Brown 
660785d1243SStefano Zampini    Collective
66157527edcSJed Brown 
66257527edcSJed Brown    Input Parameters:
66357527edcSJed Brown +  pc - the preconditioning context
664785d1243SStefano Zampini -  NeumannBoundaries - parallel IS defining the Neumann boundaries
66557527edcSJed Brown 
66657527edcSJed Brown    Level: intermediate
66757527edcSJed Brown 
6680f202f7eSStefano Zampini    Notes:
6690f202f7eSStefano Zampini      Any process can list any global node
67057527edcSJed Brown 
6710f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundariesLocal()
67257527edcSJed Brown @*/
67353cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries)
6740c7d97c5SJed Brown {
6750c7d97c5SJed Brown   PetscErrorCode ierr;
6760c7d97c5SJed Brown 
6770c7d97c5SJed Brown   PetscFunctionBegin;
6780c7d97c5SJed Brown   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
679674ae819SStefano Zampini   PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2);
680785d1243SStefano Zampini   PetscCheckSameComm(pc,1,NeumannBoundaries,2);
68153cdbc3dSStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr);
68253cdbc3dSStefano Zampini   PetscFunctionReturn(0);
68353cdbc3dSStefano Zampini }
68453cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */
6851e6b0712SBarry Smith 
68653cdbc3dSStefano Zampini #undef __FUNCT__
68782ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal_BDDC"
68882ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries)
6890c7d97c5SJed Brown {
6900c7d97c5SJed Brown   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
69156282151SStefano Zampini   PetscBool      isequal = PETSC_FALSE;
6920c7d97c5SJed Brown   PetscErrorCode ierr;
6930c7d97c5SJed Brown 
6940c7d97c5SJed Brown   PetscFunctionBegin;
69556282151SStefano Zampini   ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr);
69656282151SStefano Zampini   if (pcbddc->NeumannBoundariesLocal) {
69756282151SStefano Zampini     ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundariesLocal,&isequal);CHKERRQ(ierr);
69856282151SStefano Zampini   }
699785d1243SStefano Zampini   /* last user setting takes precendence -> destroy any other customization */
700785d1243SStefano Zampini   ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr);
7010c7d97c5SJed Brown   ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr);
702785d1243SStefano Zampini   pcbddc->NeumannBoundariesLocal = NeumannBoundaries;
70356282151SStefano Zampini   if (!isequal) pcbddc->recompute_topography = PETSC_TRUE;
7040c7d97c5SJed Brown   PetscFunctionReturn(0);
7050c7d97c5SJed Brown }
7060c7d97c5SJed Brown 
7070c7d97c5SJed Brown #undef __FUNCT__
70882ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal"
7090c7d97c5SJed Brown /*@
71082ba6b80SStefano Zampini  PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering.
7110c7d97c5SJed Brown 
712785d1243SStefano Zampini    Collective
7130c7d97c5SJed Brown 
7140c7d97c5SJed Brown    Input Parameters:
7150c7d97c5SJed Brown +  pc - the preconditioning context
71682ba6b80SStefano Zampini -  NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering)
7170c7d97c5SJed Brown 
7180c7d97c5SJed Brown    Level: intermediate
7190c7d97c5SJed Brown 
7200c7d97c5SJed Brown    Notes:
7210c7d97c5SJed Brown 
7220f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundaries()
7230c7d97c5SJed Brown @*/
72482ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries)
7250c7d97c5SJed Brown {
7260c7d97c5SJed Brown   PetscErrorCode ierr;
7270c7d97c5SJed Brown 
7280c7d97c5SJed Brown   PetscFunctionBegin;
7290c7d97c5SJed Brown   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
7300c7d97c5SJed Brown   PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2);
73182ba6b80SStefano Zampini   PetscCheckSameComm(pc,1,NeumannBoundaries,2);
73282ba6b80SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr);
73353cdbc3dSStefano Zampini   PetscFunctionReturn(0);
73453cdbc3dSStefano Zampini }
73553cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */
73653cdbc3dSStefano Zampini 
73753cdbc3dSStefano Zampini #undef __FUNCT__
738da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC"
739da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries)
740da1bb401SStefano Zampini {
741da1bb401SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
742da1bb401SStefano Zampini 
743da1bb401SStefano Zampini   PetscFunctionBegin;
744da1bb401SStefano Zampini   *DirichletBoundaries = pcbddc->DirichletBoundaries;
745da1bb401SStefano Zampini   PetscFunctionReturn(0);
746da1bb401SStefano Zampini }
7471e6b0712SBarry Smith 
748da1bb401SStefano Zampini #undef __FUNCT__
749da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries"
750da1bb401SStefano Zampini /*@
751785d1243SStefano Zampini  PCBDDCGetDirichletBoundaries - Get parallel IS for Dirichlet boundaries
752da1bb401SStefano Zampini 
753785d1243SStefano Zampini    Collective
754785d1243SStefano Zampini 
755785d1243SStefano Zampini    Input Parameters:
756785d1243SStefano Zampini .  pc - the preconditioning context
757785d1243SStefano Zampini 
758785d1243SStefano Zampini    Output Parameters:
759785d1243SStefano Zampini .  DirichletBoundaries - index set defining the Dirichlet boundaries
760785d1243SStefano Zampini 
761785d1243SStefano Zampini    Level: intermediate
762785d1243SStefano Zampini 
7630f202f7eSStefano Zampini    Notes:
7640f202f7eSStefano Zampini      The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetDirichletBoundaries
765785d1243SStefano Zampini 
766785d1243SStefano Zampini .seealso: PCBDDC
767785d1243SStefano Zampini @*/
768785d1243SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries)
769785d1243SStefano Zampini {
770785d1243SStefano Zampini   PetscErrorCode ierr;
771785d1243SStefano Zampini 
772785d1243SStefano Zampini   PetscFunctionBegin;
773785d1243SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
774785d1243SStefano Zampini   ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr);
775785d1243SStefano Zampini   PetscFunctionReturn(0);
776785d1243SStefano Zampini }
777785d1243SStefano Zampini /* -------------------------------------------------------------------------- */
778785d1243SStefano Zampini 
779785d1243SStefano Zampini #undef __FUNCT__
780785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal_BDDC"
781785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries)
782785d1243SStefano Zampini {
783785d1243SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
784785d1243SStefano Zampini 
785785d1243SStefano Zampini   PetscFunctionBegin;
786785d1243SStefano Zampini   *DirichletBoundaries = pcbddc->DirichletBoundariesLocal;
787785d1243SStefano Zampini   PetscFunctionReturn(0);
788785d1243SStefano Zampini }
789785d1243SStefano Zampini 
790785d1243SStefano Zampini #undef __FUNCT__
79182ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal"
792da1bb401SStefano Zampini /*@
79382ba6b80SStefano Zampini  PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering)
794da1bb401SStefano Zampini 
795785d1243SStefano Zampini    Collective
796da1bb401SStefano Zampini 
797da1bb401SStefano Zampini    Input Parameters:
79828509bceSStefano Zampini .  pc - the preconditioning context
799da1bb401SStefano Zampini 
800da1bb401SStefano Zampini    Output Parameters:
80128509bceSStefano Zampini .  DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries
802da1bb401SStefano Zampini 
803da1bb401SStefano Zampini    Level: intermediate
804da1bb401SStefano Zampini 
805da1bb401SStefano Zampini    Notes:
8060f202f7eSStefano Zampini      The IS returned could be the same passed in earlier by the user (if provided with PCBDDCSetDirichletBoundariesLocal) or a global-to-local map of the global IS (if provided with PCBDDCSetDirichletBoundaries).
8070f202f7eSStefano Zampini           In the latter case, the IS will be available after PCSetUp.
808da1bb401SStefano Zampini 
809da1bb401SStefano Zampini .seealso: PCBDDC
810da1bb401SStefano Zampini @*/
81182ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries)
812da1bb401SStefano Zampini {
813da1bb401SStefano Zampini   PetscErrorCode ierr;
814da1bb401SStefano Zampini 
815da1bb401SStefano Zampini   PetscFunctionBegin;
816da1bb401SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
81782ba6b80SStefano Zampini   ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr);
818da1bb401SStefano Zampini   PetscFunctionReturn(0);
819da1bb401SStefano Zampini }
820da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */
8211e6b0712SBarry Smith 
822da1bb401SStefano Zampini #undef __FUNCT__
82353cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC"
82453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries)
82553cdbc3dSStefano Zampini {
82653cdbc3dSStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
82753cdbc3dSStefano Zampini 
82853cdbc3dSStefano Zampini   PetscFunctionBegin;
82953cdbc3dSStefano Zampini   *NeumannBoundaries = pcbddc->NeumannBoundaries;
83053cdbc3dSStefano Zampini   PetscFunctionReturn(0);
83153cdbc3dSStefano Zampini }
8321e6b0712SBarry Smith 
83353cdbc3dSStefano Zampini #undef __FUNCT__
83453cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries"
83553cdbc3dSStefano Zampini /*@
836785d1243SStefano Zampini  PCBDDCGetNeumannBoundaries - Get parallel IS for Neumann boundaries
83753cdbc3dSStefano Zampini 
838785d1243SStefano Zampini    Collective
839785d1243SStefano Zampini 
840785d1243SStefano Zampini    Input Parameters:
841785d1243SStefano Zampini .  pc - the preconditioning context
842785d1243SStefano Zampini 
843785d1243SStefano Zampini    Output Parameters:
844785d1243SStefano Zampini .  NeumannBoundaries - index set defining the Neumann boundaries
845785d1243SStefano Zampini 
846785d1243SStefano Zampini    Level: intermediate
847785d1243SStefano Zampini 
8480f202f7eSStefano Zampini    Notes:
8490f202f7eSStefano Zampini      The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetNeumannBoundaries
850785d1243SStefano Zampini 
851785d1243SStefano Zampini .seealso: PCBDDC
852785d1243SStefano Zampini @*/
853785d1243SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries)
854785d1243SStefano Zampini {
855785d1243SStefano Zampini   PetscErrorCode ierr;
856785d1243SStefano Zampini 
857785d1243SStefano Zampini   PetscFunctionBegin;
858785d1243SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
859785d1243SStefano Zampini   ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr);
860785d1243SStefano Zampini   PetscFunctionReturn(0);
861785d1243SStefano Zampini }
862785d1243SStefano Zampini /* -------------------------------------------------------------------------- */
863785d1243SStefano Zampini 
864785d1243SStefano Zampini #undef __FUNCT__
865785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal_BDDC"
866785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries)
867785d1243SStefano Zampini {
868785d1243SStefano Zampini   PC_BDDC  *pcbddc = (PC_BDDC*)pc->data;
869785d1243SStefano Zampini 
870785d1243SStefano Zampini   PetscFunctionBegin;
871785d1243SStefano Zampini   *NeumannBoundaries = pcbddc->NeumannBoundariesLocal;
872785d1243SStefano Zampini   PetscFunctionReturn(0);
873785d1243SStefano Zampini }
874785d1243SStefano Zampini 
875785d1243SStefano Zampini #undef __FUNCT__
87682ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal"
87753cdbc3dSStefano Zampini /*@
87882ba6b80SStefano Zampini  PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering)
87953cdbc3dSStefano Zampini 
880785d1243SStefano Zampini    Collective
88153cdbc3dSStefano Zampini 
88253cdbc3dSStefano Zampini    Input Parameters:
88328509bceSStefano Zampini .  pc - the preconditioning context
88453cdbc3dSStefano Zampini 
88553cdbc3dSStefano Zampini    Output Parameters:
88628509bceSStefano Zampini .  NeumannBoundaries - index set defining the subdomain part of Neumann boundaries
88753cdbc3dSStefano Zampini 
88853cdbc3dSStefano Zampini    Level: intermediate
88953cdbc3dSStefano Zampini 
89053cdbc3dSStefano Zampini    Notes:
8910f202f7eSStefano Zampini      The IS returned could be the same passed in earlier by the user (if provided with PCBDDCSetNeumannBoundariesLocal) or a global-to-local map of the global IS (if provided with PCBDDCSetNeumannBoundaries).
8920f202f7eSStefano Zampini           In the latter case, the IS will be available after PCSetUp.
89353cdbc3dSStefano Zampini 
89453cdbc3dSStefano Zampini .seealso: PCBDDC
89553cdbc3dSStefano Zampini @*/
89682ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries)
89753cdbc3dSStefano Zampini {
89853cdbc3dSStefano Zampini   PetscErrorCode ierr;
89953cdbc3dSStefano Zampini 
90053cdbc3dSStefano Zampini   PetscFunctionBegin;
90153cdbc3dSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
90282ba6b80SStefano Zampini   ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr);
9030c7d97c5SJed Brown   PetscFunctionReturn(0);
9040c7d97c5SJed Brown }
90536e030ebSStefano Zampini /* -------------------------------------------------------------------------- */
9061e6b0712SBarry Smith 
90736e030ebSStefano Zampini #undef __FUNCT__
908da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC"
9091a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode)
91036e030ebSStefano Zampini {
91136e030ebSStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
912da1bb401SStefano Zampini   PCBDDCGraph    mat_graph = pcbddc->mat_graph;
91356282151SStefano Zampini   PetscBool      same_data = PETSC_FALSE;
914da1bb401SStefano Zampini   PetscErrorCode ierr;
91536e030ebSStefano Zampini 
91636e030ebSStefano Zampini   PetscFunctionBegin;
9178687889aSStefano Zampini   if (!nvtxs) {
9188687889aSStefano Zampini     ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr);
9198687889aSStefano Zampini     PetscFunctionReturn(0);
9208687889aSStefano Zampini   }
92156282151SStefano Zampini   if (mat_graph->nvtxs_csr == nvtxs) {
92256282151SStefano Zampini     if (mat_graph->xadj == xadj && mat_graph->adjncy == adjncy) same_data = PETSC_TRUE;
92356282151SStefano Zampini     if (!same_data && mat_graph->xadj[nvtxs] == xadj[nvtxs]) {
92456282151SStefano Zampini       ierr = PetscMemcmp(adjncy,mat_graph->adjncy,nvtxs*sizeof(PetscInt),&same_data);CHKERRQ(ierr);
92556282151SStefano Zampini     }
92656282151SStefano Zampini   }
92756282151SStefano Zampini   if (!same_data) {
928674ae819SStefano Zampini     /* free old CSR */
929674ae819SStefano Zampini     ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr);
930674ae819SStefano Zampini     /* get CSR into graph structure */
931da1bb401SStefano Zampini     if (copymode == PETSC_COPY_VALUES) {
932854ce69bSBarry Smith       ierr = PetscMalloc1(nvtxs+1,&mat_graph->xadj);CHKERRQ(ierr);
933785e854fSJed Brown       ierr = PetscMalloc1(xadj[nvtxs],&mat_graph->adjncy);CHKERRQ(ierr);
934674ae819SStefano Zampini       ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr);
935674ae819SStefano Zampini       ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr);
936da1bb401SStefano Zampini     } else if (copymode == PETSC_OWN_POINTER) {
9371a83f524SJed Brown       mat_graph->xadj = (PetscInt*)xadj;
9381a83f524SJed Brown       mat_graph->adjncy = (PetscInt*)adjncy;
939674ae819SStefano Zampini     }
940575ad6abSStefano Zampini     mat_graph->nvtxs_csr = nvtxs;
94156282151SStefano Zampini     pcbddc->recompute_topography = PETSC_TRUE;
94256282151SStefano Zampini   }
94336e030ebSStefano Zampini   PetscFunctionReturn(0);
94436e030ebSStefano Zampini }
9451e6b0712SBarry Smith 
94636e030ebSStefano Zampini #undef __FUNCT__
947da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph"
94836e030ebSStefano Zampini /*@
9490f202f7eSStefano Zampini  PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local matrix
95036e030ebSStefano Zampini 
95136e030ebSStefano Zampini    Not collective
95236e030ebSStefano Zampini 
95336e030ebSStefano Zampini    Input Parameters:
95436e030ebSStefano Zampini +  pc - the preconditioning context
9550f202f7eSStefano Zampini .  nvtxs - number of local vertices of the graph (i.e., the size of the local problem)
95628509bceSStefano Zampini .  xadj, adjncy - the CSR graph
95728509bceSStefano Zampini -  copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER.
95836e030ebSStefano Zampini 
95936e030ebSStefano Zampini    Level: intermediate
96036e030ebSStefano Zampini 
96136e030ebSStefano Zampini    Notes:
96236e030ebSStefano Zampini 
96328509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode
96436e030ebSStefano Zampini @*/
9651a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode)
96636e030ebSStefano Zampini {
967575ad6abSStefano Zampini   void (*f)(void) = 0;
96836e030ebSStefano Zampini   PetscErrorCode ierr;
96936e030ebSStefano Zampini 
97036e030ebSStefano Zampini   PetscFunctionBegin;
97136e030ebSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
9728687889aSStefano Zampini   if (nvtxs) {
973674ae819SStefano Zampini     PetscValidIntPointer(xadj,3);
974d7de1dd9SStefano Zampini     PetscValidIntPointer(adjncy,4);
9758687889aSStefano Zampini   }
9766c4ed002SBarry Smith   if (copymode != PETSC_COPY_VALUES && copymode != PETSC_OWN_POINTER)  SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d",copymode);
9771a83f524SJed Brown   ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr);
978575ad6abSStefano Zampini   /* free arrays if PCBDDC is not the PC type */
979575ad6abSStefano Zampini   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr);
980575ad6abSStefano Zampini   if (!f && copymode == PETSC_OWN_POINTER) {
981575ad6abSStefano Zampini     ierr = PetscFree(xadj);CHKERRQ(ierr);
982575ad6abSStefano Zampini     ierr = PetscFree(adjncy);CHKERRQ(ierr);
983da1bb401SStefano Zampini   }
98436e030ebSStefano Zampini   PetscFunctionReturn(0);
98536e030ebSStefano Zampini }
9869c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */
9871e6b0712SBarry Smith 
9889c0446d6SStefano Zampini #undef __FUNCT__
98963602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal_BDDC"
99063602bcaSStefano Zampini static PetscErrorCode PCBDDCSetDofsSplittingLocal_BDDC(PC pc,PetscInt n_is, IS ISForDofs[])
99163602bcaSStefano Zampini {
99263602bcaSStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
99363602bcaSStefano Zampini   PetscInt       i;
99456282151SStefano Zampini   PetscBool      isequal = PETSC_FALSE;
99563602bcaSStefano Zampini   PetscErrorCode ierr;
99663602bcaSStefano Zampini 
99763602bcaSStefano Zampini   PetscFunctionBegin;
99856282151SStefano Zampini   if (pcbddc->n_ISForDofsLocal == n_is) {
99956282151SStefano Zampini     for (i=0;i<n_is;i++) {
100056282151SStefano Zampini       PetscBool isequalt;
100156282151SStefano Zampini       ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofsLocal[i],&isequalt);CHKERRQ(ierr);
100256282151SStefano Zampini       if (!isequalt) break;
100356282151SStefano Zampini     }
100456282151SStefano Zampini     if (i == n_is) isequal = PETSC_TRUE;
100556282151SStefano Zampini   }
100656282151SStefano Zampini   for (i=0;i<n_is;i++) {
100756282151SStefano Zampini     ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr);
100856282151SStefano Zampini   }
100963602bcaSStefano Zampini   /* Destroy ISes if they were already set */
101063602bcaSStefano Zampini   for (i=0;i<pcbddc->n_ISForDofsLocal;i++) {
101163602bcaSStefano Zampini     ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr);
101263602bcaSStefano Zampini   }
101363602bcaSStefano Zampini   ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr);
101463602bcaSStefano Zampini   /* last user setting takes precendence -> destroy any other customization */
101563602bcaSStefano Zampini   for (i=0;i<pcbddc->n_ISForDofs;i++) {
101663602bcaSStefano Zampini     ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr);
101763602bcaSStefano Zampini   }
101863602bcaSStefano Zampini   ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr);
101963602bcaSStefano Zampini   pcbddc->n_ISForDofs = 0;
102063602bcaSStefano Zampini   /* allocate space then set */
1021d02579f5SStefano Zampini   if (n_is) {
1022d02579f5SStefano Zampini     ierr = PetscMalloc1(n_is,&pcbddc->ISForDofsLocal);CHKERRQ(ierr);
1023d02579f5SStefano Zampini   }
102463602bcaSStefano Zampini   for (i=0;i<n_is;i++) {
102563602bcaSStefano Zampini     pcbddc->ISForDofsLocal[i] = ISForDofs[i];
102663602bcaSStefano Zampini   }
102763602bcaSStefano Zampini   pcbddc->n_ISForDofsLocal = n_is;
102863602bcaSStefano Zampini   if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE;
102956282151SStefano Zampini   if (!isequal) pcbddc->recompute_topography = PETSC_TRUE;
103063602bcaSStefano Zampini   PetscFunctionReturn(0);
103163602bcaSStefano Zampini }
103263602bcaSStefano Zampini 
103363602bcaSStefano Zampini #undef __FUNCT__
103463602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal"
103563602bcaSStefano Zampini /*@
103663602bcaSStefano Zampini  PCBDDCSetDofsSplittingLocal - Set index sets defining fields of the local subdomain matrix
103763602bcaSStefano Zampini 
103863602bcaSStefano Zampini    Collective
103963602bcaSStefano Zampini 
104063602bcaSStefano Zampini    Input Parameters:
104163602bcaSStefano Zampini +  pc - the preconditioning context
10420f202f7eSStefano Zampini .  n_is - number of index sets defining the fields
10430f202f7eSStefano Zampini -  ISForDofs - array of IS describing the fields in local ordering
104463602bcaSStefano Zampini 
104563602bcaSStefano Zampini    Level: intermediate
104663602bcaSStefano Zampini 
10470f202f7eSStefano Zampini    Notes:
10480f202f7eSStefano Zampini      n_is should be the same among processes. Not all nodes need to be listed: unlisted nodes will belong to the complement field.
104963602bcaSStefano Zampini 
105063602bcaSStefano Zampini .seealso: PCBDDC
105163602bcaSStefano Zampini @*/
105263602bcaSStefano Zampini PetscErrorCode PCBDDCSetDofsSplittingLocal(PC pc,PetscInt n_is, IS ISForDofs[])
105363602bcaSStefano Zampini {
105463602bcaSStefano Zampini   PetscInt       i;
105563602bcaSStefano Zampini   PetscErrorCode ierr;
105663602bcaSStefano Zampini 
105763602bcaSStefano Zampini   PetscFunctionBegin;
105863602bcaSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
105963602bcaSStefano Zampini   PetscValidLogicalCollectiveInt(pc,n_is,2);
106063602bcaSStefano Zampini   for (i=0;i<n_is;i++) {
106163602bcaSStefano Zampini     PetscCheckSameComm(pc,1,ISForDofs[i],3);
106263602bcaSStefano Zampini     PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3);
106363602bcaSStefano Zampini   }
1064e71e7a71SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplittingLocal_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr);
106563602bcaSStefano Zampini   PetscFunctionReturn(0);
106663602bcaSStefano Zampini }
106763602bcaSStefano Zampini /* -------------------------------------------------------------------------- */
106863602bcaSStefano Zampini 
106963602bcaSStefano Zampini #undef __FUNCT__
10709c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC"
10719c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[])
10729c0446d6SStefano Zampini {
10739c0446d6SStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
10749c0446d6SStefano Zampini   PetscInt       i;
107556282151SStefano Zampini   PetscBool      isequal = PETSC_FALSE;
10769c0446d6SStefano Zampini   PetscErrorCode ierr;
10779c0446d6SStefano Zampini 
10789c0446d6SStefano Zampini   PetscFunctionBegin;
107956282151SStefano Zampini   if (pcbddc->n_ISForDofs == n_is) {
108056282151SStefano Zampini     for (i=0;i<n_is;i++) {
108156282151SStefano Zampini       PetscBool isequalt;
108256282151SStefano Zampini       ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofs[i],&isequalt);CHKERRQ(ierr);
108356282151SStefano Zampini       if (!isequalt) break;
108456282151SStefano Zampini     }
108556282151SStefano Zampini     if (i == n_is) isequal = PETSC_TRUE;
108656282151SStefano Zampini   }
108756282151SStefano Zampini   for (i=0;i<n_is;i++) {
108856282151SStefano Zampini     ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr);
108956282151SStefano Zampini   }
1090da1bb401SStefano Zampini   /* Destroy ISes if they were already set */
10919c0446d6SStefano Zampini   for (i=0;i<pcbddc->n_ISForDofs;i++) {
10929c0446d6SStefano Zampini     ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr);
10939c0446d6SStefano Zampini   }
1094d11ae9bbSstefano_zampini   ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr);
109563602bcaSStefano Zampini   /* last user setting takes precendence -> destroy any other customization */
109663602bcaSStefano Zampini   for (i=0;i<pcbddc->n_ISForDofsLocal;i++) {
109763602bcaSStefano Zampini     ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr);
109863602bcaSStefano Zampini   }
109963602bcaSStefano Zampini   ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr);
110063602bcaSStefano Zampini   pcbddc->n_ISForDofsLocal = 0;
1101da1bb401SStefano Zampini   /* allocate space then set */
1102d02579f5SStefano Zampini   if (n_is) {
1103785e854fSJed Brown     ierr = PetscMalloc1(n_is,&pcbddc->ISForDofs);CHKERRQ(ierr);
1104d02579f5SStefano Zampini   }
11059c0446d6SStefano Zampini   for (i=0;i<n_is;i++) {
1106da1bb401SStefano Zampini     pcbddc->ISForDofs[i] = ISForDofs[i];
11079c0446d6SStefano Zampini   }
11089c0446d6SStefano Zampini   pcbddc->n_ISForDofs = n_is;
110963602bcaSStefano Zampini   if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE;
111056282151SStefano Zampini   if (!isequal) pcbddc->recompute_topography = PETSC_TRUE;
11119c0446d6SStefano Zampini   PetscFunctionReturn(0);
11129c0446d6SStefano Zampini }
11131e6b0712SBarry Smith 
11149c0446d6SStefano Zampini #undef __FUNCT__
11159c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting"
11169c0446d6SStefano Zampini /*@
111763602bcaSStefano Zampini  PCBDDCSetDofsSplitting - Set index sets defining fields of the global matrix
11189c0446d6SStefano Zampini 
111963602bcaSStefano Zampini    Collective
11209c0446d6SStefano Zampini 
11219c0446d6SStefano Zampini    Input Parameters:
11229c0446d6SStefano Zampini +  pc - the preconditioning context
11230f202f7eSStefano Zampini .  n_is - number of index sets defining the fields
11240f202f7eSStefano Zampini -  ISForDofs - array of IS describing the fields in global ordering
11259c0446d6SStefano Zampini 
11269c0446d6SStefano Zampini    Level: intermediate
11279c0446d6SStefano Zampini 
11280f202f7eSStefano Zampini    Notes:
11290f202f7eSStefano Zampini      Any process can list any global node. Not all nodes need to be listed: unlisted nodes will belong to the complement field.
11309c0446d6SStefano Zampini 
11319c0446d6SStefano Zampini .seealso: PCBDDC
11329c0446d6SStefano Zampini @*/
11339c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[])
11349c0446d6SStefano Zampini {
11352b510759SStefano Zampini   PetscInt       i;
11369c0446d6SStefano Zampini   PetscErrorCode ierr;
11379c0446d6SStefano Zampini 
11389c0446d6SStefano Zampini   PetscFunctionBegin;
11399c0446d6SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
114063602bcaSStefano Zampini   PetscValidLogicalCollectiveInt(pc,n_is,2);
11412b510759SStefano Zampini   for (i=0;i<n_is;i++) {
114263602bcaSStefano Zampini     PetscCheckSameComm(pc,1,ISForDofs[i],3);
114363602bcaSStefano Zampini     PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3);
11442b510759SStefano Zampini   }
11459c0446d6SStefano Zampini   ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr);
11469c0446d6SStefano Zampini   PetscFunctionReturn(0);
11479c0446d6SStefano Zampini }
1148906d46d4SStefano Zampini 
1149da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */
1150534831adSStefano Zampini #undef __FUNCT__
1151534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC"
1152534831adSStefano Zampini /* -------------------------------------------------------------------------- */
1153534831adSStefano Zampini /*
1154534831adSStefano Zampini    PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial
1155534831adSStefano Zampini                      guess if a transformation of basis approach has been selected.
11569c0446d6SStefano Zampini 
1157534831adSStefano Zampini    Input Parameter:
1158534831adSStefano Zampini +  pc - the preconditioner contex
1159534831adSStefano Zampini 
1160534831adSStefano Zampini    Application Interface Routine: PCPreSolve()
1161534831adSStefano Zampini 
1162534831adSStefano Zampini    Notes:
1163534831adSStefano Zampini      The interface routine PCPreSolve() is not usually called directly by
1164534831adSStefano Zampini    the user, but instead is called by KSPSolve().
1165534831adSStefano Zampini */
1166534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x)
1167534831adSStefano Zampini {
1168534831adSStefano Zampini   PetscErrorCode ierr;
1169534831adSStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
1170534831adSStefano Zampini   PC_IS          *pcis = (PC_IS*)(pc->data);
11713972b0daSStefano Zampini   Vec            used_vec;
11728d00608fSStefano Zampini   PetscBool      copy_rhs = PETSC_TRUE;
1173a3df083aSStefano Zampini   PetscBool      iscg = PETSC_FALSE;
1174534831adSStefano Zampini 
1175534831adSStefano Zampini   PetscFunctionBegin;
117685c4d303SStefano Zampini   /* if we are working with cg, one dirichlet solve can be avoided during Krylov iterations */
117785c4d303SStefano Zampini   if (ksp) {
117885c4d303SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr);
117916909a7fSStefano Zampini     if (!iscg || pcbddc->switch_static) {
118085c4d303SStefano Zampini       ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr);
118185c4d303SStefano Zampini     }
118285c4d303SStefano Zampini   }
118385c4d303SStefano Zampini   /* Creates parallel work vectors used in presolve */
118462a6ff1dSStefano Zampini   if (!pcbddc->original_rhs) {
118562a6ff1dSStefano Zampini     ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr);
118662a6ff1dSStefano Zampini   }
118762a6ff1dSStefano Zampini   if (!pcbddc->temp_solution) {
118862a6ff1dSStefano Zampini     ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr);
118962a6ff1dSStefano Zampini   }
11908d00608fSStefano Zampini 
11911dd7afcfSStefano Zampini   ierr = VecSet(pcbddc->temp_solution,0.);CHKERRQ(ierr);
11923972b0daSStefano Zampini   if (x) {
11933972b0daSStefano Zampini     ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);
11943972b0daSStefano Zampini     used_vec = x;
11958d00608fSStefano Zampini   } else { /* it can only happen when calling PCBDDCMatFETIDPGetRHS */
11963972b0daSStefano Zampini     ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr);
11973972b0daSStefano Zampini     used_vec = pcbddc->temp_solution;
11983972b0daSStefano Zampini     ierr = VecSet(used_vec,0.0);CHKERRQ(ierr);
11993972b0daSStefano Zampini   }
12008efcfb23SStefano Zampini 
12018efcfb23SStefano Zampini   /* hack into ksp data structure since PCPreSolve comes earlier than setting to zero the guess in src/ksp/ksp/interface/itfunc.c */
12023972b0daSStefano Zampini   if (ksp) {
1203a0cb1b98SStefano Zampini     /* store the flag for the initial guess since it will be restored back during PCPostSolve_BDDC */
12048efcfb23SStefano Zampini     ierr = KSPGetInitialGuessNonzero(ksp,&pcbddc->ksp_guess_nonzero);CHKERRQ(ierr);
12058efcfb23SStefano Zampini     if (!pcbddc->ksp_guess_nonzero) {
12063972b0daSStefano Zampini       ierr = VecSet(used_vec,0.0);CHKERRQ(ierr);
12073972b0daSStefano Zampini     }
12083972b0daSStefano Zampini   }
12093308cffdSStefano Zampini 
12108d00608fSStefano Zampini   pcbddc->rhs_change = PETSC_FALSE;
12113972b0daSStefano Zampini   /* Take into account zeroed rows -> change rhs and store solution removed */
121270c64980SStefano Zampini   if (rhs && pcbddc->eliminate_dirdofs) {
12133975b054SStefano Zampini     IS dirIS = NULL;
12143975b054SStefano Zampini 
1215a07ea27aSStefano Zampini     /* DirichletBoundariesLocal may not be consistent among neighbours; gets a dirichlet dofs IS from graph (may be cached) */
12163975b054SStefano Zampini     ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr);
12173975b054SStefano Zampini     if (dirIS) {
1218906d46d4SStefano Zampini       Mat_IS            *matis = (Mat_IS*)pc->pmat->data;
1219785d1243SStefano Zampini       PetscInt          dirsize,i,*is_indices;
12202b095fd8SStefano Zampini       PetscScalar       *array_x;
12212b095fd8SStefano Zampini       const PetscScalar *array_diagonal;
1222785d1243SStefano Zampini 
12233972b0daSStefano Zampini       ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr);
12243972b0daSStefano Zampini       ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr);
1225e176bc59SStefano Zampini       ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1226e176bc59SStefano Zampini       ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1227e176bc59SStefano Zampini       ierr = VecScatterBegin(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1228e176bc59SStefano Zampini       ierr = VecScatterEnd(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
122982ba6b80SStefano Zampini       ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr);
12303972b0daSStefano Zampini       ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr);
12312b095fd8SStefano Zampini       ierr = VecGetArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr);
12323972b0daSStefano Zampini       ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr);
12332fa5cd67SKarl Rupp       for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]];
12343972b0daSStefano Zampini       ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr);
12352b095fd8SStefano Zampini       ierr = VecRestoreArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr);
12363972b0daSStefano Zampini       ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr);
1237e176bc59SStefano Zampini       ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1238e176bc59SStefano Zampini       ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
12398d00608fSStefano Zampini       pcbddc->rhs_change = PETSC_TRUE;
12401b968477SStefano Zampini       ierr = ISDestroy(&dirIS);CHKERRQ(ierr);
12418efcfb23SStefano Zampini     }
1242a07ea27aSStefano Zampini   }
1243b76ba322SStefano Zampini 
12448efcfb23SStefano Zampini   /* remove the computed solution or the initial guess from the rhs */
12458d00608fSStefano Zampini   if (pcbddc->rhs_change || (ksp && pcbddc->ksp_guess_nonzero) ) {
12468d00608fSStefano Zampini     /* store the original rhs */
12478d00608fSStefano Zampini     if (copy_rhs) {
12488d00608fSStefano Zampini       ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr);
12498d00608fSStefano Zampini       copy_rhs = PETSC_FALSE;
12508d00608fSStefano Zampini     }
12518d00608fSStefano Zampini     pcbddc->rhs_change = PETSC_TRUE;
12523972b0daSStefano Zampini     ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr);
12530369aaf7SStefano Zampini     ierr = MatMultAdd(pc->mat,used_vec,rhs,rhs);CHKERRQ(ierr);
12543972b0daSStefano Zampini     ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr);
12558efcfb23SStefano Zampini     ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr);
12567acc28cbSStefano Zampini     if (ksp) {
12577acc28cbSStefano Zampini       ierr = KSPSetInitialGuessNonzero(ksp,PETSC_FALSE);CHKERRQ(ierr);
12587acc28cbSStefano Zampini     }
12593308cffdSStefano Zampini   }
12608efcfb23SStefano Zampini   ierr = VecDestroy(&used_vec);CHKERRQ(ierr);
1261b76ba322SStefano Zampini 
12621dd7afcfSStefano Zampini   /* compute initial vector in benign space (TODO: what about FETI-DP?)*/
12630369aaf7SStefano Zampini   if (rhs && pcbddc->benign_saddle_point) {
12640369aaf7SStefano Zampini     /* compute u^*_h as in Xuemin Tu's thesis (see Section 4.8.1) */
12650369aaf7SStefano Zampini     if (!pcbddc->benign_vec) {
12660369aaf7SStefano Zampini       ierr = VecDuplicate(rhs,&pcbddc->benign_vec);CHKERRQ(ierr);
12670369aaf7SStefano Zampini     }
12684fee134fSStefano Zampini     pcbddc->benign_apply_coarse_only = PETSC_TRUE;
12691dd7afcfSStefano Zampini     ierr = PCApply_BDDC(pc,rhs,pcbddc->benign_vec);CHKERRQ(ierr);
12704fee134fSStefano Zampini     pcbddc->benign_apply_coarse_only = PETSC_FALSE;
12711dd7afcfSStefano Zampini     /* TODO: what about Stokes? */
12721dd7afcfSStefano Zampini #if 0
12731dd7afcfSStefano Zampini     ierr = VecNorm(pcbddc->benign_vec,NORM_INFINITY,&norm);CHKERRQ(ierr);
12741dd7afcfSStefano Zampini     if (norm < PETSC_SMALL) benign_correction_is_zero = PETSC_TRUE;
12751dd7afcfSStefano Zampini #endif
127692e3dcfbSStefano Zampini   }
127792e3dcfbSStefano Zampini 
12780369aaf7SStefano Zampini   /* remove non-benign solution from the rhs */
12790369aaf7SStefano Zampini   if (pcbddc->benign_saddle_point) {
12800369aaf7SStefano Zampini     /* store the original rhs */
12810369aaf7SStefano Zampini     if (copy_rhs) {
12820369aaf7SStefano Zampini       ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr);
12830369aaf7SStefano Zampini       copy_rhs = PETSC_FALSE;
12840369aaf7SStefano Zampini     }
12851dd7afcfSStefano Zampini     /* this code is disabled, until I test against incompressible Stokes */
12861dd7afcfSStefano Zampini #if 0
128751694757SStefano Zampini     if (benign_correction_is_zero) { /* still need to understand why it works great */
128851694757SStefano Zampini       ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr);
128951694757SStefano Zampini       ierr = PCApply_BDDC(pc,rhs,pcbddc->benign_vec);CHKERRQ(ierr);
129051694757SStefano Zampini     }
12911dd7afcfSStefano Zampini #endif
12920369aaf7SStefano Zampini     ierr = VecScale(pcbddc->benign_vec,-1.0);CHKERRQ(ierr);
12930369aaf7SStefano Zampini     ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,rhs,rhs);CHKERRQ(ierr);
12940369aaf7SStefano Zampini     pcbddc->rhs_change = PETSC_TRUE;
12951dd7afcfSStefano Zampini     ierr = VecAXPY(pcbddc->temp_solution,-1.0,pcbddc->benign_vec);CHKERRQ(ierr);
12960369aaf7SStefano Zampini   }
12970369aaf7SStefano Zampini 
12980369aaf7SStefano Zampini   /* set initial guess if using PCG */
12990369aaf7SStefano Zampini   if (x && pcbddc->use_exact_dirichlet_trick) {
13000369aaf7SStefano Zampini     ierr = VecSet(x,0.0);CHKERRQ(ierr);
13011dd7afcfSStefano Zampini     if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) {
13021dd7afcfSStefano Zampini       if (pcbddc->benign_saddle_point) { /* we have already saved the changed rhs */
13031dd7afcfSStefano Zampini         ierr = VecLockPop(pcis->vec1_global);CHKERRQ(ierr);
13041dd7afcfSStefano Zampini       } else {
13051dd7afcfSStefano Zampini         ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,pcis->vec1_global);CHKERRQ(ierr);
13061dd7afcfSStefano Zampini       }
13071dd7afcfSStefano Zampini       ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
13081dd7afcfSStefano Zampini       ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
13091dd7afcfSStefano Zampini     } else {
13100369aaf7SStefano Zampini       ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
13110369aaf7SStefano Zampini       ierr = VecScatterEnd(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
13121dd7afcfSStefano Zampini     }
13130369aaf7SStefano Zampini     ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr);
13141dd7afcfSStefano Zampini     if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) {
13151dd7afcfSStefano Zampini       ierr = VecSet(pcis->vec1_global,0.);CHKERRQ(ierr);
13161dd7afcfSStefano Zampini       ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
13171dd7afcfSStefano Zampini       ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
13181dd7afcfSStefano Zampini       ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x);CHKERRQ(ierr);
13191dd7afcfSStefano Zampini     } else {
13200369aaf7SStefano Zampini       ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
13210369aaf7SStefano Zampini       ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
13221dd7afcfSStefano Zampini     }
13230369aaf7SStefano Zampini     if (ksp) {
13240369aaf7SStefano Zampini       ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr);
13250369aaf7SStefano Zampini     }
13260369aaf7SStefano Zampini   }
1327534831adSStefano Zampini   PetscFunctionReturn(0);
1328534831adSStefano Zampini }
1329906d46d4SStefano Zampini 
1330534831adSStefano Zampini /* -------------------------------------------------------------------------- */
1331534831adSStefano Zampini #undef __FUNCT__
1332534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC"
1333534831adSStefano Zampini /* -------------------------------------------------------------------------- */
1334534831adSStefano Zampini /*
1335534831adSStefano Zampini    PCPostSolve_BDDC - Changes the computed solution if a transformation of basis
1336534831adSStefano Zampini                      approach has been selected. Also, restores rhs to its original state.
1337534831adSStefano Zampini 
1338534831adSStefano Zampini    Input Parameter:
1339534831adSStefano Zampini +  pc - the preconditioner contex
1340534831adSStefano Zampini 
1341534831adSStefano Zampini    Application Interface Routine: PCPostSolve()
1342534831adSStefano Zampini 
1343534831adSStefano Zampini    Notes:
1344534831adSStefano Zampini      The interface routine PCPostSolve() is not usually called directly by
1345534831adSStefano Zampini      the user, but instead is called by KSPSolve().
1346534831adSStefano Zampini */
1347534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x)
1348534831adSStefano Zampini {
1349534831adSStefano Zampini   PetscErrorCode ierr;
1350534831adSStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
1351534831adSStefano Zampini 
1352534831adSStefano Zampini   PetscFunctionBegin;
13533972b0daSStefano Zampini   /* add solution removed in presolve */
13546bcfc461SStefano Zampini   if (x && pcbddc->rhs_change) {
13553425bc38SStefano Zampini     ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr);
13563425bc38SStefano Zampini   }
1357fb223d50SStefano Zampini   /* restore rhs to its original state */
13588d00608fSStefano Zampini   if (rhs && pcbddc->rhs_change) {
1359fb223d50SStefano Zampini     ierr = VecCopy(pcbddc->original_rhs,rhs);CHKERRQ(ierr);
1360fb223d50SStefano Zampini   }
13618d00608fSStefano Zampini   pcbddc->rhs_change = PETSC_FALSE;
13628efcfb23SStefano Zampini   /* restore ksp guess state */
13638efcfb23SStefano Zampini   if (ksp) {
13648efcfb23SStefano Zampini     ierr = KSPSetInitialGuessNonzero(ksp,pcbddc->ksp_guess_nonzero);CHKERRQ(ierr);
13658efcfb23SStefano Zampini   }
1366534831adSStefano Zampini   PetscFunctionReturn(0);
1367534831adSStefano Zampini }
1368534831adSStefano Zampini /* -------------------------------------------------------------------------- */
136953cdbc3dSStefano Zampini #undef __FUNCT__
137053cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC"
13710c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
13720c7d97c5SJed Brown /*
13730c7d97c5SJed Brown    PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner
13740c7d97c5SJed Brown                   by setting data structures and options.
13750c7d97c5SJed Brown 
13760c7d97c5SJed Brown    Input Parameter:
137753cdbc3dSStefano Zampini +  pc - the preconditioner context
13780c7d97c5SJed Brown 
13790c7d97c5SJed Brown    Application Interface Routine: PCSetUp()
13800c7d97c5SJed Brown 
13810c7d97c5SJed Brown    Notes:
13820c7d97c5SJed Brown      The interface routine PCSetUp() is not usually called directly by
13830c7d97c5SJed Brown      the user, but instead is called by PCApply() if necessary.
13840c7d97c5SJed Brown */
138553cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc)
13860c7d97c5SJed Brown {
13870c7d97c5SJed Brown   PetscErrorCode ierr;
13880c7d97c5SJed Brown   PC_BDDC*       pcbddc = (PC_BDDC*)pc->data;
13895e8657edSStefano Zampini   Mat_IS*        matis;
139008122e43SStefano Zampini   MatNullSpace   nearnullspace;
1391c9ed8603SStefano Zampini   IS             zerodiag = NULL;
139291e8d312SStefano Zampini   PetscInt       nrows,ncols;
139308122e43SStefano Zampini   PetscBool      computetopography,computesolvers,computesubschurs;
13948de1fae6SStefano Zampini   PetscBool      computeconstraintsmatrix;
13955e8657edSStefano Zampini   PetscBool      new_nearnullspace_provided,ismatis;
13960c7d97c5SJed Brown 
13970c7d97c5SJed Brown   PetscFunctionBegin;
13985e8657edSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATIS,&ismatis);CHKERRQ(ierr);
13996c4ed002SBarry Smith   if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner requires matrix of type MATIS");
140091e8d312SStefano Zampini   ierr = MatGetSize(pc->pmat,&nrows,&ncols);CHKERRQ(ierr);
14016c4ed002SBarry Smith   if (nrows != ncols) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PCBDDC preconditioner requires a square preconditioning matrix");
14025e8657edSStefano Zampini   matis = (Mat_IS*)pc->pmat->data;
1403f4ddd8eeSStefano Zampini   /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other future nonoverlapping preconditioners */
14043b03a366Sstefano_zampini   /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup
1405fcd409f5SStefano Zampini      Also, BDDC directly build the Dirichlet problem */
1406f4ddd8eeSStefano Zampini   /* split work */
1407674ae819SStefano Zampini   if (pc->setupcalled) {
1408d1e9a80fSBarry Smith     if (pc->flag == SAME_NONZERO_PATTERN) {
1409674ae819SStefano Zampini       computetopography = PETSC_FALSE;
1410674ae819SStefano Zampini       computesolvers = PETSC_TRUE;
1411674ae819SStefano Zampini     } else { /* DIFFERENT_NONZERO_PATTERN */
1412674ae819SStefano Zampini       computetopography = PETSC_TRUE;
1413674ae819SStefano Zampini       computesolvers = PETSC_TRUE;
1414674ae819SStefano Zampini     }
1415674ae819SStefano Zampini   } else {
1416674ae819SStefano Zampini     computetopography = PETSC_TRUE;
1417674ae819SStefano Zampini     computesolvers = PETSC_TRUE;
1418674ae819SStefano Zampini   }
1419fb180af4SStefano Zampini   if (pcbddc->recompute_topography) {
1420fb180af4SStefano Zampini     computetopography = PETSC_TRUE;
1421fb180af4SStefano Zampini   }
142256282151SStefano Zampini   pcbddc->recompute_topography = computetopography;
14238de1fae6SStefano Zampini   computeconstraintsmatrix = PETSC_FALSE;
1424b087196eSStefano Zampini 
1425b087196eSStefano Zampini   /* check parameters' compatibility */
1426b7ab4a40SStefano Zampini   if (!pcbddc->use_deluxe_scaling) pcbddc->deluxe_zerorows = PETSC_FALSE;
14279d54b7f4SStefano Zampini   pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_threshold > 0.0);
1428bf3a8328SStefano Zampini   pcbddc->adaptive_userdefined = (PetscBool)(pcbddc->adaptive_selection && pcbddc->adaptive_userdefined);
1429862806e4SStefano Zampini   if (pcbddc->adaptive_selection) pcbddc->use_faces = PETSC_TRUE;
1430862806e4SStefano Zampini 
14315a95e1ceSStefano Zampini   computesubschurs = (PetscBool)(pcbddc->adaptive_selection || pcbddc->use_deluxe_scaling);
143216909a7fSStefano Zampini   if (pcbddc->switch_static) {
143316909a7fSStefano Zampini     PetscBool ismatis;
143416909a7fSStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)pc->mat,MATIS,&ismatis);CHKERRQ(ierr);
143516909a7fSStefano Zampini     if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"When the static switch is one, the iteration matrix should be of type MATIS");
143616909a7fSStefano Zampini   }
143716909a7fSStefano Zampini 
1438f4ddd8eeSStefano Zampini   /* Get stdout for dbg */
143970cf5478SStefano Zampini   if (pcbddc->dbg_flag) {
144070cf5478SStefano Zampini     if (!pcbddc->dbg_viewer) {
144158a03d70SStefano Zampini       pcbddc->dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pc));
14421575c14dSBarry Smith       ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr);
1443f4ddd8eeSStefano Zampini     }
144458a03d70SStefano Zampini     ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr);
1445f4ddd8eeSStefano Zampini   }
1446f4ddd8eeSStefano Zampini 
14475e8657edSStefano Zampini   if (pcbddc->user_ChangeOfBasisMatrix) {
14485e8657edSStefano Zampini     /* use_change_of_basis flag is used to automatically compute a change of basis from constraints */
14495e8657edSStefano Zampini     pcbddc->use_change_of_basis = PETSC_FALSE;
14505e8657edSStefano Zampini     ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr);
14515e8657edSStefano Zampini   } else {
1452b96c3477SStefano Zampini     ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr);
14535e8657edSStefano Zampini     ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr);
14545e8657edSStefano Zampini     pcbddc->local_mat = matis->A;
1455d16cbb6bSStefano Zampini   }
1456d16cbb6bSStefano Zampini 
14574f1b2e48SStefano Zampini   /* detect local disconnected subdomains if requested and not done before */
14584f1b2e48SStefano Zampini   if (pcbddc->detect_disconnected && !pcbddc->n_local_subs) {
14594f1b2e48SStefano Zampini     ierr = MatDetectDisconnectedComponents(pcbddc->local_mat,PETSC_FALSE,&pcbddc->n_local_subs,&pcbddc->local_subs);CHKERRQ(ierr);
14604f1b2e48SStefano Zampini   }
14614f1b2e48SStefano Zampini 
14624f1b2e48SStefano Zampini   /*
14631dd7afcfSStefano Zampini      Compute change of basis on local pressures (aka zerodiag dofs)
14644f1b2e48SStefano Zampini      This should come earlier then PCISSetUp for extracting the correct subdomain matrices
14654f1b2e48SStefano Zampini   */
14661dd7afcfSStefano Zampini   ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr);
1467d16cbb6bSStefano Zampini   if (pcbddc->benign_saddle_point) {
14689f47a83aSStefano Zampini     PC_IS* pcis = (PC_IS*)pc->data;
14699f47a83aSStefano Zampini 
147005b28244SStefano Zampini     if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->use_change_of_basis || !computesubschurs) pcbddc->benign_change_explicit = PETSC_TRUE;
1471339f8db1SStefano Zampini     /* detect local saddle point and change the basis in pcbddc->local_mat */
1472339f8db1SStefano Zampini     ierr = PCBDDCBenignDetectSaddlePoint(pc,&zerodiag);CHKERRQ(ierr);
1473a3df083aSStefano Zampini     /* pop B0 mat from local mat */
1474c263805aSStefano Zampini     ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr);
14751dd7afcfSStefano Zampini     /* give pcis a hint to not reuse submatrices during PCISCreate */
14761dd7afcfSStefano Zampini     if (pc->flag == SAME_NONZERO_PATTERN && pcis->reusesubmatrices == PETSC_TRUE) {
14771dd7afcfSStefano Zampini       if (pcbddc->benign_n && (pcbddc->benign_change_explicit || pcbddc->dbg_flag)) {
14781dd7afcfSStefano Zampini         pcis->reusesubmatrices = PETSC_FALSE;
14791dd7afcfSStefano Zampini       } else {
1480a3df083aSStefano Zampini         pcis->reusesubmatrices = PETSC_TRUE;
14811dd7afcfSStefano Zampini       }
1482a3df083aSStefano Zampini     } else {
14839f47a83aSStefano Zampini       pcis->reusesubmatrices = PETSC_FALSE;
1484674ae819SStefano Zampini     }
1485a3df083aSStefano Zampini   }
1486f1a72664SStefano Zampini   /* propagate relevant information */
14874f1b2e48SStefano Zampini #if !defined(PETSC_USE_COMPLEX) /* workaround for reals */
14883301b35fSStefano Zampini   if (matis->A->symmetric_set) {
14893301b35fSStefano Zampini     ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr);
14903301b35fSStefano Zampini   }
1491e496cd5dSStefano Zampini #endif
149206a4e24aSStefano Zampini   if (matis->A->symmetric_set) {
149306a4e24aSStefano Zampini     ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr);
149406a4e24aSStefano Zampini   }
149506a4e24aSStefano Zampini   if (matis->A->spd_set) {
149606a4e24aSStefano Zampini     ierr = MatSetOption(pcbddc->local_mat,MAT_SPD,matis->A->spd);CHKERRQ(ierr);
149706a4e24aSStefano Zampini   }
1498e496cd5dSStefano Zampini 
14995e8657edSStefano Zampini   /* Set up all the "iterative substructuring" common block without computing solvers */
15005e8657edSStefano Zampini   {
15015e8657edSStefano Zampini     Mat temp_mat;
15025e8657edSStefano Zampini 
15035e8657edSStefano Zampini     temp_mat = matis->A;
15045e8657edSStefano Zampini     matis->A = pcbddc->local_mat;
15055e8657edSStefano Zampini     ierr = PCISSetUp(pc,PETSC_FALSE);CHKERRQ(ierr);
15065e8657edSStefano Zampini     pcbddc->local_mat = matis->A;
15075e8657edSStefano Zampini     matis->A = temp_mat;
15085e8657edSStefano Zampini   }
1509684f6988SStefano Zampini 
151081d14e9dSStefano Zampini   /* Analyze interface */
1511674ae819SStefano Zampini   if (computetopography) {
1512674ae819SStefano Zampini     ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr);
15138de1fae6SStefano Zampini     computeconstraintsmatrix = PETSC_TRUE;
1514674ae819SStefano Zampini   }
1515fb8d54d4SStefano Zampini 
15165408967cSStefano Zampini   /* check existence of a divergence free extension, i.e.
15175408967cSStefano Zampini      b(v_I,p_0) = 0 for all v_I (raise error if not).
15185408967cSStefano Zampini      Also, check that PCBDDCBenignGetOrSetP0 works */
15195408967cSStefano Zampini #if defined(PETSC_USE_DEBUG)
152009f581a4SStefano Zampini   if (pcbddc->benign_saddle_point) {
15215408967cSStefano Zampini     ierr = PCBDDCBenignCheck(pc,zerodiag);CHKERRQ(ierr);
152209f581a4SStefano Zampini   }
15235408967cSStefano Zampini #endif
15244f1b2e48SStefano Zampini   ierr = ISDestroy(&zerodiag);CHKERRQ(ierr);
152506f24817SStefano Zampini 
1526b96c3477SStefano Zampini   /* Setup local dirichlet solver ksp_D and sub_schurs solvers */
1527684f6988SStefano Zampini   if (computesolvers) {
1528d5574798SStefano Zampini     PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs;
1529d5574798SStefano Zampini 
1530d5574798SStefano Zampini     if (computesubschurs && computetopography) {
153108122e43SStefano Zampini       ierr = PCBDDCInitSubSchurs(pc);CHKERRQ(ierr);
1532b1b3d7a2SStefano Zampini     }
15339d54b7f4SStefano Zampini     /* SetUp Scaling operator (scaling matrices could be needed in SubSchursSetUp)*/
15349d54b7f4SStefano Zampini     if (!pcbddc->use_deluxe_scaling) {
15359d54b7f4SStefano Zampini       ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr);
15369d54b7f4SStefano Zampini     }
1537df4d28bfSStefano Zampini     if (sub_schurs->schur_explicit) {
15382070dbb6SStefano Zampini       if (computesubschurs) {
153908122e43SStefano Zampini         ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr);
15402070dbb6SStefano Zampini       }
1541d5574798SStefano Zampini       ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr);
1542d5574798SStefano Zampini     } else {
1543d5574798SStefano Zampini       ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr);
15442070dbb6SStefano Zampini       if (computesubschurs) {
1545d5574798SStefano Zampini         ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr);
1546d5574798SStefano Zampini       }
15472070dbb6SStefano Zampini     }
154808122e43SStefano Zampini     if (pcbddc->adaptive_selection) {
154908122e43SStefano Zampini       ierr = PCBDDCAdaptiveSelection(pc);CHKERRQ(ierr);
15508de1fae6SStefano Zampini       computeconstraintsmatrix = PETSC_TRUE;
1551b7eb3628SStefano Zampini     }
1552b1b3d7a2SStefano Zampini   }
1553684f6988SStefano Zampini 
1554f4ddd8eeSStefano Zampini   /* infer if NullSpace object attached to Mat via MatSetNearNullSpace has changed */
1555fb8d54d4SStefano Zampini   new_nearnullspace_provided = PETSC_FALSE;
1556f4ddd8eeSStefano Zampini   ierr = MatGetNearNullSpace(pc->pmat,&nearnullspace);CHKERRQ(ierr);
1557f4ddd8eeSStefano Zampini   if (pcbddc->onearnullspace) { /* already used nearnullspace */
1558f4ddd8eeSStefano Zampini     if (!nearnullspace) { /* near null space attached to mat has been destroyed */
1559f4ddd8eeSStefano Zampini       new_nearnullspace_provided = PETSC_TRUE;
1560f4ddd8eeSStefano Zampini     } else {
1561f4ddd8eeSStefano Zampini       /* determine if the two nullspaces are different (should be lightweight) */
1562f4ddd8eeSStefano Zampini       if (nearnullspace != pcbddc->onearnullspace) {
1563f4ddd8eeSStefano Zampini         new_nearnullspace_provided = PETSC_TRUE;
1564165b64e2SStefano Zampini       } else { /* maybe the user has changed the content of the nearnullspace so check vectors ObjectStateId */
1565f4ddd8eeSStefano Zampini         PetscInt         i;
1566165b64e2SStefano Zampini         const Vec        *nearnullvecs;
1567165b64e2SStefano Zampini         PetscObjectState state;
1568165b64e2SStefano Zampini         PetscInt         nnsp_size;
1569165b64e2SStefano Zampini         ierr = MatNullSpaceGetVecs(nearnullspace,NULL,&nnsp_size,&nearnullvecs);CHKERRQ(ierr);
1570f4ddd8eeSStefano Zampini         for (i=0;i<nnsp_size;i++) {
1571f4ddd8eeSStefano Zampini           ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&state);CHKERRQ(ierr);
1572165b64e2SStefano Zampini           if (pcbddc->onearnullvecs_state[i] != state) {
1573f4ddd8eeSStefano Zampini             new_nearnullspace_provided = PETSC_TRUE;
1574f4ddd8eeSStefano Zampini             break;
1575f4ddd8eeSStefano Zampini           }
1576f4ddd8eeSStefano Zampini         }
1577f4ddd8eeSStefano Zampini       }
1578f4ddd8eeSStefano Zampini     }
1579f4ddd8eeSStefano Zampini   } else {
1580f4ddd8eeSStefano Zampini     if (!nearnullspace) { /* both nearnullspaces are null */
1581f4ddd8eeSStefano Zampini       new_nearnullspace_provided = PETSC_FALSE;
1582f4ddd8eeSStefano Zampini     } else { /* nearnullspace attached later */
1583f4ddd8eeSStefano Zampini       new_nearnullspace_provided = PETSC_TRUE;
1584f4ddd8eeSStefano Zampini     }
1585f4ddd8eeSStefano Zampini   }
1586f4ddd8eeSStefano Zampini 
1587f4ddd8eeSStefano Zampini   /* Setup constraints and related work vectors */
1588727cdba6SStefano Zampini   /* reset primal space flags */
1589f4ddd8eeSStefano Zampini   pcbddc->new_primal_space = PETSC_FALSE;
1590727cdba6SStefano Zampini   pcbddc->new_primal_space_local = PETSC_FALSE;
15918de1fae6SStefano Zampini   if (computeconstraintsmatrix || new_nearnullspace_provided) {
1592727cdba6SStefano Zampini     /* It also sets the primal space flags */
1593674ae819SStefano Zampini     ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr);
1594e7b262bdSStefano Zampini     /* Allocate needed local vectors (which depends on quantities defined during ConstraintsSetUp) */
1595f4ddd8eeSStefano Zampini     ierr = PCBDDCSetUpLocalWorkVectors(pc);CHKERRQ(ierr);
15963975b054SStefano Zampini   }
15975e8657edSStefano Zampini 
15983975b054SStefano Zampini   if (computesolvers || pcbddc->new_primal_space) {
15995e8657edSStefano Zampini     if (pcbddc->use_change_of_basis) {
16005e8657edSStefano Zampini       PC_IS *pcis = (PC_IS*)(pc->data);
16015e8657edSStefano Zampini 
16025e8657edSStefano Zampini       ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr);
16034f1b2e48SStefano Zampini       if (pcbddc->benign_change) {
16041dd7afcfSStefano Zampini         ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr);
1605c263805aSStefano Zampini         /* pop B0 from pcbddc->local_mat */
1606c263805aSStefano Zampini         ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr);
1607c263805aSStefano Zampini       }
16085e8657edSStefano Zampini       /* get submatrices */
16095e8657edSStefano Zampini       ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr);
16105e8657edSStefano Zampini       ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr);
16115e8657edSStefano Zampini       ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr);
16125e8657edSStefano Zampini       ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr);
16135e8657edSStefano Zampini       ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr);
16145e8657edSStefano Zampini       ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr);
16153975b054SStefano Zampini       /* set flag in pcis to not reuse submatrices during PCISCreate */
16163975b054SStefano Zampini       pcis->reusesubmatrices = PETSC_FALSE;
16179c6a02ceSStefano Zampini     } else if (!pcbddc->user_ChangeOfBasisMatrix && !pcbddc->benign_change) {
1618b96c3477SStefano Zampini       ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr);
16195e8657edSStefano Zampini       ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr);
16205e8657edSStefano Zampini       pcbddc->local_mat = matis->A;
16215e8657edSStefano Zampini     }
1622b96c3477SStefano Zampini     /* SetUp coarse and local Neumann solvers */
162399cc7994SStefano Zampini     ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr);
1624b96c3477SStefano Zampini     /* SetUp Scaling operator */
16259d54b7f4SStefano Zampini     if (pcbddc->use_deluxe_scaling) {
1626674ae819SStefano Zampini       ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr);
16270c7d97c5SJed Brown     }
16289d54b7f4SStefano Zampini   }
16291dd7afcfSStefano Zampini   /* mark topography as done */
163056282151SStefano Zampini   pcbddc->recompute_topography = PETSC_FALSE;
16310369aaf7SStefano Zampini 
16321dd7afcfSStefano Zampini   /* wrap pcis->A_IB and pcis->A_BI if we did not change explicitly the variables on the pressures */
16331dd7afcfSStefano Zampini   ierr = PCBDDCBenignShellMat(pc,PETSC_FALSE);CHKERRQ(ierr);
16341dd7afcfSStefano Zampini 
163558a03d70SStefano Zampini   if (pcbddc->dbg_flag) {
163658a03d70SStefano Zampini     ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr);
16372b510759SStefano Zampini   }
16380c7d97c5SJed Brown   PetscFunctionReturn(0);
16390c7d97c5SJed Brown }
16400c7d97c5SJed Brown 
16410c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
16420c7d97c5SJed Brown /*
164350efa1b5SStefano Zampini    PCApply_BDDC - Applies the BDDC operator to a vector.
16440c7d97c5SJed Brown 
16450c7d97c5SJed Brown    Input Parameters:
16460f202f7eSStefano Zampini +  pc - the preconditioner context
16470f202f7eSStefano Zampini -  r - input vector (global)
16480c7d97c5SJed Brown 
16490c7d97c5SJed Brown    Output Parameter:
16500c7d97c5SJed Brown .  z - output vector (global)
16510c7d97c5SJed Brown 
16520c7d97c5SJed Brown    Application Interface Routine: PCApply()
16530c7d97c5SJed Brown  */
16540c7d97c5SJed Brown #undef __FUNCT__
16550c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC"
165653cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z)
16570c7d97c5SJed Brown {
16580c7d97c5SJed Brown   PC_IS             *pcis = (PC_IS*)(pc->data);
16590c7d97c5SJed Brown   PC_BDDC           *pcbddc = (PC_BDDC*)(pc->data);
1660b097fa66SStefano Zampini   PetscInt          n_B = pcis->n_B, n_D = pcis->n - n_B;
16610c7d97c5SJed Brown   PetscErrorCode    ierr;
16623b03a366Sstefano_zampini   const PetscScalar one = 1.0;
16633b03a366Sstefano_zampini   const PetscScalar m_one = -1.0;
16642617d88aSStefano Zampini   const PetscScalar zero = 0.0;
16650c7d97c5SJed Brown 
16660c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN
16670c7d97c5SJed Brown    NN interface preconditioner changed to BDDC
1668b097fa66SStefano Zampini    Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static == PETSC_TRUE) */
16690c7d97c5SJed Brown 
16700c7d97c5SJed Brown   PetscFunctionBegin;
16711dd7afcfSStefano Zampini   if (pcbddc->ChangeOfBasisMatrix) {
16721dd7afcfSStefano Zampini     Vec swap;
16731dd7afcfSStefano Zampini     ierr = VecCopy(r,pcbddc->work_change);CHKERRQ(ierr);
16741dd7afcfSStefano Zampini     swap = pcbddc->work_change;
16751dd7afcfSStefano Zampini     pcbddc->work_change = r;
16761dd7afcfSStefano Zampini     r = swap;
16771dd7afcfSStefano Zampini     ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,r);CHKERRQ(ierr);
16781dd7afcfSStefano Zampini     /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */
16791dd7afcfSStefano Zampini     if (pcbddc->benign_apply_coarse_only && pcbddc->use_exact_dirichlet_trick && pcbddc->change_interior) {
16801dd7afcfSStefano Zampini       ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr);
16811dd7afcfSStefano Zampini       ierr = VecLockPush(pcis->vec1_global);CHKERRQ(ierr);
16821dd7afcfSStefano Zampini     }
16831dd7afcfSStefano Zampini   }
1684015636ebSStefano Zampini   if (pcbddc->benign_saddle_point) { /* get p0 from r */
1685015636ebSStefano Zampini     ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr);
1686efc2fbd9SStefano Zampini   }
168785c4d303SStefano Zampini   if (!pcbddc->use_exact_dirichlet_trick) {
1688b097fa66SStefano Zampini     ierr = VecCopy(r,z);CHKERRQ(ierr);
16890c7d97c5SJed Brown     /* First Dirichlet solve */
16900c7d97c5SJed Brown     ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
16910c7d97c5SJed Brown     ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
16920c7d97c5SJed Brown     /*
16930c7d97c5SJed Brown       Assembling right hand side for BDDC operator
1694b097fa66SStefano Zampini       - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE)
1695674ae819SStefano Zampini       - pcis->vec1_B the interface part of the global vector z
16960c7d97c5SJed Brown     */
1697b097fa66SStefano Zampini     if (n_D) {
1698b097fa66SStefano Zampini       ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr);
16990c7d97c5SJed Brown       ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr);
170016909a7fSStefano Zampini       if (pcbddc->switch_static) {
170116909a7fSStefano Zampini         Mat_IS *matis = (Mat_IS*)(pc->mat->data);
170216909a7fSStefano Zampini 
170316909a7fSStefano Zampini         ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr);
170416909a7fSStefano Zampini         ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
170516909a7fSStefano Zampini         ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
170616909a7fSStefano Zampini         if (!pcbddc->switch_static_change) {
170716909a7fSStefano Zampini           ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr);
170816909a7fSStefano Zampini         } else {
170916909a7fSStefano Zampini           ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr);
171016909a7fSStefano Zampini           ierr = MatMult(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr);
171116909a7fSStefano Zampini           ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr);
171216909a7fSStefano Zampini         }
171316909a7fSStefano Zampini         ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
171416909a7fSStefano Zampini         ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
171516909a7fSStefano Zampini         ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
171616909a7fSStefano Zampini         ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
171716909a7fSStefano Zampini       } else {
1718b097fa66SStefano Zampini         ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr);
171916909a7fSStefano Zampini       }
1720b097fa66SStefano Zampini     } else {
1721b097fa66SStefano Zampini       ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr);
1722b097fa66SStefano Zampini     }
17230c7d97c5SJed Brown     ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
17240c7d97c5SJed Brown     ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1725674ae819SStefano Zampini     ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr);
1726b76ba322SStefano Zampini   } else {
17274fee134fSStefano Zampini     if (!pcbddc->benign_apply_coarse_only) {
1728674ae819SStefano Zampini       ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr);
1729b76ba322SStefano Zampini     }
17304fee134fSStefano Zampini   }
1731b76ba322SStefano Zampini 
17322617d88aSStefano Zampini   /* Apply interface preconditioner
17332617d88aSStefano Zampini      input/output vecs: pcis->vec1_B and pcis->vec1_D */
1734dc359a40SStefano Zampini   ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr);
17352617d88aSStefano Zampini 
1736674ae819SStefano Zampini   /* Apply transpose of partition of unity operator */
1737674ae819SStefano Zampini   ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr);
17380c7d97c5SJed Brown 
17393b03a366Sstefano_zampini   /* Second Dirichlet solve and assembling of output */
17400c7d97c5SJed Brown   ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
17410c7d97c5SJed Brown   ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1742b097fa66SStefano Zampini   if (n_B) {
174316909a7fSStefano Zampini     if (pcbddc->switch_static) {
174416909a7fSStefano Zampini       Mat_IS *matis = (Mat_IS*)(pc->mat->data);
174516909a7fSStefano Zampini 
174616909a7fSStefano Zampini       ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
174716909a7fSStefano Zampini       ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
174816909a7fSStefano Zampini       ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
174916909a7fSStefano Zampini       ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
175016909a7fSStefano Zampini       if (!pcbddc->switch_static_change) {
175116909a7fSStefano Zampini         ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr);
175216909a7fSStefano Zampini       } else {
175316909a7fSStefano Zampini         ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr);
175416909a7fSStefano Zampini         ierr = MatMult(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr);
175516909a7fSStefano Zampini         ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr);
175616909a7fSStefano Zampini       }
175716909a7fSStefano Zampini       ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
175816909a7fSStefano Zampini       ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
175916909a7fSStefano Zampini     } else {
17600c7d97c5SJed Brown       ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr);
176116909a7fSStefano Zampini     }
176216909a7fSStefano Zampini   } else if (pcbddc->switch_static) { /* n_B is zero */
176316909a7fSStefano Zampini     Mat_IS *matis = (Mat_IS*)(pc->mat->data);
176416909a7fSStefano Zampini 
176516909a7fSStefano Zampini     if (!pcbddc->switch_static_change) {
176616909a7fSStefano Zampini       ierr = MatMult(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr);
176716909a7fSStefano Zampini     } else {
176816909a7fSStefano Zampini       ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr);
176916909a7fSStefano Zampini       ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr);
177016909a7fSStefano Zampini       ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr);
177116909a7fSStefano Zampini     }
1772b097fa66SStefano Zampini   }
1773df187020SStefano Zampini   ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr);
1774efc2fbd9SStefano Zampini 
1775b097fa66SStefano Zampini   if (!pcbddc->use_exact_dirichlet_trick) {
1776b097fa66SStefano Zampini     if (pcbddc->switch_static) {
1777b097fa66SStefano Zampini       ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr);
1778b097fa66SStefano Zampini     } else {
1779b097fa66SStefano Zampini       ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr);
1780b097fa66SStefano Zampini     }
17810c7d97c5SJed Brown     ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
17820c7d97c5SJed Brown     ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1783b097fa66SStefano Zampini   } else {
1784b097fa66SStefano Zampini     if (pcbddc->switch_static) {
1785b097fa66SStefano Zampini       ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr);
1786b097fa66SStefano Zampini     } else {
1787b097fa66SStefano Zampini       ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr);
1788b097fa66SStefano Zampini     }
1789b097fa66SStefano Zampini     ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1790b097fa66SStefano Zampini     ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1791b097fa66SStefano Zampini   }
1792efc2fbd9SStefano Zampini 
1793015636ebSStefano Zampini   if (pcbddc->benign_saddle_point) { /* set p0 (computed in PCBDDCApplyInterface) */
17941dd7afcfSStefano Zampini     if (pcbddc->benign_apply_coarse_only) {
17951dd7afcfSStefano Zampini       ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr);
17961dd7afcfSStefano Zampini     }
1797015636ebSStefano Zampini     ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr);
1798efc2fbd9SStefano Zampini   }
17991dd7afcfSStefano Zampini   if (pcbddc->ChangeOfBasisMatrix) {
18001dd7afcfSStefano Zampini     Vec swap;
18011dd7afcfSStefano Zampini 
18021dd7afcfSStefano Zampini     swap = r;
18031dd7afcfSStefano Zampini     r = pcbddc->work_change;
18041dd7afcfSStefano Zampini     pcbddc->work_change = swap;
18051dd7afcfSStefano Zampini     ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr);
18061dd7afcfSStefano Zampini     ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr);
18071dd7afcfSStefano Zampini   }
18080c7d97c5SJed Brown   PetscFunctionReturn(0);
18090c7d97c5SJed Brown }
181050efa1b5SStefano Zampini 
181150efa1b5SStefano Zampini /* -------------------------------------------------------------------------- */
181250efa1b5SStefano Zampini /*
181350efa1b5SStefano Zampini    PCApplyTranspose_BDDC - Applies the transpose of the BDDC operator to a vector.
181450efa1b5SStefano Zampini 
181550efa1b5SStefano Zampini    Input Parameters:
18160f202f7eSStefano Zampini +  pc - the preconditioner context
18170f202f7eSStefano Zampini -  r - input vector (global)
181850efa1b5SStefano Zampini 
181950efa1b5SStefano Zampini    Output Parameter:
182050efa1b5SStefano Zampini .  z - output vector (global)
182150efa1b5SStefano Zampini 
182250efa1b5SStefano Zampini    Application Interface Routine: PCApplyTranspose()
182350efa1b5SStefano Zampini  */
182450efa1b5SStefano Zampini #undef __FUNCT__
182550efa1b5SStefano Zampini #define __FUNCT__ "PCApplyTranspose_BDDC"
182650efa1b5SStefano Zampini PetscErrorCode PCApplyTranspose_BDDC(PC pc,Vec r,Vec z)
182750efa1b5SStefano Zampini {
182850efa1b5SStefano Zampini   PC_IS             *pcis = (PC_IS*)(pc->data);
182950efa1b5SStefano Zampini   PC_BDDC           *pcbddc = (PC_BDDC*)(pc->data);
1830b097fa66SStefano Zampini   PetscInt          n_B = pcis->n_B, n_D = pcis->n - n_B;
183150efa1b5SStefano Zampini   PetscErrorCode    ierr;
183250efa1b5SStefano Zampini   const PetscScalar one = 1.0;
183350efa1b5SStefano Zampini   const PetscScalar m_one = -1.0;
183450efa1b5SStefano Zampini   const PetscScalar zero = 0.0;
183550efa1b5SStefano Zampini 
183650efa1b5SStefano Zampini   PetscFunctionBegin;
18371dd7afcfSStefano Zampini   if (pcbddc->ChangeOfBasisMatrix) {
18381dd7afcfSStefano Zampini     Vec swap;
18391dd7afcfSStefano Zampini     ierr = VecCopy(r,pcbddc->work_change);CHKERRQ(ierr);
18401dd7afcfSStefano Zampini     swap = pcbddc->work_change;
18411dd7afcfSStefano Zampini     pcbddc->work_change = r;
18421dd7afcfSStefano Zampini     r = swap;
18431dd7afcfSStefano Zampini     ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,r);CHKERRQ(ierr);
18441dd7afcfSStefano Zampini   }
1845537c1cdfSStefano Zampini   if (pcbddc->benign_saddle_point) { /* get p0 from r */
1846537c1cdfSStefano Zampini     ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr);
1847537c1cdfSStefano Zampini   }
184850efa1b5SStefano Zampini   if (!pcbddc->use_exact_dirichlet_trick) {
1849b097fa66SStefano Zampini     ierr = VecCopy(r,z);CHKERRQ(ierr);
185050efa1b5SStefano Zampini     /* First Dirichlet solve */
185150efa1b5SStefano Zampini     ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
185250efa1b5SStefano Zampini     ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
185350efa1b5SStefano Zampini     /*
185450efa1b5SStefano Zampini       Assembling right hand side for BDDC operator
1855b097fa66SStefano Zampini       - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE)
185650efa1b5SStefano Zampini       - pcis->vec1_B the interface part of the global vector z
185750efa1b5SStefano Zampini     */
1858b097fa66SStefano Zampini     if (n_D) {
1859b097fa66SStefano Zampini       ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr);
186050efa1b5SStefano Zampini       ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr);
186116909a7fSStefano Zampini       if (pcbddc->switch_static) {
186216909a7fSStefano Zampini         Mat_IS *matis = (Mat_IS*)(pc->mat->data);
186316909a7fSStefano Zampini 
186416909a7fSStefano Zampini         ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr);
186516909a7fSStefano Zampini         ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
186616909a7fSStefano Zampini         ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
186716909a7fSStefano Zampini         if (!pcbddc->switch_static_change) {
186816909a7fSStefano Zampini           ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr);
186916909a7fSStefano Zampini         } else {
187016909a7fSStefano Zampini           ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr);
187116909a7fSStefano Zampini           ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr);
187216909a7fSStefano Zampini           ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr);
187316909a7fSStefano Zampini         }
187416909a7fSStefano Zampini         ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
187516909a7fSStefano Zampini         ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
187616909a7fSStefano Zampini         ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
187716909a7fSStefano Zampini         ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
187816909a7fSStefano Zampini       } else {
1879b097fa66SStefano Zampini         ierr = MatMultTranspose(pcis->A_IB,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr);
188016909a7fSStefano Zampini       }
1881b097fa66SStefano Zampini     } else {
1882b097fa66SStefano Zampini       ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr);
1883b097fa66SStefano Zampini     }
188450efa1b5SStefano Zampini     ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
188550efa1b5SStefano Zampini     ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
188650efa1b5SStefano Zampini     ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr);
188750efa1b5SStefano Zampini   } else {
188850efa1b5SStefano Zampini     ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr);
188950efa1b5SStefano Zampini   }
189050efa1b5SStefano Zampini 
189150efa1b5SStefano Zampini   /* Apply interface preconditioner
189250efa1b5SStefano Zampini      input/output vecs: pcis->vec1_B and pcis->vec1_D */
1893dc359a40SStefano Zampini   ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_TRUE);CHKERRQ(ierr);
189450efa1b5SStefano Zampini 
189550efa1b5SStefano Zampini   /* Apply transpose of partition of unity operator */
189650efa1b5SStefano Zampini   ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr);
189750efa1b5SStefano Zampini 
189850efa1b5SStefano Zampini   /* Second Dirichlet solve and assembling of output */
189950efa1b5SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
190050efa1b5SStefano Zampini   ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1901b097fa66SStefano Zampini   if (n_B) {
190216909a7fSStefano Zampini     if (pcbddc->switch_static) {
190316909a7fSStefano Zampini       Mat_IS *matis = (Mat_IS*)(pc->mat->data);
190416909a7fSStefano Zampini 
190516909a7fSStefano Zampini       ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
190616909a7fSStefano Zampini       ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
190716909a7fSStefano Zampini       ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
190816909a7fSStefano Zampini       ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
190916909a7fSStefano Zampini       if (!pcbddc->switch_static_change) {
191016909a7fSStefano Zampini         ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr);
191116909a7fSStefano Zampini       } else {
191216909a7fSStefano Zampini         ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr);
191316909a7fSStefano Zampini         ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr);
191416909a7fSStefano Zampini         ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr);
191516909a7fSStefano Zampini       }
191616909a7fSStefano Zampini       ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
191716909a7fSStefano Zampini       ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
191816909a7fSStefano Zampini     } else {
191950efa1b5SStefano Zampini       ierr = MatMultTranspose(pcis->A_BI,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr);
192016909a7fSStefano Zampini     }
192116909a7fSStefano Zampini   } else if (pcbddc->switch_static) { /* n_B is zero */
192216909a7fSStefano Zampini     Mat_IS *matis = (Mat_IS*)(pc->mat->data);
192316909a7fSStefano Zampini 
192416909a7fSStefano Zampini     if (!pcbddc->switch_static_change) {
192516909a7fSStefano Zampini       ierr = MatMultTranspose(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr);
192616909a7fSStefano Zampini     } else {
192716909a7fSStefano Zampini       ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr);
192816909a7fSStefano Zampini       ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr);
192916909a7fSStefano Zampini       ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr);
193016909a7fSStefano Zampini     }
1931b097fa66SStefano Zampini   }
1932b0147a47SStefano Zampini   ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr);
1933b097fa66SStefano Zampini   if (!pcbddc->use_exact_dirichlet_trick) {
1934b097fa66SStefano Zampini     if (pcbddc->switch_static) {
1935b097fa66SStefano Zampini       ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr);
1936b097fa66SStefano Zampini     } else {
1937b097fa66SStefano Zampini       ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr);
1938b097fa66SStefano Zampini     }
193950efa1b5SStefano Zampini     ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
194050efa1b5SStefano Zampini     ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1941b097fa66SStefano Zampini   } else {
1942b097fa66SStefano Zampini     if (pcbddc->switch_static) {
1943b097fa66SStefano Zampini       ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr);
1944b097fa66SStefano Zampini     } else {
1945b097fa66SStefano Zampini       ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr);
1946b097fa66SStefano Zampini     }
1947b097fa66SStefano Zampini     ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1948b097fa66SStefano Zampini     ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1949b097fa66SStefano Zampini   }
1950537c1cdfSStefano Zampini   if (pcbddc->benign_saddle_point) { /* set p0 (computed in PCBDDCApplyInterface) */
1951537c1cdfSStefano Zampini     ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr);
1952537c1cdfSStefano Zampini   }
19531dd7afcfSStefano Zampini   if (pcbddc->ChangeOfBasisMatrix) {
19541dd7afcfSStefano Zampini     Vec swap;
19551dd7afcfSStefano Zampini 
19561dd7afcfSStefano Zampini     swap = r;
19571dd7afcfSStefano Zampini     r = pcbddc->work_change;
19581dd7afcfSStefano Zampini     pcbddc->work_change = swap;
19591dd7afcfSStefano Zampini     ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr);
19601dd7afcfSStefano Zampini     ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr);
19611dd7afcfSStefano Zampini   }
196250efa1b5SStefano Zampini   PetscFunctionReturn(0);
196350efa1b5SStefano Zampini }
1964da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */
1965674ae819SStefano Zampini 
1966da1bb401SStefano Zampini #undef __FUNCT__
1967da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC"
1968da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc)
1969da1bb401SStefano Zampini {
1970da1bb401SStefano Zampini   PC_BDDC        *pcbddc = (PC_BDDC*)pc->data;
1971da1bb401SStefano Zampini   PetscErrorCode ierr;
1972da1bb401SStefano Zampini 
1973da1bb401SStefano Zampini   PetscFunctionBegin;
1974674ae819SStefano Zampini   /* free BDDC custom data  */
1975674ae819SStefano Zampini   ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr);
1976674ae819SStefano Zampini   /* destroy objects related to topography */
1977674ae819SStefano Zampini   ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr);
1978674ae819SStefano Zampini   /* free allocated graph structure */
1979da1bb401SStefano Zampini   ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr);
1980b96c3477SStefano Zampini   /* free allocated sub schurs structure */
1981b96c3477SStefano Zampini   ierr = PetscFree(pcbddc->sub_schurs);CHKERRQ(ierr);
198234a97f8cSStefano Zampini   /* destroy objects for scaling operator */
1983674ae819SStefano Zampini   ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr);
198434a97f8cSStefano Zampini   ierr = PetscFree(pcbddc->deluxe_ctx);CHKERRQ(ierr);
1985674ae819SStefano Zampini   /* free solvers stuff */
1986674ae819SStefano Zampini   ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr);
198762a6ff1dSStefano Zampini   /* free global vectors needed in presolve */
198862a6ff1dSStefano Zampini   ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr);
198962a6ff1dSStefano Zampini   ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr);
19901dd7afcfSStefano Zampini   /* free data created by PCIS */
19911dd7afcfSStefano Zampini   ierr = PCISDestroy(pc);CHKERRQ(ierr);
19923425bc38SStefano Zampini   /* remove functions */
1993906d46d4SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",NULL);CHKERRQ(ierr);
1994674ae819SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr);
199530368db7SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",NULL);CHKERRQ(ierr);
1996bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr);
19972b510759SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr);
1998b8ffe317SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr);
19992b510759SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr);
2000bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",NULL);CHKERRQ(ierr);
2001bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr);
200282ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr);
2003bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr);
200482ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr);
2005bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr);
200682ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr);
2007bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr);
2008785d1243SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr);
2009bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr);
201063602bcaSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",NULL);CHKERRQ(ierr);
2011bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr);
2012bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr);
2013bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr);
2014bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr);
2015674ae819SStefano Zampini   /* Free the private data structure */
2016674ae819SStefano Zampini   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2017da1bb401SStefano Zampini   PetscFunctionReturn(0);
2018da1bb401SStefano Zampini }
20193425bc38SStefano Zampini /* -------------------------------------------------------------------------- */
20201e6b0712SBarry Smith 
20213425bc38SStefano Zampini #undef __FUNCT__
20223425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC"
20233425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs)
20243425bc38SStefano Zampini {
2025674ae819SStefano Zampini   FETIDPMat_ctx  mat_ctx;
2026c08af4c6SStefano Zampini   Vec            copy_standard_rhs;
20273425bc38SStefano Zampini   PC_IS*         pcis;
20283425bc38SStefano Zampini   PC_BDDC*       pcbddc;
20293425bc38SStefano Zampini   PetscErrorCode ierr;
20300c7d97c5SJed Brown 
20313425bc38SStefano Zampini   PetscFunctionBegin;
20323425bc38SStefano Zampini   ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr);
20333425bc38SStefano Zampini   pcis = (PC_IS*)mat_ctx->pc->data;
20343425bc38SStefano Zampini   pcbddc = (PC_BDDC*)mat_ctx->pc->data;
20353425bc38SStefano Zampini 
2036c08af4c6SStefano Zampini   /*
2037c08af4c6SStefano Zampini      change of basis for physical rhs if needed
2038c08af4c6SStefano Zampini      It also changes the rhs in case of dirichlet boundaries
2039c08af4c6SStefano Zampini      TODO: better management when FETIDP will have its own class
2040c08af4c6SStefano Zampini   */
2041c08af4c6SStefano Zampini   ierr = VecDuplicate(standard_rhs,&copy_standard_rhs);CHKERRQ(ierr);
2042c08af4c6SStefano Zampini   ierr = VecCopy(standard_rhs,copy_standard_rhs);CHKERRQ(ierr);
2043c08af4c6SStefano Zampini   ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,copy_standard_rhs,NULL);CHKERRQ(ierr);
20443425bc38SStefano Zampini   /* store vectors for computation of fetidp final solution */
2045c08af4c6SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_D,copy_standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2046c08af4c6SStefano Zampini   ierr = VecScatterEnd(pcis->global_to_D,copy_standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2047fb223d50SStefano Zampini   /* scale rhs since it should be unassembled */
2048fb223d50SStefano Zampini   /* TODO use counter scaling? (also below) */
2049c08af4c6SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2050c08af4c6SStefano Zampini   ierr = VecScatterEnd(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2051674ae819SStefano Zampini   /* Apply partition of unity */
20523425bc38SStefano Zampini   ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr);
2053c08af4c6SStefano Zampini   /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,copy_standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */
20548eeda7d8SStefano Zampini   if (!pcbddc->switch_static) {
20553425bc38SStefano Zampini     /* compute partially subassembled Schur complement right-hand side */
20563425bc38SStefano Zampini     ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr);
20573425bc38SStefano Zampini     ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr);
20583425bc38SStefano Zampini     ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr);
2059c08af4c6SStefano Zampini     ierr = VecSet(copy_standard_rhs,0.0);CHKERRQ(ierr);
2060c08af4c6SStefano Zampini     ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,copy_standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
2061c08af4c6SStefano Zampini     ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,copy_standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
2062c08af4c6SStefano Zampini     /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,copy_standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */
2063c08af4c6SStefano Zampini     ierr = VecScatterBegin(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2064c08af4c6SStefano Zampini     ierr = VecScatterEnd(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
20653425bc38SStefano Zampini     ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr);
20663425bc38SStefano Zampini   }
2067c08af4c6SStefano Zampini   ierr = VecDestroy(&copy_standard_rhs);CHKERRQ(ierr);
20683425bc38SStefano Zampini   /* BDDC rhs */
20693425bc38SStefano Zampini   ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr);
20708eeda7d8SStefano Zampini   if (pcbddc->switch_static) {
20713425bc38SStefano Zampini     ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr);
20723425bc38SStefano Zampini   }
20733425bc38SStefano Zampini   /* apply BDDC */
2074dc359a40SStefano Zampini   ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr);
20753425bc38SStefano Zampini   /* Application of B_delta and assembling of rhs for fetidp fluxes */
20763425bc38SStefano Zampini   ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr);
20773425bc38SStefano Zampini   ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr);
20783425bc38SStefano Zampini   ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
20793425bc38SStefano Zampini   ierr = VecScatterEnd(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
20803425bc38SStefano Zampini   PetscFunctionReturn(0);
20813425bc38SStefano Zampini }
20821e6b0712SBarry Smith 
20833425bc38SStefano Zampini #undef __FUNCT__
20843425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS"
20853425bc38SStefano Zampini /*@
20860f202f7eSStefano Zampini  PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETI-DP linear system using the physical right-hand side
20873425bc38SStefano Zampini 
20883425bc38SStefano Zampini    Collective
20893425bc38SStefano Zampini 
20903425bc38SStefano Zampini    Input Parameters:
20910f202f7eSStefano Zampini +  fetidp_mat      - the FETI-DP matrix object obtained by a call to PCBDDCCreateFETIDPOperators
20920f202f7eSStefano Zampini -  standard_rhs    - the right-hand side of the original linear system
20933425bc38SStefano Zampini 
20943425bc38SStefano Zampini    Output Parameters:
20950f202f7eSStefano Zampini .  fetidp_flux_rhs - the right-hand side for the FETI-DP linear system
20963425bc38SStefano Zampini 
20973425bc38SStefano Zampini    Level: developer
20983425bc38SStefano Zampini 
20993425bc38SStefano Zampini    Notes:
21003425bc38SStefano Zampini 
21010f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetSolution
21023425bc38SStefano Zampini @*/
21033425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs)
21043425bc38SStefano Zampini {
2105674ae819SStefano Zampini   FETIDPMat_ctx  mat_ctx;
21063425bc38SStefano Zampini   PetscErrorCode ierr;
21073425bc38SStefano Zampini 
21083425bc38SStefano Zampini   PetscFunctionBegin;
21093425bc38SStefano Zampini   ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr);
21103425bc38SStefano Zampini   ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr);
21113425bc38SStefano Zampini   PetscFunctionReturn(0);
21123425bc38SStefano Zampini }
21133425bc38SStefano Zampini /* -------------------------------------------------------------------------- */
21141e6b0712SBarry Smith 
21153425bc38SStefano Zampini #undef __FUNCT__
21163425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC"
21173425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol)
21183425bc38SStefano Zampini {
2119674ae819SStefano Zampini   FETIDPMat_ctx  mat_ctx;
21203425bc38SStefano Zampini   PC_IS*         pcis;
21213425bc38SStefano Zampini   PC_BDDC*       pcbddc;
21223425bc38SStefano Zampini   PetscErrorCode ierr;
21233425bc38SStefano Zampini 
21243425bc38SStefano Zampini   PetscFunctionBegin;
21253425bc38SStefano Zampini   ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr);
21263425bc38SStefano Zampini   pcis = (PC_IS*)mat_ctx->pc->data;
21273425bc38SStefano Zampini   pcbddc = (PC_BDDC*)mat_ctx->pc->data;
21283425bc38SStefano Zampini 
21293425bc38SStefano Zampini   /* apply B_delta^T */
21303425bc38SStefano Zampini   ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
21313425bc38SStefano Zampini   ierr = VecScatterEnd  (mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
21323425bc38SStefano Zampini   ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr);
21333425bc38SStefano Zampini   /* compute rhs for BDDC application */
21343425bc38SStefano Zampini   ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr);
21358eeda7d8SStefano Zampini   if (pcbddc->switch_static) {
21363425bc38SStefano Zampini     ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr);
21373425bc38SStefano Zampini   }
21383425bc38SStefano Zampini   /* apply BDDC */
2139dc359a40SStefano Zampini   ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr);
21403425bc38SStefano Zampini   /* put values into standard global vector */
21413425bc38SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
21423425bc38SStefano Zampini   ierr = VecScatterEnd  (pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
21438eeda7d8SStefano Zampini   if (!pcbddc->switch_static) {
21443425bc38SStefano Zampini     /* compute values into the interior if solved for the partially subassembled Schur complement */
21453425bc38SStefano Zampini     ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr);
21463425bc38SStefano Zampini     ierr = VecAXPY(mat_ctx->temp_solution_D,-1.0,pcis->vec1_D);CHKERRQ(ierr);
21473425bc38SStefano Zampini     ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr);
21483425bc38SStefano Zampini   }
21493425bc38SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
21503425bc38SStefano Zampini   ierr = VecScatterEnd  (pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
21513425bc38SStefano Zampini   /* final change of basis if needed
21523425bc38SStefano Zampini      Is also sums the dirichlet part removed during RHS assembling */
21533308cffdSStefano Zampini   ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr);
21543425bc38SStefano Zampini   PetscFunctionReturn(0);
21553425bc38SStefano Zampini }
21561e6b0712SBarry Smith 
21573425bc38SStefano Zampini #undef __FUNCT__
21583425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution"
21593425bc38SStefano Zampini /*@
21600f202f7eSStefano Zampini  PCBDDCMatFETIDPGetSolution - Compute the physical solution using the solution of the FETI-DP linear system
21613425bc38SStefano Zampini 
21623425bc38SStefano Zampini    Collective
21633425bc38SStefano Zampini 
21643425bc38SStefano Zampini    Input Parameters:
21650f202f7eSStefano Zampini +  fetidp_mat      - the FETI-DP matrix obtained by a call to PCBDDCCreateFETIDPOperators
21660f202f7eSStefano Zampini -  fetidp_flux_sol - the solution of the FETI-DP linear system
21673425bc38SStefano Zampini 
21683425bc38SStefano Zampini    Output Parameters:
21690f202f7eSStefano Zampini .  standard_sol    - the solution defined on the physical domain
21703425bc38SStefano Zampini 
21713425bc38SStefano Zampini    Level: developer
21723425bc38SStefano Zampini 
21733425bc38SStefano Zampini    Notes:
21743425bc38SStefano Zampini 
21750f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetRHS
21763425bc38SStefano Zampini @*/
21773425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol)
21783425bc38SStefano Zampini {
2179674ae819SStefano Zampini   FETIDPMat_ctx  mat_ctx;
21803425bc38SStefano Zampini   PetscErrorCode ierr;
21813425bc38SStefano Zampini 
21823425bc38SStefano Zampini   PetscFunctionBegin;
21833425bc38SStefano Zampini   ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr);
21843425bc38SStefano Zampini   ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr);
21853425bc38SStefano Zampini   PetscFunctionReturn(0);
21863425bc38SStefano Zampini }
21873425bc38SStefano Zampini /* -------------------------------------------------------------------------- */
21881e6b0712SBarry Smith 
2189f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec);
2190edf7251bSStefano Zampini extern PetscErrorCode FETIDPMatMultTranspose(Mat,Vec,Vec);
2191f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat);
2192f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec);
2193edf7251bSStefano Zampini extern PetscErrorCode FETIDPPCApplyTranspose(PC,Vec,Vec);
2194f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC);
2195674ae819SStefano Zampini 
21963425bc38SStefano Zampini #undef __FUNCT__
21973425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC"
21983425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, Mat *fetidp_mat, PC *fetidp_pc)
21993425bc38SStefano Zampini {
2200674ae819SStefano Zampini 
2201674ae819SStefano Zampini   FETIDPMat_ctx  fetidpmat_ctx;
22023425bc38SStefano Zampini   Mat            newmat;
2203674ae819SStefano Zampini   FETIDPPC_ctx   fetidppc_ctx;
22043425bc38SStefano Zampini   PC             newpc;
2205ce94432eSBarry Smith   MPI_Comm       comm;
22063425bc38SStefano Zampini   PetscErrorCode ierr;
22073425bc38SStefano Zampini 
22083425bc38SStefano Zampini   PetscFunctionBegin;
2209ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr);
22103425bc38SStefano Zampini   /* FETIDP linear matrix */
22113425bc38SStefano Zampini   ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr);
22123425bc38SStefano Zampini   ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr);
22133425bc38SStefano Zampini   ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr);
22143425bc38SStefano Zampini   ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr);
2215edf7251bSStefano Zampini   ierr = MatShellSetOperation(newmat,MATOP_MULT_TRANSPOSE,(void (*)(void))FETIDPMatMultTranspose);CHKERRQ(ierr);
22163425bc38SStefano Zampini   ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr);
22173425bc38SStefano Zampini   ierr = MatSetUp(newmat);CHKERRQ(ierr);
22183425bc38SStefano Zampini   /* FETIDP preconditioner */
22193425bc38SStefano Zampini   ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr);
22203425bc38SStefano Zampini   ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr);
22213425bc38SStefano Zampini   ierr = PCCreate(comm,&newpc);CHKERRQ(ierr);
22223425bc38SStefano Zampini   ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr);
22233425bc38SStefano Zampini   ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr);
22243425bc38SStefano Zampini   ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr);
2225edf7251bSStefano Zampini   ierr = PCShellSetApplyTranspose(newpc,FETIDPPCApplyTranspose);CHKERRQ(ierr);
22263425bc38SStefano Zampini   ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr);
222723ee1639SBarry Smith   ierr = PCSetOperators(newpc,newmat,newmat);CHKERRQ(ierr);
22283425bc38SStefano Zampini   ierr = PCSetUp(newpc);CHKERRQ(ierr);
22293425bc38SStefano Zampini   /* return pointers for objects created */
22303425bc38SStefano Zampini   *fetidp_mat=newmat;
22313425bc38SStefano Zampini   *fetidp_pc=newpc;
22323425bc38SStefano Zampini   PetscFunctionReturn(0);
22333425bc38SStefano Zampini }
22341e6b0712SBarry Smith 
22353425bc38SStefano Zampini #undef __FUNCT__
22363425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators"
22373425bc38SStefano Zampini /*@
22380f202f7eSStefano Zampini  PCBDDCCreateFETIDPOperators - Create FETI-DP operators
22393425bc38SStefano Zampini 
22403425bc38SStefano Zampini    Collective
22413425bc38SStefano Zampini 
22423425bc38SStefano Zampini    Input Parameters:
22430f202f7eSStefano Zampini .  pc - the BDDC preconditioning context (setup should have been called before)
224428509bceSStefano Zampini 
224528509bceSStefano Zampini    Output Parameters:
22460f202f7eSStefano Zampini +  fetidp_mat - shell FETI-DP matrix object
22470f202f7eSStefano Zampini -  fetidp_pc  - shell Dirichlet preconditioner for FETI-DP matrix
224828509bceSStefano Zampini 
224928509bceSStefano Zampini    Options Database Keys:
22500f202f7eSStefano Zampini .    -fetidp_fullyredundant <false> - use or not a fully redundant set of Lagrange multipliers
22513425bc38SStefano Zampini 
22523425bc38SStefano Zampini    Level: developer
22533425bc38SStefano Zampini 
22543425bc38SStefano Zampini    Notes:
22550f202f7eSStefano Zampini      Currently the only operations provided for FETI-DP matrix are MatMult and MatMultTranspose
22563425bc38SStefano Zampini 
22570f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCMatFETIDPGetRHS, PCBDDCMatFETIDPGetSolution
22583425bc38SStefano Zampini @*/
22593425bc38SStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, Mat *fetidp_mat, PC *fetidp_pc)
22603425bc38SStefano Zampini {
22613425bc38SStefano Zampini   PetscErrorCode ierr;
22623425bc38SStefano Zampini 
22633425bc38SStefano Zampini   PetscFunctionBegin;
22643425bc38SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
22653425bc38SStefano Zampini   if (pc->setupcalled) {
2266516d51a7SStefano Zampini     ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,Mat*,PC*),(pc,fetidp_mat,fetidp_pc));CHKERRQ(ierr);
2267f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n");
22683425bc38SStefano Zampini   PetscFunctionReturn(0);
22693425bc38SStefano Zampini }
22700c7d97c5SJed Brown /* -------------------------------------------------------------------------- */
2271da1bb401SStefano Zampini /*MC
2272da1bb401SStefano Zampini    PCBDDC - Balancing Domain Decomposition by Constraints.
22730c7d97c5SJed Brown 
227428509bceSStefano Zampini    An implementation of the BDDC preconditioner based on
227528509bceSStefano Zampini 
227628509bceSStefano Zampini .vb
227728509bceSStefano Zampini    [1] C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007
227828509bceSStefano 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
227928509bceSStefano Zampini    [3] J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", http://arxiv.org/abs/0712.3977
22800f202f7eSStefano Zampini    [4] C. Pechstein and C. R. Dohrmann. "Modern domain decomposition methods BDDC, deluxe scaling, and an algebraic approach", Seminar talk, Linz, December 2013, http://people.ricam.oeaw.ac.at/c.pechstein/pechstein-bddc2013.pdf
228128509bceSStefano Zampini .ve
228228509bceSStefano Zampini 
228328509bceSStefano Zampini    The matrix to be preconditioned (Pmat) must be of type MATIS.
228428509bceSStefano Zampini 
22850f202f7eSStefano Zampini    Currently works with MATIS matrices with local matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers.
228628509bceSStefano Zampini 
228728509bceSStefano Zampini    It also works with unsymmetric and indefinite problems.
228828509bceSStefano Zampini 
2289b6fdb6dfSStefano 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.
2290b6fdb6dfSStefano Zampini 
22910f202f7eSStefano Zampini    Approximate local solvers are automatically adapted for singular linear problems (see [1]) if the user has provided the nullspace using PCBDDCSetNullSpace()
229228509bceSStefano Zampini 
22930f202f7eSStefano Zampini    Boundary nodes are split in vertices, edges and faces classes 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()
229430368db7SStefano Zampini    Additional information on dofs can be provided by using PCBDDCSetDofsSplitting(), PCBDDCSetDirichletBoundaries(), PCBDDCSetNeumannBoundaries(), and PCBDDCSetPrimalVerticesIS() and their local counterparts.
229528509bceSStefano Zampini 
22960f202f7eSStefano Zampini    Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace(). Non-singular modes are retained via SVD.
229728509bceSStefano Zampini 
22980f202f7eSStefano Zampini    Change of basis is performed similarly to [2] when requested. When more than 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.
22990f202f7eSStefano Zampini    User defined change of basis can be passed to PCBDDC by using PCBDDCSetChangeOfBasisMat()
230028509bceSStefano Zampini 
23010f202f7eSStefano Zampini    The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using a MatPartitioning object.
230228509bceSStefano Zampini 
2303df4d28bfSStefano Zampini    Adaptive selection of primal constraints [4] is supported for SPD systems with high-contrast in the coefficients if MUMPS or MKL_PARDISO are present. Future versions of the code will also consider using PASTIX.
230428509bceSStefano Zampini 
23050f202f7eSStefano Zampini    An experimental interface to the FETI-DP method is available. FETI-DP operators could be created using PCBDDCCreateFETIDPOperators(). A stand-alone class for the FETI-DP method will be provided in the next releases.
23060f202f7eSStefano Zampini    Deluxe scaling is not supported yet for FETI-DP.
23070f202f7eSStefano Zampini 
23080f202f7eSStefano Zampini    Options Database Keys (some of them, run with -h for a complete list):
23090f202f7eSStefano Zampini 
23100f202f7eSStefano Zampini .    -pc_bddc_use_vertices <true> - use or not vertices in primal space
23110f202f7eSStefano Zampini .    -pc_bddc_use_edges <true> - use or not edges in primal space
23120f202f7eSStefano Zampini .    -pc_bddc_use_faces <false> - use or not faces in primal space
23130f202f7eSStefano Zampini .    -pc_bddc_symmetric <true> - symmetric computation of primal basis functions. Specify false for unsymmetric problems
23140f202f7eSStefano Zampini .    -pc_bddc_use_change_of_basis <false> - use change of basis approach (on edges only)
23150f202f7eSStefano Zampini .    -pc_bddc_use_change_on_faces <false> - use change of basis approach on faces if change of basis has been requested
23160f202f7eSStefano Zampini .    -pc_bddc_switch_static <false> - switches from M_2 (default) to M_3 operator (see reference article [1])
231728509bceSStefano Zampini .    -pc_bddc_levels <0> - maximum number of levels for multilevel
23180f202f7eSStefano Zampini .    -pc_bddc_coarsening_ratio <8> - number of subdomains which will be aggregated together at the coarser level (e.g. H/h ratio at the coarser level, significative only in the multilevel case)
23190f202f7eSStefano Zampini .    -pc_bddc_redistribute <0> - size of a subset of processors where the coarse problem will be remapped (the value is ignored if not at the coarsest level)
23200f202f7eSStefano Zampini .    -pc_bddc_use_deluxe_scaling <false> - use deluxe scaling
23210f202f7eSStefano Zampini .    -pc_bddc_schur_layers <-1> - select the economic version of deluxe scaling by specifying the number of layers (-1 corresponds to the original deluxe scaling)
2322df4d28bfSStefano Zampini .    -pc_bddc_adaptive_threshold <0.0> - when a value greater than one is specified, adaptive selection of constraints is performed on edges and faces (requires deluxe scaling and MUMPS or MKL_PARDISO installed)
232328509bceSStefano Zampini -    -pc_bddc_check_level <0> - set verbosity level of debugging output
232428509bceSStefano Zampini 
232528509bceSStefano Zampini    Options for Dirichlet, Neumann or coarse solver can be set with
232628509bceSStefano Zampini .vb
232728509bceSStefano Zampini       -pc_bddc_dirichlet_
232828509bceSStefano Zampini       -pc_bddc_neumann_
232928509bceSStefano Zampini       -pc_bddc_coarse_
233028509bceSStefano Zampini .ve
23310f202f7eSStefano Zampini    e.g -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg. PCBDDC uses by default KPSPREONLY and PCLU.
233228509bceSStefano Zampini 
23330f202f7eSStefano Zampini    When using a multilevel approach, solvers' options at the N-th level (N > 1) can be specified as
233428509bceSStefano Zampini .vb
2335312be037SStefano Zampini       -pc_bddc_dirichlet_lN_
2336312be037SStefano Zampini       -pc_bddc_neumann_lN_
2337312be037SStefano Zampini       -pc_bddc_coarse_lN_
233828509bceSStefano Zampini .ve
23390f202f7eSStefano Zampini    Note that level number ranges from the finest (0) to the coarsest (N).
23400f202f7eSStefano Zampini    In order to specify options for the BDDC operators at the coarser levels (and not for the solvers), prepend -pc_bddc_coarse_ or -pc_bddc_coarse_l to the option, e.g.
23410f202f7eSStefano Zampini .vb
23420f202f7eSStefano Zampini      -pc_bddc_coarse_pc_bddc_adaptive_threshold 5 -pc_bddc_coarse_l1_pc_bddc_redistribute 3
23430f202f7eSStefano Zampini .ve
23440f202f7eSStefano Zampini    will use a threshold of 5 for constraints' selection at the first coarse level and will redistribute the coarse problem of the first coarse level on 3 processors
2345da1bb401SStefano Zampini 
2346da1bb401SStefano Zampini    Level: intermediate
2347da1bb401SStefano Zampini 
2348b6fdb6dfSStefano Zampini    Developer notes:
2349da1bb401SStefano Zampini 
2350da1bb401SStefano Zampini    Contributed by Stefano Zampini
2351da1bb401SStefano Zampini 
2352da1bb401SStefano Zampini .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,  MATIS
2353da1bb401SStefano Zampini M*/
2354b2573a8aSBarry Smith 
2355da1bb401SStefano Zampini #undef __FUNCT__
2356da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC"
23578cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc)
2358da1bb401SStefano Zampini {
2359da1bb401SStefano Zampini   PetscErrorCode      ierr;
2360da1bb401SStefano Zampini   PC_BDDC             *pcbddc;
2361da1bb401SStefano Zampini 
2362da1bb401SStefano Zampini   PetscFunctionBegin;
2363da1bb401SStefano Zampini   /* Creates the private data structure for this preconditioner and attach it to the PC object. */
2364b00a9115SJed Brown   ierr      = PetscNewLog(pc,&pcbddc);CHKERRQ(ierr);
2365da1bb401SStefano Zampini   pc->data  = (void*)pcbddc;
2366da1bb401SStefano Zampini 
2367da1bb401SStefano Zampini   /* create PCIS data structure */
2368da1bb401SStefano Zampini   ierr = PCISCreate(pc);CHKERRQ(ierr);
2369da1bb401SStefano Zampini 
237047d04d0dSStefano Zampini   /* BDDC customization */
237108a5cf49SStefano Zampini   pcbddc->use_local_adj       = PETSC_TRUE;
237247d04d0dSStefano Zampini   pcbddc->use_vertices        = PETSC_TRUE;
237347d04d0dSStefano Zampini   pcbddc->use_edges           = PETSC_TRUE;
237447d04d0dSStefano Zampini   pcbddc->use_faces           = PETSC_FALSE;
237547d04d0dSStefano Zampini   pcbddc->use_change_of_basis = PETSC_FALSE;
237647d04d0dSStefano Zampini   pcbddc->use_change_on_faces = PETSC_FALSE;
237747d04d0dSStefano Zampini   pcbddc->switch_static       = PETSC_FALSE;
2378fa434743SStefano Zampini   pcbddc->use_nnsp_true       = PETSC_FALSE;
2379fa434743SStefano Zampini   pcbddc->use_qr_single       = PETSC_FALSE;
23803301b35fSStefano Zampini   pcbddc->symmetric_primal    = PETSC_TRUE;
238106a4e24aSStefano Zampini   pcbddc->benign_saddle_point = PETSC_FALSE;
238214f95afaSStefano Zampini   pcbddc->vertex_size         = 1;
238347d04d0dSStefano Zampini   pcbddc->dbg_flag            = 0;
2384b9d89cd5SStefano Zampini   /* private */
2385727cdba6SStefano Zampini   pcbddc->local_primal_size          = 0;
23860e6343abSStefano Zampini   pcbddc->local_primal_size_cc       = 0;
23870e6343abSStefano Zampini   pcbddc->local_primal_ref_node      = 0;
23880e6343abSStefano Zampini   pcbddc->local_primal_ref_mult      = 0;
2389e9189074SStefano Zampini   pcbddc->n_vertices                 = 0;
2390727cdba6SStefano Zampini   pcbddc->primal_indices_local_idxs  = 0;
2391fb180af4SStefano Zampini   pcbddc->recompute_topography       = PETSC_FALSE;
239268457ee5SStefano Zampini   pcbddc->coarse_size                = -1;
2393f4ddd8eeSStefano Zampini   pcbddc->new_primal_space           = PETSC_FALSE;
2394727cdba6SStefano Zampini   pcbddc->new_primal_space_local     = PETSC_FALSE;
2395f4ddd8eeSStefano Zampini   pcbddc->global_primal_indices      = 0;
2396f4ddd8eeSStefano Zampini   pcbddc->onearnullspace             = 0;
2397f4ddd8eeSStefano Zampini   pcbddc->onearnullvecs_state        = 0;
2398674ae819SStefano Zampini   pcbddc->user_primal_vertices       = 0;
239930368db7SStefano Zampini   pcbddc->user_primal_vertices_local = 0;
24000bdf917eSStefano Zampini   pcbddc->NullSpace                  = 0;
24013972b0daSStefano Zampini   pcbddc->temp_solution              = 0;
2402534831adSStefano Zampini   pcbddc->original_rhs               = 0;
2403534831adSStefano Zampini   pcbddc->local_mat                  = 0;
2404534831adSStefano Zampini   pcbddc->ChangeOfBasisMatrix        = 0;
2405b9b85e73SStefano Zampini   pcbddc->user_ChangeOfBasisMatrix   = 0;
2406da1bb401SStefano Zampini   pcbddc->coarse_vec                 = 0;
2407da1bb401SStefano Zampini   pcbddc->coarse_ksp                 = 0;
2408da1bb401SStefano Zampini   pcbddc->coarse_phi_B               = 0;
2409da1bb401SStefano Zampini   pcbddc->coarse_phi_D               = 0;
241015aaf578SStefano Zampini   pcbddc->coarse_psi_B               = 0;
241115aaf578SStefano Zampini   pcbddc->coarse_psi_D               = 0;
2412da1bb401SStefano Zampini   pcbddc->vec1_P                     = 0;
2413da1bb401SStefano Zampini   pcbddc->vec1_R                     = 0;
2414da1bb401SStefano Zampini   pcbddc->vec2_R                     = 0;
2415da1bb401SStefano Zampini   pcbddc->local_auxmat1              = 0;
2416da1bb401SStefano Zampini   pcbddc->local_auxmat2              = 0;
2417da1bb401SStefano Zampini   pcbddc->R_to_B                     = 0;
2418da1bb401SStefano Zampini   pcbddc->R_to_D                     = 0;
2419da1bb401SStefano Zampini   pcbddc->ksp_D                      = 0;
2420da1bb401SStefano Zampini   pcbddc->ksp_R                      = 0;
2421da1bb401SStefano Zampini   pcbddc->NeumannBoundaries          = 0;
2422785d1243SStefano Zampini   pcbddc->NeumannBoundariesLocal     = 0;
2423785d1243SStefano Zampini   pcbddc->DirichletBoundaries        = 0;
2424785d1243SStefano Zampini   pcbddc->DirichletBoundariesLocal   = 0;
242560d44989SStefano Zampini   pcbddc->user_provided_isfordofs    = PETSC_FALSE;
242660d44989SStefano Zampini   pcbddc->n_ISForDofs                = 0;
242763602bcaSStefano Zampini   pcbddc->n_ISForDofsLocal           = 0;
2428da1bb401SStefano Zampini   pcbddc->ISForDofs                  = 0;
242963602bcaSStefano Zampini   pcbddc->ISForDofsLocal             = 0;
2430da1bb401SStefano Zampini   pcbddc->ConstraintMatrix           = 0;
243185c4d303SStefano Zampini   pcbddc->use_exact_dirichlet_trick  = PETSC_TRUE;
243247d04d0dSStefano Zampini   pcbddc->coarse_loc_to_glob         = 0;
243347d04d0dSStefano Zampini   pcbddc->coarsening_ratio           = 8;
2434b0c7d250SStefano Zampini   pcbddc->coarse_adj_red             = 0;
24354fad6a16SStefano Zampini   pcbddc->current_level              = 0;
24362b510759SStefano Zampini   pcbddc->max_levels                 = 0;
2437323d395dSStefano Zampini   pcbddc->use_coarse_estimates       = PETSC_FALSE;
243857de7509SStefano Zampini   pcbddc->coarse_eqs_per_proc        = 1;
2439f3bde8b3SStefano Zampini   pcbddc->coarse_subassembling       = 0;
24404f1b2e48SStefano Zampini   pcbddc->detect_disconnected        = PETSC_FALSE;
24414f1b2e48SStefano Zampini   pcbddc->n_local_subs               = 0;
24424f1b2e48SStefano Zampini   pcbddc->local_subs                 = NULL;
244381d14e9dSStefano Zampini 
244481d14e9dSStefano Zampini   /* benign subspace trick */
244581d14e9dSStefano Zampini   pcbddc->benign_change              = 0;
24460369aaf7SStefano Zampini   pcbddc->benign_vec                 = 0;
24470369aaf7SStefano Zampini   pcbddc->benign_original_mat        = 0;
24480369aaf7SStefano Zampini   pcbddc->benign_sf                  = 0;
24494f1b2e48SStefano Zampini   pcbddc->benign_B0                  = 0;
24504f1b2e48SStefano Zampini   pcbddc->benign_n                   = 0;
24514f1b2e48SStefano Zampini   pcbddc->benign_p0                  = NULL;
24524f1b2e48SStefano Zampini   pcbddc->benign_p0_lidx             = NULL;
24534f1b2e48SStefano Zampini   pcbddc->benign_p0_gidx             = NULL;
2454b0f5fe93SStefano Zampini   pcbddc->benign_null                = PETSC_FALSE;
245581d14e9dSStefano Zampini 
2456674ae819SStefano Zampini   /* create local graph structure */
2457674ae819SStefano Zampini   ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr);
2458674ae819SStefano Zampini 
2459674ae819SStefano Zampini   /* scaling */
2460674ae819SStefano Zampini   pcbddc->work_scaling          = 0;
246134a97f8cSStefano Zampini   pcbddc->use_deluxe_scaling    = PETSC_FALSE;
2462b96c3477SStefano Zampini 
2463b96c3477SStefano Zampini   /* create sub schurs structure */
2464b96c3477SStefano Zampini   ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr);
2465b96c3477SStefano Zampini   pcbddc->sub_schurs_rebuild     = PETSC_FALSE;
2466b96c3477SStefano Zampini   pcbddc->sub_schurs_layers      = -1;
2467b96c3477SStefano Zampini   pcbddc->sub_schurs_use_useradj = PETSC_FALSE;
2468b96c3477SStefano Zampini 
2469b96c3477SStefano Zampini   pcbddc->computed_rowadj = PETSC_FALSE;
2470da1bb401SStefano Zampini 
2471b7eb3628SStefano Zampini   /* adaptivity */
2472f6f667cfSStefano Zampini   pcbddc->adaptive_threshold      = 0.0;
247308122e43SStefano Zampini   pcbddc->adaptive_nmax           = 0;
2474f6f667cfSStefano Zampini   pcbddc->adaptive_nmin           = 0;
2475b7eb3628SStefano Zampini 
2476da1bb401SStefano Zampini   /* function pointers */
2477da1bb401SStefano Zampini   pc->ops->apply               = PCApply_BDDC;
247893bd9ae7SStefano Zampini   pc->ops->applytranspose      = PCApplyTranspose_BDDC;
2479da1bb401SStefano Zampini   pc->ops->setup               = PCSetUp_BDDC;
2480da1bb401SStefano Zampini   pc->ops->destroy             = PCDestroy_BDDC;
2481da1bb401SStefano Zampini   pc->ops->setfromoptions      = PCSetFromOptions_BDDC;
24826b78500eSPatrick Sanan   pc->ops->view                = PCView_BDDC;
2483da1bb401SStefano Zampini   pc->ops->applyrichardson     = 0;
2484da1bb401SStefano Zampini   pc->ops->applysymmetricleft  = 0;
2485da1bb401SStefano Zampini   pc->ops->applysymmetricright = 0;
2486534831adSStefano Zampini   pc->ops->presolve            = PCPreSolve_BDDC;
2487534831adSStefano Zampini   pc->ops->postsolve           = PCPostSolve_BDDC;
2488da1bb401SStefano Zampini 
2489da1bb401SStefano Zampini   /* composing function */
2490906d46d4SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",PCBDDCSetChangeOfBasisMat_BDDC);CHKERRQ(ierr);
2491674ae819SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr);
249230368db7SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",PCBDDCSetPrimalVerticesIS_BDDC);CHKERRQ(ierr);
2493bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr);
24942b510759SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr);
2495b8ffe317SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr);
24962b510759SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr);
2497bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",PCBDDCSetNullSpace_BDDC);CHKERRQ(ierr);
2498bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr);
249982ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr);
2500bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr);
250182ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr);
2502bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr);
250382ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr);
2504bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr);
250582ba6b80SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr);
2506bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr);
250763602bcaSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",PCBDDCSetDofsSplittingLocal_BDDC);CHKERRQ(ierr);
2508bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr);
2509bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr);
2510bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr);
2511bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr);
2512da1bb401SStefano Zampini   PetscFunctionReturn(0);
2513da1bb401SStefano Zampini }
25143425bc38SStefano Zampini 
2515