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 MATIS related operations contained in BDDC code 18eb97c9d2SStefano Zampini - Provide general case for subassembling 19eb97c9d2SStefano Zampini 2053cdbc3dSStefano Zampini */ 210c7d97c5SJed Brown 22ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 23ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 243b03a366Sstefano_zampini #include <petscblaslapack.h> 25674ae819SStefano Zampini 2643371fb9SStefano Zampini static PetscBool PCBDDCPackageInitialized = PETSC_FALSE; 2743371fb9SStefano Zampini 28f3d41395Sstefano_zampini static PetscBool cited = PETSC_FALSE; 29f3d41395Sstefano_zampini static const char citation[] = 30f3d41395Sstefano_zampini "@article{ZampiniPCBDDC,\n" 31f3d41395Sstefano_zampini "author = {Stefano Zampini},\n" 32f3d41395Sstefano_zampini "title = {{PCBDDC}: A Class of Robust Dual-Primal Methods in {PETS}c},\n" 33f3d41395Sstefano_zampini "journal = {SIAM Journal on Scientific Computing},\n" 34f3d41395Sstefano_zampini "volume = {38},\n" 35f3d41395Sstefano_zampini "number = {5},\n" 36f3d41395Sstefano_zampini "pages = {S282-S306},\n" 37f3d41395Sstefano_zampini "year = {2016},\n" 38f3d41395Sstefano_zampini "doi = {10.1137/15M1025785},\n" 39f3d41395Sstefano_zampini "URL = {http://dx.doi.org/10.1137/15M1025785},\n" 40f3d41395Sstefano_zampini "eprint = {http://dx.doi.org/10.1137/15M1025785}\n" 41f3d41395Sstefano_zampini "}\n"; 42f3d41395Sstefano_zampini 4343371fb9SStefano Zampini PetscLogEvent PC_BDDC_Topology[PETSC_PCBDDC_MAXLEVELS]; 4443371fb9SStefano Zampini PetscLogEvent PC_BDDC_LocalSolvers[PETSC_PCBDDC_MAXLEVELS]; 4543371fb9SStefano Zampini PetscLogEvent PC_BDDC_LocalWork[PETSC_PCBDDC_MAXLEVELS]; 4643371fb9SStefano Zampini PetscLogEvent PC_BDDC_CorrectionSetUp[PETSC_PCBDDC_MAXLEVELS]; 478ead10e4SStefano Zampini PetscLogEvent PC_BDDC_ApproxSetUp[PETSC_PCBDDC_MAXLEVELS]; 488ead10e4SStefano Zampini PetscLogEvent PC_BDDC_ApproxApply[PETSC_PCBDDC_MAXLEVELS]; 4943371fb9SStefano Zampini PetscLogEvent PC_BDDC_CoarseSetUp[PETSC_PCBDDC_MAXLEVELS]; 5043371fb9SStefano Zampini PetscLogEvent PC_BDDC_CoarseSolver[PETSC_PCBDDC_MAXLEVELS]; 5143371fb9SStefano Zampini PetscLogEvent PC_BDDC_AdaptiveSetUp[PETSC_PCBDDC_MAXLEVELS]; 5243371fb9SStefano Zampini PetscLogEvent PC_BDDC_Scaling[PETSC_PCBDDC_MAXLEVELS]; 5343371fb9SStefano Zampini PetscLogEvent PC_BDDC_Schurs[PETSC_PCBDDC_MAXLEVELS]; 5455c176c0SStefano Zampini PetscLogEvent PC_BDDC_Solves[PETSC_PCBDDC_MAXLEVELS][3]; 5543371fb9SStefano Zampini 56bc960bbfSJed Brown const char *const PCBDDCInterfaceExtTypes[] = {"DIRICHLET","LUMP","PCBDDCInterfaceExtType","PC_BDDC_INTERFACE_EXT_",NULL}; 57bc960bbfSJed Brown 580369aaf7SStefano Zampini PetscErrorCode PCApply_BDDC(PC,Vec,Vec); 590369aaf7SStefano Zampini 604416b707SBarry Smith PetscErrorCode PCSetFromOptions_BDDC(PetscOptionItems *PetscOptionsObject,PC pc) 610c7d97c5SJed Brown { 620c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 63e569e4e1SStefano Zampini PetscInt nt,i; 640c7d97c5SJed Brown PetscErrorCode ierr; 650c7d97c5SJed Brown 660c7d97c5SJed Brown PetscFunctionBegin; 67e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"BDDC options");CHKERRQ(ierr); 688eeda7d8SStefano Zampini /* Verbose debugging */ 69a13144ffSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_check_level","Verbose output for PCBDDC (intended for debug)","none",pcbddc->dbg_flag,&pcbddc->dbg_flag,NULL);CHKERRQ(ierr); 70a13144ffSStefano Zampini /* Approximate solvers */ 71bc960bbfSJed Brown ierr = PetscOptionsEnum("-pc_bddc_interface_ext_type","Use DIRICHLET or LUMP to extend interface corrections to interior","PCBDDCSetInterfaceExtType",PCBDDCInterfaceExtTypes,(PetscEnum)pcbddc->interface_extension,(PetscEnum*)&pcbddc->interface_extension,NULL);CHKERRQ(ierr); 72bc960bbfSJed Brown if (pcbddc->interface_extension == PC_BDDC_INTERFACE_EXT_DIRICHLET) { 73c7017625SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_dirichlet_approximate","Inform PCBDDC that we are using approximate Dirichlet solvers","none",pcbddc->NullSpace_corr[0],&pcbddc->NullSpace_corr[0],NULL);CHKERRQ(ierr); 74c7017625SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_dirichlet_approximate_scale","Inform PCBDDC that we need to scale the Dirichlet solve","none",pcbddc->NullSpace_corr[1],&pcbddc->NullSpace_corr[1],NULL);CHKERRQ(ierr); 75bc960bbfSJed Brown } else { 76bc960bbfSJed Brown /* This flag is needed/implied by lumping */ 77bc960bbfSJed Brown pcbddc->switch_static = PETSC_TRUE; 78bc960bbfSJed Brown } 79c7017625SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_neumann_approximate","Inform PCBDDC that we are using approximate Neumann solvers","none",pcbddc->NullSpace_corr[2],&pcbddc->NullSpace_corr[2],NULL);CHKERRQ(ierr); 80c7017625SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_neumann_approximate_scale","Inform PCBDDC that we need to scale the Neumann solve","none",pcbddc->NullSpace_corr[3],&pcbddc->NullSpace_corr[3],NULL);CHKERRQ(ierr); 816b78500eSPatrick Sanan /* Primal space customization */ 8208a5cf49SStefano 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); 83be12c134Sstefano_zampini ierr = PetscOptionsInt("-pc_bddc_graph_maxcount","Maximum number of shared subdomains for a connected component","none",pcbddc->graphmaxcount,&pcbddc->graphmaxcount,NULL);CHKERRQ(ierr); 841c7a958bSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_corner_selection","Activates face-based corner selection","none",pcbddc->corner_selection,&pcbddc->corner_selection,NULL);CHKERRQ(ierr); 858eeda7d8SStefano 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); 868eeda7d8SStefano 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); 878eeda7d8SStefano 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); 8814f95afaSStefano 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); 896d9e27e4SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_nnsp","Use near null space attached to the matrix to compute constraints","none",pcbddc->use_nnsp,&pcbddc->use_nnsp,NULL);CHKERRQ(ierr); 906d9e27e4SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_nnsp_true","Use near null space attached to the matrix to compute constraints as is","none",pcbddc->use_nnsp_true,&pcbddc->use_nnsp_true,NULL);CHKERRQ(ierr); 9114f95afaSStefano 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); 928eeda7d8SStefano Zampini /* Change of basis */ 93b9b85e73SStefano 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); 94b9b85e73SStefano 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); 95674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 96674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 97674ae819SStefano Zampini } 988eeda7d8SStefano Zampini /* Switch between M_2 (default) and M_3 preconditioners (as defined by C. Dohrmann in the ref. article) */ 998eeda7d8SStefano 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); 100e569e4e1SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_coarse_eqs_per_proc","Target 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); 101e569e4e1SStefano Zampini i = pcbddc->coarsening_ratio; 102e569e4e1SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","PCBDDCSetCoarseningRatio",i,&i,NULL);CHKERRQ(ierr); 103e569e4e1SStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc,i);CHKERRQ(ierr); 104e569e4e1SStefano Zampini i = pcbddc->max_levels; 105e569e4e1SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_levels","Set maximum number of levels for multilevel","PCBDDCSetLevels",i,&i,NULL);CHKERRQ(ierr); 106e569e4e1SStefano Zampini ierr = PCBDDCSetLevels(pc,i);CHKERRQ(ierr); 107e569e4e1SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_coarse_eqs_limit","Set maximum number of equations on coarsest grid to aim for","none",pcbddc->coarse_eqs_limit,&pcbddc->coarse_eqs_limit,NULL);CHKERRQ(ierr); 108323d395dSStefano 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); 109674ae819SStefano 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); 110b96c3477SStefano 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); 111b96c3477SStefano 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); 112b96c3477SStefano 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); 113683d3df6SStefano 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); 114bf3a8328SStefano 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); 115839e9adbSstefano_zampini ierr = PetscOptionsBool("-pc_bddc_deluxe_singlemat","Collapse deluxe operators","none",pcbddc->deluxe_singlemat,&pcbddc->deluxe_singlemat,NULL);CHKERRQ(ierr); 116bf3a8328SStefano 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); 117bd2a564bSStefano Zampini nt = 2; 118bd2a564bSStefano Zampini ierr = PetscOptionsRealArray("-pc_bddc_adaptive_threshold","Thresholds to be used for adaptive selection of constraints","none",pcbddc->adaptive_threshold,&nt,NULL);CHKERRQ(ierr); 119bd2a564bSStefano Zampini if (nt == 1) pcbddc->adaptive_threshold[1] = pcbddc->adaptive_threshold[0]; 12008122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmin","Minimum number of constraints per connected components","none",pcbddc->adaptive_nmin,&pcbddc->adaptive_nmin,NULL);CHKERRQ(ierr); 12108122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmax","Maximum number of constraints per connected components","none",pcbddc->adaptive_nmax,&pcbddc->adaptive_nmax,NULL);CHKERRQ(ierr); 1223301b35fSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_symmetric","Symmetric computation of primal basis functions","none",pcbddc->symmetric_primal,&pcbddc->symmetric_primal,NULL);CHKERRQ(ierr); 123b0c7d250SStefano 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); 124b3afcdbeSStefano 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); 125e9627c49SStefano 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); 12627b6a85dSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_benign_compute_correction","Compute the benign correction during PreSolve","none",pcbddc->benign_compute_correction,&pcbddc->benign_compute_correction,NULL);CHKERRQ(ierr); 127a198735bSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nonetflux","Automatic computation of no-net-flux quadrature weights","none",pcbddc->compute_nonetflux,&pcbddc->compute_nonetflux,NULL);CHKERRQ(ierr); 1284f1b2e48SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_detect_disconnected","Detects disconnected subdomains","none",pcbddc->detect_disconnected,&pcbddc->detect_disconnected,NULL);CHKERRQ(ierr); 1298361f951SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_detect_disconnected_filter","Filters out small entries in the local matrix when detecting disconnected subdomains","none",pcbddc->detect_disconnected_filter,&pcbddc->detect_disconnected_filter,NULL);CHKERRQ(ierr); 13070c64980SStefano 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); 1310c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 1320c7d97c5SJed Brown PetscFunctionReturn(0); 1330c7d97c5SJed Brown } 1346b78500eSPatrick Sanan 1356b78500eSPatrick Sanan static PetscErrorCode PCView_BDDC(PC pc,PetscViewer viewer) 1366b78500eSPatrick Sanan { 1376b78500eSPatrick Sanan PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 138e9627c49SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1396b78500eSPatrick Sanan PetscErrorCode ierr; 14071783a16SStefano Zampini PetscBool isascii; 141e9627c49SStefano Zampini PetscSubcomm subcomm; 142e9627c49SStefano Zampini PetscViewer subviewer; 1436b78500eSPatrick Sanan 1446b78500eSPatrick Sanan PetscFunctionBegin; 1456b78500eSPatrick Sanan ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1466b78500eSPatrick Sanan /* ASCII viewer */ 1476b78500eSPatrick Sanan if (isascii) { 1484b2aedd3SStefano Zampini PetscMPIInt color,rank,size; 149fbad9177SStefano Zampini PetscInt64 loc[7],gsum[6],gmax[6],gmin[6],totbenign; 150e9627c49SStefano Zampini PetscScalar interface_size; 151e9627c49SStefano Zampini PetscReal ratio1=0.,ratio2=0.; 152e9627c49SStefano Zampini Vec counter; 1536b78500eSPatrick Sanan 154b74ba07aSstefano_zampini if (!pc->setupcalled) { 155b74ba07aSstefano_zampini ierr = PetscViewerASCIIPrintf(viewer," Partial information available: preconditioner has not been setup yet\n");CHKERRQ(ierr); 156b74ba07aSstefano_zampini } 157efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use verbose output: %D\n",pcbddc->dbg_flag);CHKERRQ(ierr); 1586f0c0a6aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use user-defined CSR: %d\n",!!pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 1596f0c0a6aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use local mat graph: %d\n",pcbddc->use_local_adj && !pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 160e9627c49SStefano Zampini if (pcbddc->mat_graph->twodim) { 161efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Connectivity graph topological dimension: 2\n");CHKERRQ(ierr); 162e9627c49SStefano Zampini } else { 163efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Connectivity graph topological dimension: 3\n");CHKERRQ(ierr); 164e9627c49SStefano Zampini } 165aefa1729SStefano Zampini if (pcbddc->graphmaxcount != PETSC_MAX_INT) { 166efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Graph max count: %D\n",pcbddc->graphmaxcount);CHKERRQ(ierr); 167aefa1729SStefano Zampini } 1680dfc91b7SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Corner selection: %d (selected %d)\n",pcbddc->corner_selection,pcbddc->corner_selected);CHKERRQ(ierr); 16950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use vertices: %d (vertex size %D)\n",pcbddc->use_vertices,pcbddc->vertex_size);CHKERRQ(ierr); 170efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use edges: %d\n",pcbddc->use_edges);CHKERRQ(ierr); 171efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use faces: %d\n",pcbddc->use_faces);CHKERRQ(ierr); 172efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use true near null space: %d\n",pcbddc->use_nnsp_true);CHKERRQ(ierr); 173efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use QR for single constraints on cc: %d\n",pcbddc->use_qr_single);CHKERRQ(ierr); 174efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use change of basis on local edge nodes: %d\n",pcbddc->use_change_of_basis);CHKERRQ(ierr); 175efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use change of basis on local face nodes: %d\n",pcbddc->use_change_on_faces);CHKERRQ(ierr); 176efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," User defined change of basis matrix: %d\n",!!pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 177efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Has change of basis matrix: %d\n",!!pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 178efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eliminate dirichlet boundary dofs: %d\n",pcbddc->eliminate_dirdofs);CHKERRQ(ierr); 179efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Switch on static condensation ops around the interface preconditioner: %d\n",pcbddc->switch_static);CHKERRQ(ierr); 180efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use exact dirichlet trick: %d\n",pcbddc->use_exact_dirichlet_trick);CHKERRQ(ierr); 181bc960bbfSJed Brown ierr = PetscViewerASCIIPrintf(viewer," Interface extension: %s\n",PCBDDCInterfaceExtTypes[pcbddc->interface_extension]);CHKERRQ(ierr); 18250e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Multilevel max levels: %D\n",pcbddc->max_levels);CHKERRQ(ierr); 18350e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Multilevel coarsening ratio: %D\n",pcbddc->coarsening_ratio);CHKERRQ(ierr); 184efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use estimated eigs for coarse problem: %d\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 185efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe scaling: %d\n",pcbddc->use_deluxe_scaling);CHKERRQ(ierr); 186efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe zerorows: %d\n",pcbddc->deluxe_zerorows);CHKERRQ(ierr); 187efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe singlemat: %d\n",pcbddc->deluxe_singlemat);CHKERRQ(ierr); 188efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Rebuild interface graph for Schur principal minors: %d\n",pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 18950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Number of dofs' layers for the computation of principal minors: %D\n",pcbddc->sub_schurs_layers);CHKERRQ(ierr); 190efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use user CSR graph to compute successive layers: %d\n",pcbddc->sub_schurs_use_useradj);CHKERRQ(ierr); 191bd2a564bSStefano Zampini if (pcbddc->adaptive_threshold[1] != pcbddc->adaptive_threshold[0]) { 192bd2a564bSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Adaptive constraint selection thresholds (active %d, userdefined %d): %g,%g\n",pcbddc->adaptive_selection,pcbddc->adaptive_userdefined,pcbddc->adaptive_threshold[0],pcbddc->adaptive_threshold[1]);CHKERRQ(ierr); 193bd2a564bSStefano Zampini } else { 194bd2a564bSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Adaptive constraint selection threshold (active %d, userdefined %d): %g\n",pcbddc->adaptive_selection,pcbddc->adaptive_userdefined,pcbddc->adaptive_threshold[0]);CHKERRQ(ierr); 195bd2a564bSStefano Zampini } 19650e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Min constraints / connected component: %D\n",pcbddc->adaptive_nmin);CHKERRQ(ierr); 19750e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Max constraints / connected component: %D\n",pcbddc->adaptive_nmax);CHKERRQ(ierr); 198efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Invert exact Schur complement for adaptive selection: %d\n",pcbddc->sub_schurs_exact_schur);CHKERRQ(ierr); 199efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Symmetric computation of primal basis functions: %d\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 20050e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Num. Procs. to map coarse adjacency list: %D\n",pcbddc->coarse_adj_red);CHKERRQ(ierr); 20150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Coarse eqs per proc (significant at the coarsest level): %D\n",pcbddc->coarse_eqs_per_proc);CHKERRQ(ierr); 2028361f951SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Detect disconnected: %d (filter %d)\n",pcbddc->detect_disconnected,pcbddc->detect_disconnected_filter);CHKERRQ(ierr); 203efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Benign subspace trick: %d (change explicit %d)\n",pcbddc->benign_saddle_point,pcbddc->benign_change_explicit);CHKERRQ(ierr); 204efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Benign subspace trick is active: %d\n",pcbddc->benign_have_null);CHKERRQ(ierr); 20515579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Algebraic computation of no-net-flux: %d\n",pcbddc->compute_nonetflux);CHKERRQ(ierr); 206b74ba07aSstefano_zampini if (!pc->setupcalled) PetscFunctionReturn(0); 2076b78500eSPatrick Sanan 208fbad9177SStefano Zampini /* compute interface size */ 209e9627c49SStefano Zampini ierr = VecSet(pcis->vec1_B,1.0);CHKERRQ(ierr); 2100a545947SLisandro Dalcin ierr = MatCreateVecs(pc->pmat,&counter,NULL);CHKERRQ(ierr); 211e9627c49SStefano Zampini ierr = VecSet(counter,0.0);CHKERRQ(ierr); 212e9627c49SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 213e9627c49SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 214e9627c49SStefano Zampini ierr = VecSum(counter,&interface_size);CHKERRQ(ierr); 215e9627c49SStefano Zampini ierr = VecDestroy(&counter);CHKERRQ(ierr); 216fbad9177SStefano Zampini 217fbad9177SStefano Zampini /* compute some statistics on the domain decomposition */ 218e9627c49SStefano Zampini gsum[0] = 1; 219fbad9177SStefano Zampini gsum[1] = gsum[2] = gsum[3] = gsum[4] = gsum[5] = 0; 220e9627c49SStefano Zampini loc[0] = !!pcis->n; 221e9627c49SStefano Zampini loc[1] = pcis->n - pcis->n_B; 222e9627c49SStefano Zampini loc[2] = pcis->n_B; 223e9627c49SStefano Zampini loc[3] = pcbddc->local_primal_size; 224345ecf6cSStefano Zampini loc[4] = pcis->n; 225fbad9177SStefano Zampini loc[5] = pcbddc->n_local_subs > 0 ? pcbddc->n_local_subs : (pcis->n ? 1 : 0); 226fbad9177SStefano Zampini loc[6] = pcbddc->benign_n; 227ffc4695bSBarry Smith ierr = MPI_Reduce(loc,gsum,6,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRMPI(ierr); 228fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = -1; 229ffc4695bSBarry Smith ierr = MPI_Reduce(loc,gmax,6,MPIU_INT64,MPI_MAX,0,PetscObjectComm((PetscObject)pc));CHKERRMPI(ierr); 230fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = PETSC_MAX_INT; 231ffc4695bSBarry Smith ierr = MPI_Reduce(loc,gmin,6,MPIU_INT64,MPI_MIN,0,PetscObjectComm((PetscObject)pc));CHKERRMPI(ierr); 232ffc4695bSBarry Smith ierr = MPI_Reduce(&loc[6],&totbenign,1,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRMPI(ierr); 233e9627c49SStefano Zampini if (pcbddc->coarse_size) { 234e9627c49SStefano Zampini ratio1 = pc->pmat->rmap->N/(1.*pcbddc->coarse_size); 235e9627c49SStefano Zampini ratio2 = PetscRealPart(interface_size)/pcbddc->coarse_size; 236e9627c49SStefano Zampini } 237efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"********************************** STATISTICS AT LEVEL %d **********************************\n",pcbddc->current_level);CHKERRQ(ierr); 23850e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Global dofs sizes: all %D interface %D coarse %D\n",pc->pmat->rmap->N,(PetscInt)PetscRealPart(interface_size),pcbddc->coarse_size);CHKERRQ(ierr); 23950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Coarsening ratios: all/coarse %D interface/coarse %D\n",(PetscInt)ratio1,(PetscInt)ratio2);CHKERRQ(ierr); 24050e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Active processes : %D\n",(PetscInt)gsum[0]);CHKERRQ(ierr); 24150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Total subdomains : %D\n",(PetscInt)gsum[5]);CHKERRQ(ierr); 242345ecf6cSStefano Zampini if (pcbddc->benign_have_null) { 24350e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Benign subs : %D\n",(PetscInt)totbenign);CHKERRQ(ierr); 244345ecf6cSStefano Zampini } 24550e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Dofs type :\tMIN\tMAX\tMEAN\n");CHKERRQ(ierr); 24650e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Interior dofs :\t%D\t%D\t%D\n",(PetscInt)gmin[1],(PetscInt)gmax[1],(PetscInt)(gsum[1]/gsum[0]));CHKERRQ(ierr); 24750e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Interface dofs :\t%D\t%D\t%D\n",(PetscInt)gmin[2],(PetscInt)gmax[2],(PetscInt)(gsum[2]/gsum[0]));CHKERRQ(ierr); 24850e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Primal dofs :\t%D\t%D\t%D\n",(PetscInt)gmin[3],(PetscInt)gmax[3],(PetscInt)(gsum[3]/gsum[0]));CHKERRQ(ierr); 24950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Local dofs :\t%D\t%D\t%D\n",(PetscInt)gmin[4],(PetscInt)gmax[4],(PetscInt)(gsum[4]/gsum[0]));CHKERRQ(ierr); 25050e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Local subs :\t%D\t%D\n" ,(PetscInt)gmin[5],(PetscInt)gmax[5]);CHKERRQ(ierr); 25115579a77SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 25215579a77SStefano Zampini 253ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRMPI(ierr); 25415579a77SStefano Zampini 25515579a77SStefano Zampini /* local solvers */ 25615579a77SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscObjectComm((PetscObject)pcbddc->ksp_D),&subviewer);CHKERRQ(ierr); 257dd400576SPatrick Sanan if (rank == 0) { 25815579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Interior solver (rank 0)\n");CHKERRQ(ierr); 25915579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 26015579a77SStefano Zampini ierr = KSPView(pcbddc->ksp_D,subviewer);CHKERRQ(ierr); 26115579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 26215579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Correction solver (rank 0)\n");CHKERRQ(ierr); 26315579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 26415579a77SStefano Zampini ierr = KSPView(pcbddc->ksp_R,subviewer);CHKERRQ(ierr); 26515579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 26615579a77SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 26715579a77SStefano Zampini } 26815579a77SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscObjectComm((PetscObject)pcbddc->ksp_D),&subviewer);CHKERRQ(ierr); 26927b6a85dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 270e9627c49SStefano Zampini 271fbad9177SStefano Zampini /* the coarse problem can be handled by a different communicator */ 272e9627c49SStefano Zampini if (pcbddc->coarse_ksp) color = 1; 273e9627c49SStefano Zampini else color = 0; 274ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRMPI(ierr); 275e9627c49SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)pc),&subcomm);CHKERRQ(ierr); 2764b2aedd3SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,PetscMin(size,2));CHKERRQ(ierr); 277e9627c49SStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 278e9627c49SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 279e9627c49SStefano Zampini if (color == 1) { 28015579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Coarse solver\n");CHKERRQ(ierr); 28115579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 282e9627c49SStefano Zampini ierr = KSPView(pcbddc->coarse_ksp,subviewer);CHKERRQ(ierr); 28315579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 284e9627c49SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 285e9627c49SStefano Zampini } 286e9627c49SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 287e9627c49SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 288e9627c49SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 289e9627c49SStefano Zampini } 2906b78500eSPatrick Sanan PetscFunctionReturn(0); 2916b78500eSPatrick Sanan } 292a13144ffSStefano Zampini 2931e0482f5SStefano Zampini static PetscErrorCode PCBDDCSetDiscreteGradient_BDDC(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 294a13144ffSStefano Zampini { 295a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 296a13144ffSStefano Zampini PetscErrorCode ierr; 297a13144ffSStefano Zampini 298a13144ffSStefano Zampini PetscFunctionBegin; 299a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr); 300a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 301a13144ffSStefano Zampini pcbddc->discretegradient = G; 302a13144ffSStefano Zampini pcbddc->nedorder = order > 0 ? order : -order; 303495a2a07SStefano Zampini pcbddc->nedfield = field; 3041e0482f5SStefano Zampini pcbddc->nedglobal = global; 3051e0482f5SStefano Zampini pcbddc->conforming = conforming; 306a13144ffSStefano Zampini PetscFunctionReturn(0); 307a13144ffSStefano Zampini } 308a13144ffSStefano Zampini 309a13144ffSStefano Zampini /*@ 310a13144ffSStefano Zampini PCBDDCSetDiscreteGradient - Sets the discrete gradient 311a13144ffSStefano Zampini 312a13144ffSStefano Zampini Collective on PC 313a13144ffSStefano Zampini 314a13144ffSStefano Zampini Input Parameters: 315a13144ffSStefano Zampini + pc - the preconditioning context 316a13144ffSStefano Zampini . G - the discrete gradient matrix (should be in AIJ format) 317a13144ffSStefano Zampini . order - the order of the Nedelec space (1 for the lowest order) 318495a2a07SStefano Zampini . field - the field id of the Nedelec dofs (not used if the fields have not been specified) 3191e0482f5SStefano Zampini . global - the type of global ordering for the rows of G 320a13144ffSStefano Zampini - conforming - whether the mesh is conforming or not 321a13144ffSStefano Zampini 322a13144ffSStefano Zampini Level: advanced 323a13144ffSStefano Zampini 32495452b02SPatrick Sanan Notes: 32595452b02SPatrick Sanan The discrete gradient matrix G is used to analyze the subdomain edges, and it should not contain any zero entry. 326495a2a07SStefano Zampini For variable order spaces, the order should be set to zero. 3271e0482f5SStefano Zampini If global is true, the rows of G should be given in global ordering for the whole dofs; 3281e0482f5SStefano Zampini if false, the ordering should be global for the Nedelec field. 3291e0482f5SStefano Zampini In the latter case, it should hold gid[i] < gid[j] iff geid[i] < geid[j], with gid the global orderding for all the dofs 3301e0482f5SStefano Zampini and geid the one for the Nedelec field. 331a13144ffSStefano Zampini 332495a2a07SStefano Zampini .seealso: PCBDDC,PCBDDCSetDofsSplitting(),PCBDDCSetDofsSplittingLocal() 333a13144ffSStefano Zampini @*/ 3341e0482f5SStefano Zampini PetscErrorCode PCBDDCSetDiscreteGradient(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 335a13144ffSStefano Zampini { 336a13144ffSStefano Zampini PetscErrorCode ierr; 337a13144ffSStefano Zampini 338a13144ffSStefano Zampini PetscFunctionBegin; 339a13144ffSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 340a13144ffSStefano Zampini PetscValidHeaderSpecific(G,MAT_CLASSID,2); 341a13144ffSStefano Zampini PetscValidLogicalCollectiveInt(pc,order,3); 3421e0482f5SStefano Zampini PetscValidLogicalCollectiveInt(pc,field,4); 3431e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,global,5); 3441e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,conforming,6); 3451e0482f5SStefano Zampini PetscCheckSameComm(pc,1,G,2); 3461e0482f5SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDiscreteGradient_C",(PC,Mat,PetscInt,PetscInt,PetscBool,PetscBool),(pc,G,order,field,global,conforming));CHKERRQ(ierr); 347a13144ffSStefano Zampini PetscFunctionReturn(0); 348a13144ffSStefano Zampini } 349a13144ffSStefano Zampini 3508ae0ca82SStefano Zampini static PetscErrorCode PCBDDCSetDivergenceMat_BDDC(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 351a198735bSStefano Zampini { 352a198735bSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 353a198735bSStefano Zampini PetscErrorCode ierr; 3546b78500eSPatrick Sanan 355a198735bSStefano Zampini PetscFunctionBegin; 356a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)divudotp);CHKERRQ(ierr); 357a198735bSStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 358a198735bSStefano Zampini pcbddc->divudotp = divudotp; 3598ae0ca82SStefano Zampini pcbddc->divudotp_trans = trans; 360a198735bSStefano Zampini pcbddc->compute_nonetflux = PETSC_TRUE; 361a198735bSStefano Zampini if (vl2l) { 362a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2l);CHKERRQ(ierr); 363fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 364a198735bSStefano Zampini pcbddc->divudotp_vl2l = vl2l; 365a198735bSStefano Zampini } 366a198735bSStefano Zampini PetscFunctionReturn(0); 367a198735bSStefano Zampini } 3683d996552SStefano Zampini 369a198735bSStefano Zampini /*@ 370a198735bSStefano Zampini PCBDDCSetDivergenceMat - Sets the linear operator representing \int_\Omega \div {\bf u} \cdot p dx 371a198735bSStefano Zampini 372a198735bSStefano Zampini Collective on PC 373a198735bSStefano Zampini 374a198735bSStefano Zampini Input Parameters: 375a198735bSStefano Zampini + pc - the preconditioning context 376a198735bSStefano Zampini . divudotp - the matrix (must be of type MATIS) 3778ae0ca82SStefano Zampini . trans - if trans if false (resp. true), then pressures are in the test (trial) space and velocities are in the trial (test) space. 37805a3bf82SStefano Zampini - vl2l - optional index set describing the local (wrt the local matrix in divudotp) to local (wrt the local matrix in the preconditioning matrix) map for the velocities 379a198735bSStefano Zampini 380a198735bSStefano Zampini Level: advanced 381a198735bSStefano Zampini 38295452b02SPatrick Sanan Notes: 38395452b02SPatrick Sanan This auxiliary matrix is used to compute quadrature weights representing the net-flux across subdomain boundaries 38405a3bf82SStefano Zampini If vl2l is NULL, the local ordering for velocities in divudotp should match that of the preconditioning matrix 385a198735bSStefano Zampini 386a198735bSStefano Zampini .seealso: PCBDDC 387a198735bSStefano Zampini @*/ 3888ae0ca82SStefano Zampini PetscErrorCode PCBDDCSetDivergenceMat(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 389a198735bSStefano Zampini { 390a198735bSStefano Zampini PetscBool ismatis; 391a198735bSStefano Zampini PetscErrorCode ierr; 392a198735bSStefano Zampini 393a198735bSStefano Zampini PetscFunctionBegin; 394a198735bSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 395a198735bSStefano Zampini PetscValidHeaderSpecific(divudotp,MAT_CLASSID,2); 396a198735bSStefano Zampini PetscCheckSameComm(pc,1,divudotp,2); 3978ae0ca82SStefano Zampini PetscValidLogicalCollectiveBool(pc,trans,3); 3981b24a7afSStefano Zampini if (vl2l) PetscValidHeaderSpecific(vl2l,IS_CLASSID,4); 399a198735bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)divudotp,MATIS,&ismatis);CHKERRQ(ierr); 4002c71b3e2SJacob Faibussowitsch PetscCheckFalse(!ismatis,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Divergence matrix needs to be of type MATIS"); 4018ae0ca82SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDivergenceMat_C",(PC,Mat,PetscBool,IS),(pc,divudotp,trans,vl2l));CHKERRQ(ierr); 402a198735bSStefano Zampini PetscFunctionReturn(0); 403a198735bSStefano Zampini } 4042d505d7fSStefano Zampini 4051dd7afcfSStefano Zampini static PetscErrorCode PCBDDCSetChangeOfBasisMat_BDDC(PC pc, Mat change, PetscBool interior) 406b9b85e73SStefano Zampini { 407b9b85e73SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 408b9b85e73SStefano Zampini PetscErrorCode ierr; 409b9b85e73SStefano Zampini 410b9b85e73SStefano Zampini PetscFunctionBegin; 411b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)change);CHKERRQ(ierr); 41256282151SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 413b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = change; 4141dd7afcfSStefano Zampini pcbddc->change_interior = interior; 415b9b85e73SStefano Zampini PetscFunctionReturn(0); 416b9b85e73SStefano Zampini } 417b9b85e73SStefano Zampini /*@ 418906d46d4SStefano Zampini PCBDDCSetChangeOfBasisMat - Set user defined change of basis for dofs 419b9b85e73SStefano Zampini 420b9b85e73SStefano Zampini Collective on PC 421b9b85e73SStefano Zampini 422b9b85e73SStefano Zampini Input Parameters: 423b9b85e73SStefano Zampini + pc - the preconditioning context 4241dd7afcfSStefano Zampini . change - the change of basis matrix 4251dd7afcfSStefano Zampini - interior - whether or not the change of basis modifies interior dofs 426b9b85e73SStefano Zampini 427b9b85e73SStefano Zampini Level: intermediate 428b9b85e73SStefano Zampini 429b9b85e73SStefano Zampini Notes: 430b9b85e73SStefano Zampini 431b9b85e73SStefano Zampini .seealso: PCBDDC 432b9b85e73SStefano Zampini @*/ 4331dd7afcfSStefano Zampini PetscErrorCode PCBDDCSetChangeOfBasisMat(PC pc, Mat change, PetscBool interior) 434b9b85e73SStefano Zampini { 435b9b85e73SStefano Zampini PetscErrorCode ierr; 436b9b85e73SStefano Zampini 437b9b85e73SStefano Zampini PetscFunctionBegin; 438b9b85e73SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 439b9b85e73SStefano Zampini PetscValidHeaderSpecific(change,MAT_CLASSID,2); 440906d46d4SStefano Zampini PetscCheckSameComm(pc,1,change,2); 441906d46d4SStefano Zampini if (pc->mat) { 442906d46d4SStefano Zampini PetscInt rows_c,cols_c,rows,cols; 443906d46d4SStefano Zampini ierr = MatGetSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 444906d46d4SStefano Zampini ierr = MatGetSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 4452c71b3e2SJacob Faibussowitsch PetscCheckFalse(rows_c != rows,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of rows for change of basis matrix! %D != %D",rows_c,rows); 4462c71b3e2SJacob Faibussowitsch PetscCheckFalse(cols_c != cols,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of columns for change of basis matrix! %D != %D",cols_c,cols); 447906d46d4SStefano Zampini ierr = MatGetLocalSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 448906d46d4SStefano Zampini ierr = MatGetLocalSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 4492c71b3e2SJacob Faibussowitsch PetscCheckFalse(rows_c != rows,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of local rows for change of basis matrix! %D != %D",rows_c,rows); 4502c71b3e2SJacob Faibussowitsch PetscCheckFalse(cols_c != cols,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of local columns for change of basis matrix! %D != %D",cols_c,cols); 451906d46d4SStefano Zampini } 4521dd7afcfSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetChangeOfBasisMat_C",(PC,Mat,PetscBool),(pc,change,interior));CHKERRQ(ierr); 453b9b85e73SStefano Zampini PetscFunctionReturn(0); 454b9b85e73SStefano Zampini } 4552d505d7fSStefano Zampini 45630368db7SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesIS_BDDC(PC pc, IS PrimalVertices) 45730368db7SStefano Zampini { 45830368db7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 45956282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 46030368db7SStefano Zampini PetscErrorCode ierr; 46130368db7SStefano Zampini 46230368db7SStefano Zampini PetscFunctionBegin; 46356282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 46456282151SStefano Zampini if (pcbddc->user_primal_vertices) { 46556282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices,&isequal);CHKERRQ(ierr); 46656282151SStefano Zampini } 46730368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 46830368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 46930368db7SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 47056282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 47130368db7SStefano Zampini PetscFunctionReturn(0); 47230368db7SStefano Zampini } 473ab8c8b98SStefano Zampini 47430368db7SStefano Zampini /*@ 47530368db7SStefano Zampini PCBDDCSetPrimalVerticesIS - Set additional user defined primal vertices in PCBDDC 47630368db7SStefano Zampini 47730368db7SStefano Zampini Collective 47830368db7SStefano Zampini 47930368db7SStefano Zampini Input Parameters: 48030368db7SStefano Zampini + pc - the preconditioning context 48130368db7SStefano Zampini - PrimalVertices - index set of primal vertices in global numbering (can be empty) 48230368db7SStefano Zampini 48330368db7SStefano Zampini Level: intermediate 48430368db7SStefano Zampini 48530368db7SStefano Zampini Notes: 48630368db7SStefano Zampini Any process can list any global node 48730368db7SStefano Zampini 4883100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCGetPrimalVerticesIS(), PCBDDCSetPrimalVerticesLocalIS(), PCBDDCGetPrimalVerticesLocalIS() 48930368db7SStefano Zampini @*/ 49030368db7SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesIS(PC pc, IS PrimalVertices) 49130368db7SStefano Zampini { 49230368db7SStefano Zampini PetscErrorCode ierr; 49330368db7SStefano Zampini 49430368db7SStefano Zampini PetscFunctionBegin; 49530368db7SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 49630368db7SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 49730368db7SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 49830368db7SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 49930368db7SStefano Zampini PetscFunctionReturn(0); 50030368db7SStefano Zampini } 5012d505d7fSStefano Zampini 5023100ebe3SStefano Zampini static PetscErrorCode PCBDDCGetPrimalVerticesIS_BDDC(PC pc, IS *is) 5033100ebe3SStefano Zampini { 5043100ebe3SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5053100ebe3SStefano Zampini 5063100ebe3SStefano Zampini PetscFunctionBegin; 5073100ebe3SStefano Zampini *is = pcbddc->user_primal_vertices; 5083100ebe3SStefano Zampini PetscFunctionReturn(0); 5093100ebe3SStefano Zampini } 5103100ebe3SStefano Zampini 5113100ebe3SStefano Zampini /*@ 5123100ebe3SStefano Zampini PCBDDCGetPrimalVerticesIS - Get user defined primal vertices set with PCBDDCSetPrimalVerticesIS() 5133100ebe3SStefano Zampini 5143100ebe3SStefano Zampini Collective 5153100ebe3SStefano Zampini 5163100ebe3SStefano Zampini Input Parameters: 5173100ebe3SStefano Zampini . pc - the preconditioning context 5183100ebe3SStefano Zampini 5193100ebe3SStefano Zampini Output Parameters: 5203100ebe3SStefano Zampini . is - index set of primal vertices in global numbering (NULL if not set) 5213100ebe3SStefano Zampini 5223100ebe3SStefano Zampini Level: intermediate 5233100ebe3SStefano Zampini 5243100ebe3SStefano Zampini Notes: 5253100ebe3SStefano Zampini 5263100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCSetPrimalVerticesIS(), PCBDDCSetPrimalVerticesLocalIS(), PCBDDCGetPrimalVerticesLocalIS() 5273100ebe3SStefano Zampini @*/ 5283100ebe3SStefano Zampini PetscErrorCode PCBDDCGetPrimalVerticesIS(PC pc, IS *is) 5293100ebe3SStefano Zampini { 5303100ebe3SStefano Zampini PetscErrorCode ierr; 5313100ebe3SStefano Zampini 5323100ebe3SStefano Zampini PetscFunctionBegin; 5333100ebe3SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5343100ebe3SStefano Zampini PetscValidPointer(is,2); 5353100ebe3SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetPrimalVerticesIS_C",(PC,IS*),(pc,is));CHKERRQ(ierr); 5363100ebe3SStefano Zampini PetscFunctionReturn(0); 5373100ebe3SStefano Zampini } 5383100ebe3SStefano Zampini 539674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 540674ae819SStefano Zampini { 541674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 54256282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 543674ae819SStefano Zampini PetscErrorCode ierr; 5441e6b0712SBarry Smith 545674ae819SStefano Zampini PetscFunctionBegin; 54656282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 54756282151SStefano Zampini if (pcbddc->user_primal_vertices_local) { 54856282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices_local,&isequal);CHKERRQ(ierr); 54956282151SStefano Zampini } 550674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 55130368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 55230368db7SStefano Zampini pcbddc->user_primal_vertices_local = PrimalVertices; 55356282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 554674ae819SStefano Zampini PetscFunctionReturn(0); 555674ae819SStefano Zampini } 5563100ebe3SStefano Zampini 557674ae819SStefano Zampini /*@ 55828509bceSStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC 559674ae819SStefano Zampini 56017eb1463SStefano Zampini Collective 561674ae819SStefano Zampini 562674ae819SStefano Zampini Input Parameters: 563674ae819SStefano Zampini + pc - the preconditioning context 56417eb1463SStefano Zampini - PrimalVertices - index set of primal vertices in local numbering (can be empty) 565674ae819SStefano Zampini 566674ae819SStefano Zampini Level: intermediate 567674ae819SStefano Zampini 568674ae819SStefano Zampini Notes: 569674ae819SStefano Zampini 5703100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCSetPrimalVerticesIS(), PCBDDCGetPrimalVerticesIS(), PCBDDCGetPrimalVerticesLocalIS() 571674ae819SStefano Zampini @*/ 572674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 573674ae819SStefano Zampini { 574674ae819SStefano Zampini PetscErrorCode ierr; 575674ae819SStefano Zampini 576674ae819SStefano Zampini PetscFunctionBegin; 577674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 578674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 57917eb1463SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 580674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 581674ae819SStefano Zampini PetscFunctionReturn(0); 582674ae819SStefano Zampini } 5832d505d7fSStefano Zampini 5843100ebe3SStefano Zampini static PetscErrorCode PCBDDCGetPrimalVerticesLocalIS_BDDC(PC pc, IS *is) 5853100ebe3SStefano Zampini { 5863100ebe3SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5873100ebe3SStefano Zampini 5883100ebe3SStefano Zampini PetscFunctionBegin; 5893100ebe3SStefano Zampini *is = pcbddc->user_primal_vertices_local; 5903100ebe3SStefano Zampini PetscFunctionReturn(0); 5913100ebe3SStefano Zampini } 5923100ebe3SStefano Zampini 5933100ebe3SStefano Zampini /*@ 5943100ebe3SStefano Zampini PCBDDCGetPrimalVerticesLocalIS - Get user defined primal vertices set with PCBDDCSetPrimalVerticesLocalIS() 5953100ebe3SStefano Zampini 5963100ebe3SStefano Zampini Collective 5973100ebe3SStefano Zampini 5983100ebe3SStefano Zampini Input Parameters: 5993100ebe3SStefano Zampini . pc - the preconditioning context 6003100ebe3SStefano Zampini 6013100ebe3SStefano Zampini Output Parameters: 6023100ebe3SStefano Zampini . is - index set of primal vertices in local numbering (NULL if not set) 6033100ebe3SStefano Zampini 6043100ebe3SStefano Zampini Level: intermediate 6053100ebe3SStefano Zampini 6063100ebe3SStefano Zampini Notes: 6073100ebe3SStefano Zampini 6083100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCSetPrimalVerticesIS(), PCBDDCGetPrimalVerticesIS(), PCBDDCSetPrimalVerticesLocalIS() 6093100ebe3SStefano Zampini @*/ 6103100ebe3SStefano Zampini PetscErrorCode PCBDDCGetPrimalVerticesLocalIS(PC pc, IS *is) 6113100ebe3SStefano Zampini { 6123100ebe3SStefano Zampini PetscErrorCode ierr; 6133100ebe3SStefano Zampini 6143100ebe3SStefano Zampini PetscFunctionBegin; 6153100ebe3SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6163100ebe3SStefano Zampini PetscValidPointer(is,2); 6173100ebe3SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetPrimalVerticesLocalIS_C",(PC,IS*),(pc,is));CHKERRQ(ierr); 6183100ebe3SStefano Zampini PetscFunctionReturn(0); 6193100ebe3SStefano Zampini } 6203100ebe3SStefano Zampini 6214fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 6224fad6a16SStefano Zampini { 6234fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6244fad6a16SStefano Zampini 6254fad6a16SStefano Zampini PetscFunctionBegin; 6264fad6a16SStefano Zampini pcbddc->coarsening_ratio = k; 6274fad6a16SStefano Zampini PetscFunctionReturn(0); 6284fad6a16SStefano Zampini } 6291e6b0712SBarry Smith 6304fad6a16SStefano Zampini /*@ 63128509bceSStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel 6324fad6a16SStefano Zampini 6334fad6a16SStefano Zampini Logically collective on PC 6344fad6a16SStefano Zampini 6354fad6a16SStefano Zampini Input Parameters: 6364fad6a16SStefano Zampini + pc - the preconditioning context 63728509bceSStefano Zampini - k - coarsening ratio (H/h at the coarser level) 6384fad6a16SStefano Zampini 6390f202f7eSStefano Zampini Options Database Keys: 6400f202f7eSStefano Zampini . -pc_bddc_coarsening_ratio 6414fad6a16SStefano Zampini 6424fad6a16SStefano Zampini Level: intermediate 6434fad6a16SStefano Zampini 6444fad6a16SStefano Zampini Notes: 6450f202f7eSStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level 6464fad6a16SStefano Zampini 6470f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetLevels() 6484fad6a16SStefano Zampini @*/ 6494fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 6504fad6a16SStefano Zampini { 6514fad6a16SStefano Zampini PetscErrorCode ierr; 6524fad6a16SStefano Zampini 6534fad6a16SStefano Zampini PetscFunctionBegin; 6544fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6552b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,k,2); 6564fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 6574fad6a16SStefano Zampini PetscFunctionReturn(0); 6584fad6a16SStefano Zampini } 6592b510759SStefano Zampini 660b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */ 661b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg) 662b8ffe317SStefano Zampini { 663b8ffe317SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 664b8ffe317SStefano Zampini 665b8ffe317SStefano Zampini PetscFunctionBegin; 66685c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = flg; 667b8ffe317SStefano Zampini PetscFunctionReturn(0); 668b8ffe317SStefano Zampini } 669b8ffe317SStefano Zampini 670b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg) 6712b510759SStefano Zampini { 6722b510759SStefano Zampini PetscErrorCode ierr; 6732b510759SStefano Zampini 6742b510759SStefano Zampini PetscFunctionBegin; 6752b510759SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 676b8ffe317SStefano Zampini PetscValidLogicalCollectiveBool(pc,flg,2); 677b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr); 6782b510759SStefano Zampini PetscFunctionReturn(0); 6792b510759SStefano Zampini } 6801e6b0712SBarry Smith 6812b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level) 6824fad6a16SStefano Zampini { 6834fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6844fad6a16SStefano Zampini 6854fad6a16SStefano Zampini PetscFunctionBegin; 6862b510759SStefano Zampini pcbddc->current_level = level; 6874fad6a16SStefano Zampini PetscFunctionReturn(0); 6884fad6a16SStefano Zampini } 6891e6b0712SBarry Smith 690b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 691b8ffe317SStefano Zampini { 692b8ffe317SStefano Zampini PetscErrorCode ierr; 693b8ffe317SStefano Zampini 694b8ffe317SStefano Zampini PetscFunctionBegin; 695b8ffe317SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 696b8ffe317SStefano Zampini PetscValidLogicalCollectiveInt(pc,level,2); 697b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr); 698b8ffe317SStefano Zampini PetscFunctionReturn(0); 699b8ffe317SStefano Zampini } 700b8ffe317SStefano Zampini 7012b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels) 7022b510759SStefano Zampini { 7032b510759SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 7042b510759SStefano Zampini 7052b510759SStefano Zampini PetscFunctionBegin; 7062c71b3e2SJacob Faibussowitsch PetscCheckFalse(levels > PETSC_PCBDDC_MAXLEVELS-1,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Maximum number of additional levels for BDDC is %d",PETSC_PCBDDC_MAXLEVELS-1); 7072b510759SStefano Zampini pcbddc->max_levels = levels; 7082b510759SStefano Zampini PetscFunctionReturn(0); 7092b510759SStefano Zampini } 7102b510759SStefano Zampini 7114fad6a16SStefano Zampini /*@ 71237ebbdf7SStefano Zampini PCBDDCSetLevels - Sets the maximum number of additional levels allowed for multilevel BDDC 7134fad6a16SStefano Zampini 7144fad6a16SStefano Zampini Logically collective on PC 7154fad6a16SStefano Zampini 7164fad6a16SStefano Zampini Input Parameters: 7174fad6a16SStefano Zampini + pc - the preconditioning context 71837ebbdf7SStefano Zampini - levels - the maximum number of levels 7194fad6a16SStefano Zampini 7200f202f7eSStefano Zampini Options Database Keys: 7210f202f7eSStefano Zampini . -pc_bddc_levels 7224fad6a16SStefano Zampini 7234fad6a16SStefano Zampini Level: intermediate 7244fad6a16SStefano Zampini 7254fad6a16SStefano Zampini Notes: 72637ebbdf7SStefano Zampini The default value is 0, that gives the classical two-levels BDDC 7274fad6a16SStefano Zampini 7280f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetCoarseningRatio() 7294fad6a16SStefano Zampini @*/ 7302b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels) 7314fad6a16SStefano Zampini { 7324fad6a16SStefano Zampini PetscErrorCode ierr; 7334fad6a16SStefano Zampini 7344fad6a16SStefano Zampini PetscFunctionBegin; 7354fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 7362b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,levels,2); 7372b510759SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr); 7384fad6a16SStefano Zampini PetscFunctionReturn(0); 7394fad6a16SStefano Zampini } 7401e6b0712SBarry Smith 7413b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 7423b03a366Sstefano_zampini { 7433b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 74456282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 7453b03a366Sstefano_zampini PetscErrorCode ierr; 7463b03a366Sstefano_zampini 7473b03a366Sstefano_zampini PetscFunctionBegin; 74856282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 74956282151SStefano Zampini if (pcbddc->DirichletBoundaries) { 75056282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundaries,&isequal);CHKERRQ(ierr); 75156282151SStefano Zampini } 752a5b23f4aSJose E. Roman /* last user setting takes precedence -> destroy any other customization */ 753785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 7543b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 75536e030ebSStefano Zampini pcbddc->DirichletBoundaries = DirichletBoundaries; 75656282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7573b03a366Sstefano_zampini PetscFunctionReturn(0); 7583b03a366Sstefano_zampini } 7591e6b0712SBarry Smith 7603b03a366Sstefano_zampini /*@ 76128509bceSStefano Zampini PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem. 7623b03a366Sstefano_zampini 763785d1243SStefano Zampini Collective 7643b03a366Sstefano_zampini 7653b03a366Sstefano_zampini Input Parameters: 7663b03a366Sstefano_zampini + pc - the preconditioning context 767785d1243SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries 7683b03a366Sstefano_zampini 7693b03a366Sstefano_zampini Level: intermediate 7703b03a366Sstefano_zampini 7710f202f7eSStefano Zampini Notes: 7720f202f7eSStefano Zampini Provide the information if you used MatZeroRows/Columns routines. Any process can list any global node 7733b03a366Sstefano_zampini 7740f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundariesLocal(), MatZeroRows(), MatZeroRowsColumns() 7753b03a366Sstefano_zampini @*/ 7763b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 7773b03a366Sstefano_zampini { 7783b03a366Sstefano_zampini PetscErrorCode ierr; 7793b03a366Sstefano_zampini 7803b03a366Sstefano_zampini PetscFunctionBegin; 7813b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 782674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 783785d1243SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 7843b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 7853b03a366Sstefano_zampini PetscFunctionReturn(0); 7863b03a366Sstefano_zampini } 7871e6b0712SBarry Smith 78882ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries) 7893b03a366Sstefano_zampini { 7903b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 79156282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 7923b03a366Sstefano_zampini PetscErrorCode ierr; 7933b03a366Sstefano_zampini 7943b03a366Sstefano_zampini PetscFunctionBegin; 79556282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 79656282151SStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 79756282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundariesLocal,&isequal);CHKERRQ(ierr); 79856282151SStefano Zampini } 799a5b23f4aSJose E. Roman /* last user setting takes precedence -> destroy any other customization */ 800785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 8013b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 802785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = DirichletBoundaries; 80356282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 8043b03a366Sstefano_zampini PetscFunctionReturn(0); 8053b03a366Sstefano_zampini } 8063b03a366Sstefano_zampini 8073b03a366Sstefano_zampini /*@ 80882ba6b80SStefano Zampini PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering. 8093b03a366Sstefano_zampini 810785d1243SStefano Zampini Collective 8113b03a366Sstefano_zampini 8123b03a366Sstefano_zampini Input Parameters: 8133b03a366Sstefano_zampini + pc - the preconditioning context 81482ba6b80SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering) 8153b03a366Sstefano_zampini 8163b03a366Sstefano_zampini Level: intermediate 8173b03a366Sstefano_zampini 8183b03a366Sstefano_zampini Notes: 8193b03a366Sstefano_zampini 8200f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundaries(), MatZeroRows(), MatZeroRowsColumns() 8213b03a366Sstefano_zampini @*/ 82282ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries) 8233b03a366Sstefano_zampini { 8243b03a366Sstefano_zampini PetscErrorCode ierr; 8253b03a366Sstefano_zampini 8263b03a366Sstefano_zampini PetscFunctionBegin; 8273b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 8283b03a366Sstefano_zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 82982ba6b80SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 83082ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 8313b03a366Sstefano_zampini PetscFunctionReturn(0); 8323b03a366Sstefano_zampini } 8333b03a366Sstefano_zampini 83453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 8350c7d97c5SJed Brown { 8360c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 83756282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 83853cdbc3dSStefano Zampini PetscErrorCode ierr; 8390c7d97c5SJed Brown 8400c7d97c5SJed Brown PetscFunctionBegin; 84156282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 84256282151SStefano Zampini if (pcbddc->NeumannBoundaries) { 84356282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundaries,&isequal);CHKERRQ(ierr); 84456282151SStefano Zampini } 845a5b23f4aSJose E. Roman /* last user setting takes precedence -> destroy any other customization */ 846785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 84753cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 84836e030ebSStefano Zampini pcbddc->NeumannBoundaries = NeumannBoundaries; 84956282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 8500c7d97c5SJed Brown PetscFunctionReturn(0); 8510c7d97c5SJed Brown } 8521e6b0712SBarry Smith 85357527edcSJed Brown /*@ 85428509bceSStefano Zampini PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem. 85557527edcSJed Brown 856785d1243SStefano Zampini Collective 85757527edcSJed Brown 85857527edcSJed Brown Input Parameters: 85957527edcSJed Brown + pc - the preconditioning context 860785d1243SStefano Zampini - NeumannBoundaries - parallel IS defining the Neumann boundaries 86157527edcSJed Brown 86257527edcSJed Brown Level: intermediate 86357527edcSJed Brown 8640f202f7eSStefano Zampini Notes: 8650f202f7eSStefano Zampini Any process can list any global node 86657527edcSJed Brown 8670f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundariesLocal() 86857527edcSJed Brown @*/ 86953cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 8700c7d97c5SJed Brown { 8710c7d97c5SJed Brown PetscErrorCode ierr; 8720c7d97c5SJed Brown 8730c7d97c5SJed Brown PetscFunctionBegin; 8740c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 875674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 876785d1243SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 87753cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 87853cdbc3dSStefano Zampini PetscFunctionReturn(0); 87953cdbc3dSStefano Zampini } 8801e6b0712SBarry Smith 88182ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries) 8820c7d97c5SJed Brown { 8830c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 88456282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 8850c7d97c5SJed Brown PetscErrorCode ierr; 8860c7d97c5SJed Brown 8870c7d97c5SJed Brown PetscFunctionBegin; 88856282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 88956282151SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 89056282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundariesLocal,&isequal);CHKERRQ(ierr); 89156282151SStefano Zampini } 892a5b23f4aSJose E. Roman /* last user setting takes precedence -> destroy any other customization */ 893785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 8940c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 895785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = NeumannBoundaries; 89656282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 8970c7d97c5SJed Brown PetscFunctionReturn(0); 8980c7d97c5SJed Brown } 8990c7d97c5SJed Brown 9000c7d97c5SJed Brown /*@ 90182ba6b80SStefano Zampini PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering. 9020c7d97c5SJed Brown 903785d1243SStefano Zampini Collective 9040c7d97c5SJed Brown 9050c7d97c5SJed Brown Input Parameters: 9060c7d97c5SJed Brown + pc - the preconditioning context 90782ba6b80SStefano Zampini - NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering) 9080c7d97c5SJed Brown 9090c7d97c5SJed Brown Level: intermediate 9100c7d97c5SJed Brown 9110c7d97c5SJed Brown Notes: 9120c7d97c5SJed Brown 9130f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundaries() 9140c7d97c5SJed Brown @*/ 91582ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries) 9160c7d97c5SJed Brown { 9170c7d97c5SJed Brown PetscErrorCode ierr; 9180c7d97c5SJed Brown 9190c7d97c5SJed Brown PetscFunctionBegin; 9200c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 9210c7d97c5SJed Brown PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 92282ba6b80SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 92382ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 92453cdbc3dSStefano Zampini PetscFunctionReturn(0); 92553cdbc3dSStefano Zampini } 92653cdbc3dSStefano Zampini 927da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 928da1bb401SStefano Zampini { 929da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 930da1bb401SStefano Zampini 931da1bb401SStefano Zampini PetscFunctionBegin; 932da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 933da1bb401SStefano Zampini PetscFunctionReturn(0); 934da1bb401SStefano Zampini } 9351e6b0712SBarry Smith 936da1bb401SStefano Zampini /*@ 937785d1243SStefano Zampini PCBDDCGetDirichletBoundaries - Get parallel IS for Dirichlet boundaries 938da1bb401SStefano Zampini 939785d1243SStefano Zampini Collective 940785d1243SStefano Zampini 941785d1243SStefano Zampini Input Parameters: 942785d1243SStefano Zampini . pc - the preconditioning context 943785d1243SStefano Zampini 944785d1243SStefano Zampini Output Parameters: 945785d1243SStefano Zampini . DirichletBoundaries - index set defining the Dirichlet boundaries 946785d1243SStefano Zampini 947785d1243SStefano Zampini Level: intermediate 948785d1243SStefano Zampini 9490f202f7eSStefano Zampini Notes: 9500f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetDirichletBoundaries 951785d1243SStefano Zampini 952785d1243SStefano Zampini .seealso: PCBDDC 953785d1243SStefano Zampini @*/ 954785d1243SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 955785d1243SStefano Zampini { 956785d1243SStefano Zampini PetscErrorCode ierr; 957785d1243SStefano Zampini 958785d1243SStefano Zampini PetscFunctionBegin; 959785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 960785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 961785d1243SStefano Zampini PetscFunctionReturn(0); 962785d1243SStefano Zampini } 963785d1243SStefano Zampini 964785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries) 965785d1243SStefano Zampini { 966785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 967785d1243SStefano Zampini 968785d1243SStefano Zampini PetscFunctionBegin; 969785d1243SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundariesLocal; 970785d1243SStefano Zampini PetscFunctionReturn(0); 971785d1243SStefano Zampini } 972785d1243SStefano Zampini 973da1bb401SStefano Zampini /*@ 97482ba6b80SStefano Zampini PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering) 975da1bb401SStefano Zampini 976785d1243SStefano Zampini Collective 977da1bb401SStefano Zampini 978da1bb401SStefano Zampini Input Parameters: 97928509bceSStefano Zampini . pc - the preconditioning context 980da1bb401SStefano Zampini 981da1bb401SStefano Zampini Output Parameters: 98228509bceSStefano Zampini . DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 983da1bb401SStefano Zampini 984da1bb401SStefano Zampini Level: intermediate 985da1bb401SStefano Zampini 986da1bb401SStefano Zampini Notes: 9870f202f7eSStefano 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). 9880f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 989da1bb401SStefano Zampini 990da1bb401SStefano Zampini .seealso: PCBDDC 991da1bb401SStefano Zampini @*/ 99282ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries) 993da1bb401SStefano Zampini { 994da1bb401SStefano Zampini PetscErrorCode ierr; 995da1bb401SStefano Zampini 996da1bb401SStefano Zampini PetscFunctionBegin; 997da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 99882ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 999da1bb401SStefano Zampini PetscFunctionReturn(0); 1000da1bb401SStefano Zampini } 10011e6b0712SBarry Smith 100253cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 100353cdbc3dSStefano Zampini { 100453cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 100553cdbc3dSStefano Zampini 100653cdbc3dSStefano Zampini PetscFunctionBegin; 100753cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 100853cdbc3dSStefano Zampini PetscFunctionReturn(0); 100953cdbc3dSStefano Zampini } 10101e6b0712SBarry Smith 101153cdbc3dSStefano Zampini /*@ 1012785d1243SStefano Zampini PCBDDCGetNeumannBoundaries - Get parallel IS for Neumann boundaries 101353cdbc3dSStefano Zampini 1014785d1243SStefano Zampini Collective 1015785d1243SStefano Zampini 1016785d1243SStefano Zampini Input Parameters: 1017785d1243SStefano Zampini . pc - the preconditioning context 1018785d1243SStefano Zampini 1019785d1243SStefano Zampini Output Parameters: 1020785d1243SStefano Zampini . NeumannBoundaries - index set defining the Neumann boundaries 1021785d1243SStefano Zampini 1022785d1243SStefano Zampini Level: intermediate 1023785d1243SStefano Zampini 10240f202f7eSStefano Zampini Notes: 10250f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetNeumannBoundaries 1026785d1243SStefano Zampini 1027785d1243SStefano Zampini .seealso: PCBDDC 1028785d1243SStefano Zampini @*/ 1029785d1243SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 1030785d1243SStefano Zampini { 1031785d1243SStefano Zampini PetscErrorCode ierr; 1032785d1243SStefano Zampini 1033785d1243SStefano Zampini PetscFunctionBegin; 1034785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1035785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 1036785d1243SStefano Zampini PetscFunctionReturn(0); 1037785d1243SStefano Zampini } 1038785d1243SStefano Zampini 1039785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries) 1040785d1243SStefano Zampini { 1041785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1042785d1243SStefano Zampini 1043785d1243SStefano Zampini PetscFunctionBegin; 1044785d1243SStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundariesLocal; 1045785d1243SStefano Zampini PetscFunctionReturn(0); 1046785d1243SStefano Zampini } 1047785d1243SStefano Zampini 104853cdbc3dSStefano Zampini /*@ 104982ba6b80SStefano Zampini PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering) 105053cdbc3dSStefano Zampini 1051785d1243SStefano Zampini Collective 105253cdbc3dSStefano Zampini 105353cdbc3dSStefano Zampini Input Parameters: 105428509bceSStefano Zampini . pc - the preconditioning context 105553cdbc3dSStefano Zampini 105653cdbc3dSStefano Zampini Output Parameters: 105728509bceSStefano Zampini . NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 105853cdbc3dSStefano Zampini 105953cdbc3dSStefano Zampini Level: intermediate 106053cdbc3dSStefano Zampini 106153cdbc3dSStefano Zampini Notes: 10620f202f7eSStefano 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). 10630f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 106453cdbc3dSStefano Zampini 106553cdbc3dSStefano Zampini .seealso: PCBDDC 106653cdbc3dSStefano Zampini @*/ 106782ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries) 106853cdbc3dSStefano Zampini { 106953cdbc3dSStefano Zampini PetscErrorCode ierr; 107053cdbc3dSStefano Zampini 107153cdbc3dSStefano Zampini PetscFunctionBegin; 107253cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 107382ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 10740c7d97c5SJed Brown PetscFunctionReturn(0); 10750c7d97c5SJed Brown } 10761e6b0712SBarry Smith 10771a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 107836e030ebSStefano Zampini { 107936e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1080da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 108156282151SStefano Zampini PetscBool same_data = PETSC_FALSE; 1082da1bb401SStefano Zampini PetscErrorCode ierr; 108336e030ebSStefano Zampini 108436e030ebSStefano Zampini PetscFunctionBegin; 10858687889aSStefano Zampini if (!nvtxs) { 108604194a47SStefano Zampini if (copymode == PETSC_OWN_POINTER) { 108704194a47SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 108804194a47SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 108904194a47SStefano Zampini } 10908687889aSStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 10918687889aSStefano Zampini PetscFunctionReturn(0); 10928687889aSStefano Zampini } 109366da6bd7Sstefano_zampini if (mat_graph->nvtxs == nvtxs && mat_graph->freecsr) { /* we own the data */ 109456282151SStefano Zampini if (mat_graph->xadj == xadj && mat_graph->adjncy == adjncy) same_data = PETSC_TRUE; 109556282151SStefano Zampini if (!same_data && mat_graph->xadj[nvtxs] == xadj[nvtxs]) { 1096580bdb30SBarry Smith ierr = PetscArraycmp(xadj,mat_graph->xadj,nvtxs+1,&same_data);CHKERRQ(ierr); 10972d505d7fSStefano Zampini if (same_data) { 1098580bdb30SBarry Smith ierr = PetscArraycmp(adjncy,mat_graph->adjncy,xadj[nvtxs],&same_data);CHKERRQ(ierr); 10992d505d7fSStefano Zampini } 110056282151SStefano Zampini } 110156282151SStefano Zampini } 110256282151SStefano Zampini if (!same_data) { 1103674ae819SStefano Zampini /* free old CSR */ 1104674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 1105674ae819SStefano Zampini /* get CSR into graph structure */ 1106da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 1107854ce69bSBarry Smith ierr = PetscMalloc1(nvtxs+1,&mat_graph->xadj);CHKERRQ(ierr); 1108785e854fSJed Brown ierr = PetscMalloc1(xadj[nvtxs],&mat_graph->adjncy);CHKERRQ(ierr); 1109580bdb30SBarry Smith ierr = PetscArraycpy(mat_graph->xadj,xadj,nvtxs+1);CHKERRQ(ierr); 1110580bdb30SBarry Smith ierr = PetscArraycpy(mat_graph->adjncy,adjncy,xadj[nvtxs]);CHKERRQ(ierr); 1111a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 1112da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 11131a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 11141a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 1115a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 1116a1dbd327SStefano Zampini } else if (copymode == PETSC_USE_POINTER) { 1117a1dbd327SStefano Zampini mat_graph->xadj = (PetscInt*)xadj; 1118a1dbd327SStefano Zampini mat_graph->adjncy = (PetscInt*)adjncy; 1119a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_FALSE; 112098921bdaSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %D",copymode); 1121575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 112256282151SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 112356282151SStefano Zampini } 112436e030ebSStefano Zampini PetscFunctionReturn(0); 112536e030ebSStefano Zampini } 11261e6b0712SBarry Smith 112736e030ebSStefano Zampini /*@ 112854fffbccSStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local degrees of freedom. 112936e030ebSStefano Zampini 113036e030ebSStefano Zampini Not collective 113136e030ebSStefano Zampini 113236e030ebSStefano Zampini Input Parameters: 113354fffbccSStefano Zampini + pc - the preconditioning context. 113454fffbccSStefano Zampini . nvtxs - number of local vertices of the graph (i.e., the number of local dofs). 113554fffbccSStefano Zampini . xadj, adjncy - the connectivity of the dofs in CSR format. 113654fffbccSStefano Zampini - copymode - supported modes are PETSC_COPY_VALUES, PETSC_USE_POINTER or PETSC_OWN_POINTER. 113736e030ebSStefano Zampini 113836e030ebSStefano Zampini Level: intermediate 113936e030ebSStefano Zampini 114095452b02SPatrick Sanan Notes: 114195452b02SPatrick Sanan A dof is considered connected with all local dofs if xadj[dof+1]-xadj[dof] == 1 and adjncy[xadj[dof]] is negative. 114236e030ebSStefano Zampini 114328509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode 114436e030ebSStefano Zampini @*/ 11451a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 114636e030ebSStefano Zampini { 11470a545947SLisandro Dalcin void (*f)(void) = NULL; 114836e030ebSStefano Zampini PetscErrorCode ierr; 114936e030ebSStefano Zampini 115036e030ebSStefano Zampini PetscFunctionBegin; 115136e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 11528687889aSStefano Zampini if (nvtxs) { 1153674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 11541633d1f0SStefano Zampini if (xadj[nvtxs]) PetscValidIntPointer(adjncy,4); 11558687889aSStefano Zampini } 11561a83f524SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 1157575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 1158575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 1159575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 1160575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 1161575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 1162da1bb401SStefano Zampini } 116336e030ebSStefano Zampini PetscFunctionReturn(0); 116436e030ebSStefano Zampini } 11651e6b0712SBarry Smith 116663602bcaSStefano Zampini static PetscErrorCode PCBDDCSetDofsSplittingLocal_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 116763602bcaSStefano Zampini { 116863602bcaSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 116963602bcaSStefano Zampini PetscInt i; 117056282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 117163602bcaSStefano Zampini PetscErrorCode ierr; 117263602bcaSStefano Zampini 117363602bcaSStefano Zampini PetscFunctionBegin; 117456282151SStefano Zampini if (pcbddc->n_ISForDofsLocal == n_is) { 117556282151SStefano Zampini for (i=0;i<n_is;i++) { 117656282151SStefano Zampini PetscBool isequalt; 117756282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofsLocal[i],&isequalt);CHKERRQ(ierr); 117856282151SStefano Zampini if (!isequalt) break; 117956282151SStefano Zampini } 118056282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 118156282151SStefano Zampini } 118256282151SStefano Zampini for (i=0;i<n_is;i++) { 118356282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 118456282151SStefano Zampini } 118563602bcaSStefano Zampini /* Destroy ISes if they were already set */ 118663602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 118763602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 118863602bcaSStefano Zampini } 118963602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1190a5b23f4aSJose E. Roman /* last user setting takes precedence -> destroy any other customization */ 119163602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 119263602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 119363602bcaSStefano Zampini } 119463602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 119563602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 119663602bcaSStefano Zampini /* allocate space then set */ 1197d02579f5SStefano Zampini if (n_is) { 1198d02579f5SStefano Zampini ierr = PetscMalloc1(n_is,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1199d02579f5SStefano Zampini } 120063602bcaSStefano Zampini for (i=0;i<n_is;i++) { 120163602bcaSStefano Zampini pcbddc->ISForDofsLocal[i] = ISForDofs[i]; 120263602bcaSStefano Zampini } 120363602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = n_is; 120463602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 120556282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 120663602bcaSStefano Zampini PetscFunctionReturn(0); 120763602bcaSStefano Zampini } 120863602bcaSStefano Zampini 120963602bcaSStefano Zampini /*@ 121063602bcaSStefano Zampini PCBDDCSetDofsSplittingLocal - Set index sets defining fields of the local subdomain matrix 121163602bcaSStefano Zampini 121263602bcaSStefano Zampini Collective 121363602bcaSStefano Zampini 121463602bcaSStefano Zampini Input Parameters: 121563602bcaSStefano Zampini + pc - the preconditioning context 12160f202f7eSStefano Zampini . n_is - number of index sets defining the fields 12170f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in local ordering 121863602bcaSStefano Zampini 121963602bcaSStefano Zampini Level: intermediate 122063602bcaSStefano Zampini 12210f202f7eSStefano Zampini Notes: 12220f202f7eSStefano Zampini n_is should be the same among processes. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 122363602bcaSStefano Zampini 122463602bcaSStefano Zampini .seealso: PCBDDC 122563602bcaSStefano Zampini @*/ 122663602bcaSStefano Zampini PetscErrorCode PCBDDCSetDofsSplittingLocal(PC pc,PetscInt n_is, IS ISForDofs[]) 122763602bcaSStefano Zampini { 122863602bcaSStefano Zampini PetscInt i; 122963602bcaSStefano Zampini PetscErrorCode ierr; 123063602bcaSStefano Zampini 123163602bcaSStefano Zampini PetscFunctionBegin; 123263602bcaSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 123363602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 123463602bcaSStefano Zampini for (i=0;i<n_is;i++) { 123563602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 123663602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 123763602bcaSStefano Zampini } 1238e71e7a71SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplittingLocal_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 123963602bcaSStefano Zampini PetscFunctionReturn(0); 124063602bcaSStefano Zampini } 124163602bcaSStefano Zampini 12429c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 12439c0446d6SStefano Zampini { 12449c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 12459c0446d6SStefano Zampini PetscInt i; 124656282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 12479c0446d6SStefano Zampini PetscErrorCode ierr; 12489c0446d6SStefano Zampini 12499c0446d6SStefano Zampini PetscFunctionBegin; 125056282151SStefano Zampini if (pcbddc->n_ISForDofs == n_is) { 125156282151SStefano Zampini for (i=0;i<n_is;i++) { 125256282151SStefano Zampini PetscBool isequalt; 125356282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofs[i],&isequalt);CHKERRQ(ierr); 125456282151SStefano Zampini if (!isequalt) break; 125556282151SStefano Zampini } 125656282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 125756282151SStefano Zampini } 125856282151SStefano Zampini for (i=0;i<n_is;i++) { 125956282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 126056282151SStefano Zampini } 1261da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 12629c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 12639c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 12649c0446d6SStefano Zampini } 1265d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 1266a5b23f4aSJose E. Roman /* last user setting takes precedence -> destroy any other customization */ 126763602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 126863602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 126963602bcaSStefano Zampini } 127063602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 127163602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 1272da1bb401SStefano Zampini /* allocate space then set */ 1273d02579f5SStefano Zampini if (n_is) { 1274785e854fSJed Brown ierr = PetscMalloc1(n_is,&pcbddc->ISForDofs);CHKERRQ(ierr); 1275d02579f5SStefano Zampini } 12769c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 1277da1bb401SStefano Zampini pcbddc->ISForDofs[i] = ISForDofs[i]; 12789c0446d6SStefano Zampini } 12799c0446d6SStefano Zampini pcbddc->n_ISForDofs = n_is; 128063602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 128156282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 12829c0446d6SStefano Zampini PetscFunctionReturn(0); 12839c0446d6SStefano Zampini } 12841e6b0712SBarry Smith 12859c0446d6SStefano Zampini /*@ 128663602bcaSStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of the global matrix 12879c0446d6SStefano Zampini 128863602bcaSStefano Zampini Collective 12899c0446d6SStefano Zampini 12909c0446d6SStefano Zampini Input Parameters: 12919c0446d6SStefano Zampini + pc - the preconditioning context 12920f202f7eSStefano Zampini . n_is - number of index sets defining the fields 12930f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in global ordering 12949c0446d6SStefano Zampini 12959c0446d6SStefano Zampini Level: intermediate 12969c0446d6SStefano Zampini 12970f202f7eSStefano Zampini Notes: 12980f202f7eSStefano Zampini Any process can list any global node. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 12999c0446d6SStefano Zampini 13009c0446d6SStefano Zampini .seealso: PCBDDC 13019c0446d6SStefano Zampini @*/ 13029c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 13039c0446d6SStefano Zampini { 13042b510759SStefano Zampini PetscInt i; 13059c0446d6SStefano Zampini PetscErrorCode ierr; 13069c0446d6SStefano Zampini 13079c0446d6SStefano Zampini PetscFunctionBegin; 13089c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 130963602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 13102b510759SStefano Zampini for (i=0;i<n_is;i++) { 131163602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 1312a011d5a7Sstefano_zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 13132b510759SStefano Zampini } 13149c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 13159c0446d6SStefano Zampini PetscFunctionReturn(0); 13169c0446d6SStefano Zampini } 1317906d46d4SStefano Zampini 1318534831adSStefano Zampini /* 1319534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 1320534831adSStefano Zampini guess if a transformation of basis approach has been selected. 13219c0446d6SStefano Zampini 1322534831adSStefano Zampini Input Parameter: 1323966d8056SPierre Jolivet + pc - the preconditioner context 1324534831adSStefano Zampini 1325534831adSStefano Zampini Application Interface Routine: PCPreSolve() 1326534831adSStefano Zampini 1327534831adSStefano Zampini Notes: 1328534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 1329534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1330534831adSStefano Zampini */ 1331534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1332534831adSStefano Zampini { 1333534831adSStefano Zampini PetscErrorCode ierr; 1334534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1335534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 13363972b0daSStefano Zampini Vec used_vec; 13374df7a6bfSStefano Zampini PetscBool iscg = PETSC_FALSE, save_rhs = PETSC_TRUE, benign_correction_computed; 1338534831adSStefano Zampini 1339534831adSStefano Zampini PetscFunctionBegin; 13401f4df5f7SStefano Zampini /* if we are working with CG, one dirichlet solve can be avoided during Krylov iterations */ 134185c4d303SStefano Zampini if (ksp) { 13424df7a6bfSStefano Zampini PetscBool isgroppcg, ispipecg, ispipelcg, ispipecgrr; 13434df7a6bfSStefano Zampini 134485c4d303SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr); 134527b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPGROPPCG,&isgroppcg);CHKERRQ(ierr); 134627b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECG,&ispipecg);CHKERRQ(ierr); 13474df7a6bfSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECG,&ispipelcg);CHKERRQ(ierr); 1348f94e96cbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECGRR,&ispipecgrr);CHKERRQ(ierr); 13494df7a6bfSStefano Zampini iscg = (PetscBool)(iscg || isgroppcg || ispipecg || ispipelcg || ispipecgrr); 13503bf6e316SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static || !iscg || pc->mat != pc->pmat) { 135185c4d303SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 135285c4d303SStefano Zampini } 135385c4d303SStefano Zampini } 13543bf6e316SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static || pc->mat != pc->pmat) { 1355fc17d649SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 1356fc17d649SStefano Zampini } 13571f4df5f7SStefano Zampini 135885c4d303SStefano Zampini /* Creates parallel work vectors used in presolve */ 135962a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 136062a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 136162a6ff1dSStefano Zampini } 136262a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 136362a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 136462a6ff1dSStefano Zampini } 13658d00608fSStefano Zampini 136627b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_FALSE; 13673972b0daSStefano Zampini if (x) { 13683972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 13693972b0daSStefano Zampini used_vec = x; 13708d00608fSStefano Zampini } else { /* it can only happen when calling PCBDDCMatFETIDPGetRHS */ 13713972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 13723972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 13733972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 137427b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 1375266e20e9SStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 1376266e20e9SStefano Zampini save_rhs = PETSC_FALSE; 1377266e20e9SStefano Zampini pcbddc->eliminate_dirdofs = PETSC_TRUE; 13783972b0daSStefano Zampini } 13798efcfb23SStefano Zampini 13808efcfb23SStefano Zampini /* hack into ksp data structure since PCPreSolve comes earlier than setting to zero the guess in src/ksp/ksp/interface/itfunc.c */ 13813972b0daSStefano Zampini if (ksp) { 1382a0cb1b98SStefano Zampini /* store the flag for the initial guess since it will be restored back during PCPostSolve_BDDC */ 13838efcfb23SStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 13848efcfb23SStefano Zampini if (!pcbddc->ksp_guess_nonzero) { 13853972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 13863972b0daSStefano Zampini } 13873972b0daSStefano Zampini } 13883308cffdSStefano Zampini 13898d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 13903972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 139170c64980SStefano Zampini if (rhs && pcbddc->eliminate_dirdofs) { 13923975b054SStefano Zampini IS dirIS = NULL; 13933975b054SStefano Zampini 1394a07ea27aSStefano Zampini /* DirichletBoundariesLocal may not be consistent among neighbours; gets a dirichlet dofs IS from graph (may be cached) */ 13953975b054SStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 13963975b054SStefano Zampini if (dirIS) { 1397906d46d4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1398785d1243SStefano Zampini PetscInt dirsize,i,*is_indices; 13992b095fd8SStefano Zampini PetscScalar *array_x; 14002b095fd8SStefano Zampini const PetscScalar *array_diagonal; 1401785d1243SStefano Zampini 14023972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 14033972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 1404e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1405e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1406e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1407e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 140882ba6b80SStefano Zampini ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr); 14093972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 14102b095fd8SStefano Zampini ierr = VecGetArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 14113972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 14122fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 14133972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 14142b095fd8SStefano Zampini ierr = VecRestoreArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 14153972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 1416e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1417e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 14188d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 14191b968477SStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 14208efcfb23SStefano Zampini } 1421a07ea27aSStefano Zampini } 1422b76ba322SStefano Zampini 14238efcfb23SStefano Zampini /* remove the computed solution or the initial guess from the rhs */ 14248d00608fSStefano Zampini if (pcbddc->rhs_change || (ksp && pcbddc->ksp_guess_nonzero)) { 142527b6a85dSStefano Zampini /* save the original rhs */ 142627b6a85dSStefano Zampini if (save_rhs) { 142727b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 142827b6a85dSStefano Zampini save_rhs = PETSC_FALSE; 14298d00608fSStefano Zampini } 14308d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 14313972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 143227b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,used_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 14333972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 14348efcfb23SStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 143527b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 14367acc28cbSStefano Zampini if (ksp) { 14377acc28cbSStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_FALSE);CHKERRQ(ierr); 14387acc28cbSStefano Zampini } 14393308cffdSStefano Zampini } 14408efcfb23SStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 1441b76ba322SStefano Zampini 1442fc17d649SStefano Zampini /* compute initial vector in benign space if needed 144327b6a85dSStefano Zampini and remove non-benign solution from the rhs */ 144427b6a85dSStefano Zampini benign_correction_computed = PETSC_FALSE; 144508af2428SStefano Zampini if (rhs && pcbddc->benign_compute_correction && (pcbddc->benign_have_null || pcbddc->benign_apply_coarse_only)) { 14461f4df5f7SStefano Zampini /* compute u^*_h using ideas similar to those in Xuemin Tu's PhD thesis (see Section 4.8.1) 14471f4df5f7SStefano Zampini Recursively apply BDDC in the multilevel case */ 14480369aaf7SStefano Zampini if (!pcbddc->benign_vec) { 14490369aaf7SStefano Zampini ierr = VecDuplicate(rhs,&pcbddc->benign_vec);CHKERRQ(ierr); 14500369aaf7SStefano Zampini } 1451c69e9cc1SStefano Zampini /* keep applying coarse solver unless we no longer have benign subdomains */ 1452c69e9cc1SStefano Zampini pcbddc->benign_apply_coarse_only = pcbddc->benign_have_null ? PETSC_TRUE : PETSC_FALSE; 145327b6a85dSStefano Zampini if (!pcbddc->benign_skip_correction) { 14541dd7afcfSStefano Zampini ierr = PCApply_BDDC(pc,rhs,pcbddc->benign_vec);CHKERRQ(ierr); 14553bca92a6SStefano Zampini benign_correction_computed = PETSC_TRUE; 14561f4df5f7SStefano Zampini if (pcbddc->temp_solution_used) { 14571f4df5f7SStefano Zampini ierr = VecAXPY(pcbddc->temp_solution,1.0,pcbddc->benign_vec);CHKERRQ(ierr); 14581f4df5f7SStefano Zampini } 14591f4df5f7SStefano Zampini ierr = VecScale(pcbddc->benign_vec,-1.0);CHKERRQ(ierr); 146027b6a85dSStefano Zampini /* store the original rhs if not done earlier */ 146127b6a85dSStefano Zampini if (save_rhs) { 146227b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 146392e3dcfbSStefano Zampini } 146427b6a85dSStefano Zampini if (pcbddc->rhs_change) { 14650369aaf7SStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,rhs,rhs);CHKERRQ(ierr); 146627b6a85dSStefano Zampini } else { 146727b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 146827b6a85dSStefano Zampini } 14690369aaf7SStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 147027b6a85dSStefano Zampini } 147127b6a85dSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_FALSE; 14724df7a6bfSStefano Zampini } else { 14734df7a6bfSStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 14740369aaf7SStefano Zampini } 14752d4c4fecSStefano Zampini 14762d4c4fecSStefano Zampini /* dbg output */ 1477a198735bSStefano Zampini if (pcbddc->dbg_flag && benign_correction_computed) { 14781f4df5f7SStefano Zampini Vec v; 1479c69e9cc1SStefano Zampini 14801f4df5f7SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&v);CHKERRQ(ierr); 1481c69e9cc1SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 14821f4df5f7SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,v);CHKERRQ(ierr); 1483c69e9cc1SStefano Zampini } else { 1484c69e9cc1SStefano Zampini ierr = VecCopy(rhs,v);CHKERRQ(ierr); 1485c69e9cc1SStefano Zampini } 14861f4df5f7SStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,v,PETSC_TRUE);CHKERRQ(ierr); 1487e0fe2d75SToby Isaac ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"LEVEL %D: is the correction benign?\n",pcbddc->current_level);CHKERRQ(ierr); 1488c69e9cc1SStefano Zampini ierr = PetscScalarView(pcbddc->benign_n,pcbddc->benign_p0,pcbddc->dbg_viewer);CHKERRQ(ierr); 1489c69e9cc1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 14901f4df5f7SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 14911f4df5f7SStefano Zampini } 14920369aaf7SStefano Zampini 14930369aaf7SStefano Zampini /* set initial guess if using PCG */ 14948ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 14950369aaf7SStefano Zampini if (x && pcbddc->use_exact_dirichlet_trick) { 14960369aaf7SStefano Zampini ierr = VecSet(x,0.0);CHKERRQ(ierr); 14971dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 149827b6a85dSStefano Zampini if (benign_correction_computed) { /* we have already saved the changed rhs */ 14998860a134SJunchao Zhang ierr = VecLockReadPop(pcis->vec1_global);CHKERRQ(ierr); 15001dd7afcfSStefano Zampini } else { 15011dd7afcfSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,pcis->vec1_global);CHKERRQ(ierr); 15021dd7afcfSStefano Zampini } 15031dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15041dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15051dd7afcfSStefano Zampini } else { 15060369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15070369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15081dd7afcfSStefano Zampini } 150955c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 15100369aaf7SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 151155c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 1512c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 15131dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 15141dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.);CHKERRQ(ierr); 15151dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15161dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15171dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x);CHKERRQ(ierr); 15181dd7afcfSStefano Zampini } else { 15190369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15200369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15211dd7afcfSStefano Zampini } 15220369aaf7SStefano Zampini if (ksp) { 15230369aaf7SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 15240369aaf7SStefano Zampini } 15258ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_TRUE; 1526266e20e9SStefano Zampini } else if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior && benign_correction_computed && pcbddc->use_exact_dirichlet_trick) { 15278860a134SJunchao Zhang ierr = VecLockReadPop(pcis->vec1_global);CHKERRQ(ierr); 15280369aaf7SStefano Zampini } 1529534831adSStefano Zampini PetscFunctionReturn(0); 1530534831adSStefano Zampini } 1531906d46d4SStefano Zampini 1532534831adSStefano Zampini /* 1533534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 1534534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 1535534831adSStefano Zampini 1536534831adSStefano Zampini Input Parameter: 1537966d8056SPierre Jolivet + pc - the preconditioner context 1538534831adSStefano Zampini 1539534831adSStefano Zampini Application Interface Routine: PCPostSolve() 1540534831adSStefano Zampini 1541534831adSStefano Zampini Notes: 1542534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 1543534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1544534831adSStefano Zampini */ 1545534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1546534831adSStefano Zampini { 1547534831adSStefano Zampini PetscErrorCode ierr; 1548534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1549534831adSStefano Zampini 1550534831adSStefano Zampini PetscFunctionBegin; 15513972b0daSStefano Zampini /* add solution removed in presolve */ 15526bcfc461SStefano Zampini if (x && pcbddc->rhs_change) { 155327b6a85dSStefano Zampini if (pcbddc->temp_solution_used) { 15543425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 1555af140850Sstefano_zampini } else if (pcbddc->benign_compute_correction && pcbddc->benign_vec) { 155627b6a85dSStefano Zampini ierr = VecAXPY(x,-1.0,pcbddc->benign_vec);CHKERRQ(ierr); 15573425bc38SStefano Zampini } 1558af140850Sstefano_zampini /* restore to original state (not for FETI-DP) */ 1559af140850Sstefano_zampini if (ksp) pcbddc->temp_solution_used = PETSC_FALSE; 156027b6a85dSStefano Zampini } 156127b6a85dSStefano Zampini 1562266e20e9SStefano Zampini /* restore rhs to its original state (not needed for FETI-DP) */ 15638d00608fSStefano Zampini if (rhs && pcbddc->rhs_change) { 156427b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 15658d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 1566af140850Sstefano_zampini } 15678efcfb23SStefano Zampini /* restore ksp guess state */ 15688efcfb23SStefano Zampini if (ksp) { 15698efcfb23SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 15708ae0ca82SStefano Zampini /* reset flag for exact dirichlet trick */ 15718ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 1572af140850Sstefano_zampini } 1573534831adSStefano Zampini PetscFunctionReturn(0); 1574534831adSStefano Zampini } 1575af140850Sstefano_zampini 15760c7d97c5SJed Brown /* 15770c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 15780c7d97c5SJed Brown by setting data structures and options. 15790c7d97c5SJed Brown 15800c7d97c5SJed Brown Input Parameter: 158153cdbc3dSStefano Zampini + pc - the preconditioner context 15820c7d97c5SJed Brown 15830c7d97c5SJed Brown Application Interface Routine: PCSetUp() 15840c7d97c5SJed Brown 15850c7d97c5SJed Brown Notes: 15860c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 15870c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 15880c7d97c5SJed Brown */ 158953cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 15900c7d97c5SJed Brown { 15910c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1592c703fcc7SStefano Zampini PCBDDCSubSchurs sub_schurs; 15935e8657edSStefano Zampini Mat_IS* matis; 159408122e43SStefano Zampini MatNullSpace nearnullspace; 159535509ce9Sstefano_zampini Mat lA; 159635509ce9Sstefano_zampini IS lP,zerodiag = NULL; 159791e8d312SStefano Zampini PetscInt nrows,ncols; 159886bfa4cfSStefano Zampini PetscMPIInt size; 1599c703fcc7SStefano Zampini PetscBool computesubschurs; 16008de1fae6SStefano Zampini PetscBool computeconstraintsmatrix; 16013b03f7bbSStefano Zampini PetscBool new_nearnullspace_provided,ismatis,rl; 1602c703fcc7SStefano Zampini PetscErrorCode ierr; 16030c7d97c5SJed Brown 16040c7d97c5SJed Brown PetscFunctionBegin; 16055e8657edSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATIS,&ismatis);CHKERRQ(ierr); 16062c71b3e2SJacob Faibussowitsch PetscCheckFalse(!ismatis,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner requires matrix of type MATIS"); 160791e8d312SStefano Zampini ierr = MatGetSize(pc->pmat,&nrows,&ncols);CHKERRQ(ierr); 16082c71b3e2SJacob Faibussowitsch PetscCheckFalse(nrows != ncols,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PCBDDC preconditioner requires a square preconditioning matrix"); 1609ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRMPI(ierr); 161086bfa4cfSStefano Zampini 16115e8657edSStefano Zampini matis = (Mat_IS*)pc->pmat->data; 1612f4ddd8eeSStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other future nonoverlapping preconditioners */ 16133b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 161471582508SStefano Zampini Also, BDDC builds its own KSP for the Dirichlet problem */ 16153b03f7bbSStefano Zampini rl = pcbddc->recompute_topography; 16163b03f7bbSStefano Zampini if (!pc->setupcalled || pc->flag == DIFFERENT_NONZERO_PATTERN) rl = PETSC_TRUE; 1617820f2d46SBarry Smith ierr = MPIU_Allreduce(&rl,&pcbddc->recompute_topography,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRMPI(ierr); 1618c83e1ba7SStefano Zampini if (pcbddc->recompute_topography) { 1619c83e1ba7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 1620c83e1ba7SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1621c83e1ba7SStefano Zampini } else { 16228de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_FALSE; 1623c83e1ba7SStefano Zampini } 1624b087196eSStefano Zampini 1625b087196eSStefano Zampini /* check parameters' compatibility */ 1626b7ab4a40SStefano Zampini if (!pcbddc->use_deluxe_scaling) pcbddc->deluxe_zerorows = PETSC_FALSE; 1627bd2a564bSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_threshold[0] != 0.0 || pcbddc->adaptive_threshold[1] != 0.0); 162886bfa4cfSStefano Zampini pcbddc->use_deluxe_scaling = (PetscBool)(pcbddc->use_deluxe_scaling && size > 1); 162986bfa4cfSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_selection && size > 1); 1630bf3a8328SStefano Zampini pcbddc->adaptive_userdefined = (PetscBool)(pcbddc->adaptive_selection && pcbddc->adaptive_userdefined); 1631862806e4SStefano Zampini if (pcbddc->adaptive_selection) pcbddc->use_faces = PETSC_TRUE; 1632862806e4SStefano Zampini 16335a95e1ceSStefano Zampini computesubschurs = (PetscBool)(pcbddc->adaptive_selection || pcbddc->use_deluxe_scaling); 163416909a7fSStefano Zampini 163571582508SStefano Zampini /* activate all connected components if the netflux has been requested */ 1636bb05f991SStefano Zampini if (pcbddc->compute_nonetflux) { 1637bb05f991SStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 1638bb05f991SStefano Zampini pcbddc->use_edges = PETSC_TRUE; 1639bb05f991SStefano Zampini pcbddc->use_faces = PETSC_TRUE; 1640bb05f991SStefano Zampini } 1641bb05f991SStefano Zampini 1642f4ddd8eeSStefano Zampini /* Get stdout for dbg */ 164370cf5478SStefano Zampini if (pcbddc->dbg_flag) { 164470cf5478SStefano Zampini if (!pcbddc->dbg_viewer) { 164558a03d70SStefano Zampini pcbddc->dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pc)); 1646f4ddd8eeSStefano Zampini } 1647d9869140SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 164858a03d70SStefano Zampini ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1649f4ddd8eeSStefano Zampini } 1650f4ddd8eeSStefano Zampini 1651c703fcc7SStefano Zampini /* process topology information */ 165243371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Topology[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 165371582508SStefano Zampini if (pcbddc->recompute_topography) { 165471582508SStefano Zampini ierr = PCBDDCComputeLocalTopologyInfo(pc);CHKERRQ(ierr); 1655c703fcc7SStefano Zampini if (pcbddc->discretegradient) { 1656a13144ffSStefano Zampini ierr = PCBDDCNedelecSupport(pc);CHKERRQ(ierr); 1657a13144ffSStefano Zampini } 1658c703fcc7SStefano Zampini } 16594f819b78SStefano Zampini if (pcbddc->corner_selected) pcbddc->use_vertices = PETSC_TRUE; 1660a13144ffSStefano Zampini 1661c703fcc7SStefano Zampini /* change basis if requested by the user */ 16625e8657edSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 16635e8657edSStefano Zampini /* use_change_of_basis flag is used to automatically compute a change of basis from constraints */ 16645e8657edSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 16655e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 16665e8657edSStefano Zampini } else { 1667b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 16685e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 16695e8657edSStefano Zampini pcbddc->local_mat = matis->A; 1670d16cbb6bSStefano Zampini } 1671d16cbb6bSStefano Zampini 16724f1b2e48SStefano Zampini /* 1673c703fcc7SStefano Zampini Compute change of basis on local pressures (aka zerodiag dofs) with the benign trick 16744f1b2e48SStefano Zampini This should come earlier then PCISSetUp for extracting the correct subdomain matrices 16754f1b2e48SStefano Zampini */ 16761dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 1677d16cbb6bSStefano Zampini if (pcbddc->benign_saddle_point) { 16789f47a83aSStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 16799f47a83aSStefano Zampini 168005b28244SStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->use_change_of_basis || !computesubschurs) pcbddc->benign_change_explicit = PETSC_TRUE; 16813b03f7bbSStefano Zampini /* detect local saddle point and change the basis in pcbddc->local_mat */ 16823b03f7bbSStefano Zampini ierr = PCBDDCBenignDetectSaddlePoint(pc,(PetscBool)(!pcbddc->recompute_topography),&zerodiag);CHKERRQ(ierr); 1683a3df083aSStefano Zampini /* pop B0 mat from local mat */ 1684c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 16851dd7afcfSStefano Zampini /* give pcis a hint to not reuse submatrices during PCISCreate */ 16861dd7afcfSStefano Zampini if (pc->flag == SAME_NONZERO_PATTERN && pcis->reusesubmatrices == PETSC_TRUE) { 16871dd7afcfSStefano Zampini if (pcbddc->benign_n && (pcbddc->benign_change_explicit || pcbddc->dbg_flag)) { 16881dd7afcfSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 16891dd7afcfSStefano Zampini } else { 1690a3df083aSStefano Zampini pcis->reusesubmatrices = PETSC_TRUE; 16911dd7afcfSStefano Zampini } 1692a3df083aSStefano Zampini } else { 16939f47a83aSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 1694674ae819SStefano Zampini } 1695a3df083aSStefano Zampini } 169627b6a85dSStefano Zampini 16978037d520SStefano Zampini /* propagate relevant information */ 169806a4e24aSStefano Zampini if (matis->A->symmetric_set) { 169906a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 170006a4e24aSStefano Zampini } 170106a4e24aSStefano Zampini if (matis->A->spd_set) { 170206a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SPD,matis->A->spd);CHKERRQ(ierr); 170306a4e24aSStefano Zampini } 1704e496cd5dSStefano Zampini 17055e8657edSStefano Zampini /* Set up all the "iterative substructuring" common block without computing solvers */ 17065e8657edSStefano Zampini { 17075e8657edSStefano Zampini Mat temp_mat; 17085e8657edSStefano Zampini 17095e8657edSStefano Zampini temp_mat = matis->A; 17105e8657edSStefano Zampini matis->A = pcbddc->local_mat; 1711d9869140SStefano Zampini ierr = PCISSetUp(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 17125e8657edSStefano Zampini pcbddc->local_mat = matis->A; 17135e8657edSStefano Zampini matis->A = temp_mat; 17145e8657edSStefano Zampini } 1715684f6988SStefano Zampini 171681d14e9dSStefano Zampini /* Analyze interface */ 171764ac59b8SStefano Zampini if (!pcbddc->graphanalyzed) { 1718674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 17198de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1720345ecf6cSStefano Zampini if (pcbddc->adaptive_selection && !pcbddc->use_deluxe_scaling && !pcbddc->mat_graph->twodim) { 17214247aa23Sstefano_zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot compute the adaptive primal space for a problem with 3D edges without deluxe scaling"); 1722345ecf6cSStefano Zampini } 1723a198735bSStefano Zampini if (pcbddc->compute_nonetflux) { 1724669cc0f4SStefano Zampini MatNullSpace nnfnnsp; 1725669cc0f4SStefano Zampini 17262c71b3e2SJacob Faibussowitsch PetscCheckFalse(!pcbddc->divudotp,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Missing divudotp operator"); 17278ae0ca82SStefano Zampini ierr = PCBDDCComputeNoNetFlux(pc->pmat,pcbddc->divudotp,pcbddc->divudotp_trans,pcbddc->divudotp_vl2l,pcbddc->mat_graph,&nnfnnsp);CHKERRQ(ierr); 172871582508SStefano Zampini /* TODO what if a nearnullspace is already attached? */ 17298037d520SStefano Zampini if (nnfnnsp) { 1730669cc0f4SStefano Zampini ierr = MatSetNearNullSpace(pc->pmat,nnfnnsp);CHKERRQ(ierr); 1731669cc0f4SStefano Zampini ierr = MatNullSpaceDestroy(&nnfnnsp);CHKERRQ(ierr); 1732669cc0f4SStefano Zampini } 1733674ae819SStefano Zampini } 17348037d520SStefano Zampini } 173543371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Topology[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 1736fb8d54d4SStefano Zampini 17375408967cSStefano Zampini /* check existence of a divergence free extension, i.e. 17385408967cSStefano Zampini b(v_I,p_0) = 0 for all v_I (raise error if not). 17395408967cSStefano Zampini Also, check that PCBDDCBenignGetOrSetP0 works */ 1740ff1f7e73Sstefano_zampini if (pcbddc->benign_saddle_point && pcbddc->dbg_flag > 1) { 17415408967cSStefano Zampini ierr = PCBDDCBenignCheck(pc,zerodiag);CHKERRQ(ierr); 174209f581a4SStefano Zampini } 17434f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 174406f24817SStefano Zampini 1745b96c3477SStefano Zampini /* Setup local dirichlet solver ksp_D and sub_schurs solvers */ 1746c703fcc7SStefano Zampini if (computesubschurs && pcbddc->recompute_topography) { 174708122e43SStefano Zampini ierr = PCBDDCInitSubSchurs(pc);CHKERRQ(ierr); 1748b1b3d7a2SStefano Zampini } 17499d54b7f4SStefano Zampini /* SetUp Scaling operator (scaling matrices could be needed in SubSchursSetUp)*/ 17509d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) { 17519d54b7f4SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 17529d54b7f4SStefano Zampini } 1753c703fcc7SStefano Zampini 1754c703fcc7SStefano Zampini /* finish setup solvers and do adaptive selection of constraints */ 1755b334f244SStefano Zampini sub_schurs = pcbddc->sub_schurs; 1756b334f244SStefano Zampini if (sub_schurs && sub_schurs->schur_explicit) { 17572070dbb6SStefano Zampini if (computesubschurs) { 175808122e43SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 17592070dbb6SStefano Zampini } 1760d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 1761d5574798SStefano Zampini } else { 1762d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 17632070dbb6SStefano Zampini if (computesubschurs) { 1764d5574798SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 1765d5574798SStefano Zampini } 17662070dbb6SStefano Zampini } 176708122e43SStefano Zampini if (pcbddc->adaptive_selection) { 176808122e43SStefano Zampini ierr = PCBDDCAdaptiveSelection(pc);CHKERRQ(ierr); 17698de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1770b7eb3628SStefano Zampini } 1771684f6988SStefano Zampini 1772f4ddd8eeSStefano Zampini /* infer if NullSpace object attached to Mat via MatSetNearNullSpace has changed */ 1773fb8d54d4SStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1774f4ddd8eeSStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullspace);CHKERRQ(ierr); 1775f4ddd8eeSStefano Zampini if (pcbddc->onearnullspace) { /* already used nearnullspace */ 1776f4ddd8eeSStefano Zampini if (!nearnullspace) { /* near null space attached to mat has been destroyed */ 1777f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1778f4ddd8eeSStefano Zampini } else { 1779f4ddd8eeSStefano Zampini /* determine if the two nullspaces are different (should be lightweight) */ 1780f4ddd8eeSStefano Zampini if (nearnullspace != pcbddc->onearnullspace) { 1781f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1782165b64e2SStefano Zampini } else { /* maybe the user has changed the content of the nearnullspace so check vectors ObjectStateId */ 1783f4ddd8eeSStefano Zampini PetscInt i; 1784165b64e2SStefano Zampini const Vec *nearnullvecs; 1785165b64e2SStefano Zampini PetscObjectState state; 1786165b64e2SStefano Zampini PetscInt nnsp_size; 1787165b64e2SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullspace,NULL,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1788f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1789f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&state);CHKERRQ(ierr); 1790165b64e2SStefano Zampini if (pcbddc->onearnullvecs_state[i] != state) { 1791f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1792f4ddd8eeSStefano Zampini break; 1793f4ddd8eeSStefano Zampini } 1794f4ddd8eeSStefano Zampini } 1795f4ddd8eeSStefano Zampini } 1796f4ddd8eeSStefano Zampini } 1797f4ddd8eeSStefano Zampini } else { 1798f4ddd8eeSStefano Zampini if (!nearnullspace) { /* both nearnullspaces are null */ 1799f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1800f4ddd8eeSStefano Zampini } else { /* nearnullspace attached later */ 1801f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1802f4ddd8eeSStefano Zampini } 1803f4ddd8eeSStefano Zampini } 1804f4ddd8eeSStefano Zampini 1805f4ddd8eeSStefano Zampini /* Setup constraints and related work vectors */ 1806727cdba6SStefano Zampini /* reset primal space flags */ 180743371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_LocalWork[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 1808f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 1809727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 18108de1fae6SStefano Zampini if (computeconstraintsmatrix || new_nearnullspace_provided) { 1811727cdba6SStefano Zampini /* It also sets the primal space flags */ 1812674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 18139543d0ffSStefano Zampini } 1814e7b262bdSStefano Zampini /* Allocate needed local vectors (which depends on quantities defined during ConstraintsSetUp) */ 1815f4ddd8eeSStefano Zampini ierr = PCBDDCSetUpLocalWorkVectors(pc);CHKERRQ(ierr); 18165e8657edSStefano Zampini 18175e8657edSStefano Zampini if (pcbddc->use_change_of_basis) { 18185e8657edSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 18195e8657edSStefano Zampini 18205e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 18214f1b2e48SStefano Zampini if (pcbddc->benign_change) { 18221dd7afcfSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 1823c263805aSStefano Zampini /* pop B0 from pcbddc->local_mat */ 1824c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 1825c263805aSStefano Zampini } 18265e8657edSStefano Zampini /* get submatrices */ 18275e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 18285e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 18295e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 18307dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 18317dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 18327dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 18333975b054SStefano Zampini /* set flag in pcis to not reuse submatrices during PCISCreate */ 18343975b054SStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 18359c6a02ceSStefano Zampini } else if (!pcbddc->user_ChangeOfBasisMatrix && !pcbddc->benign_change) { 1836b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 18375e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 18385e8657edSStefano Zampini pcbddc->local_mat = matis->A; 18395e8657edSStefano Zampini } 184035509ce9Sstefano_zampini 184135509ce9Sstefano_zampini /* interface pressure block row for B_C */ 184235509ce9Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lP" ,(PetscObject*)&lP);CHKERRQ(ierr); 184335509ce9Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject*)&lA);CHKERRQ(ierr); 184435509ce9Sstefano_zampini if (lA && lP) { 184535509ce9Sstefano_zampini PC_IS* pcis = (PC_IS*)pc->data; 184635509ce9Sstefano_zampini Mat B_BI,B_BB,Bt_BI,Bt_BB; 184735509ce9Sstefano_zampini PetscBool issym; 184835509ce9Sstefano_zampini ierr = MatIsSymmetric(lA,PETSC_SMALL,&issym);CHKERRQ(ierr); 18496cc1294bSstefano_zampini if (issym) { 18507dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_I_local,MAT_INITIAL_MATRIX,&B_BI);CHKERRQ(ierr); 18517dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_B_local,MAT_INITIAL_MATRIX,&B_BB);CHKERRQ(ierr); 185235509ce9Sstefano_zampini ierr = MatCreateTranspose(B_BI,&Bt_BI);CHKERRQ(ierr); 185335509ce9Sstefano_zampini ierr = MatCreateTranspose(B_BB,&Bt_BB);CHKERRQ(ierr); 185435509ce9Sstefano_zampini } else { 18557dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_I_local,MAT_INITIAL_MATRIX,&B_BI);CHKERRQ(ierr); 18567dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_B_local,MAT_INITIAL_MATRIX,&B_BB);CHKERRQ(ierr); 18577dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,pcis->is_I_local,lP,MAT_INITIAL_MATRIX,&Bt_BI);CHKERRQ(ierr); 18587dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,pcis->is_B_local,lP,MAT_INITIAL_MATRIX,&Bt_BB);CHKERRQ(ierr); 185935509ce9Sstefano_zampini } 186035509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_B_BI",(PetscObject)B_BI);CHKERRQ(ierr); 186135509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_B_BB",(PetscObject)B_BB);CHKERRQ(ierr); 186235509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_Bt_BI",(PetscObject)Bt_BI);CHKERRQ(ierr); 186335509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_Bt_BB",(PetscObject)Bt_BB);CHKERRQ(ierr); 186435509ce9Sstefano_zampini ierr = MatDestroy(&B_BI);CHKERRQ(ierr); 186535509ce9Sstefano_zampini ierr = MatDestroy(&B_BB);CHKERRQ(ierr); 186635509ce9Sstefano_zampini ierr = MatDestroy(&Bt_BI);CHKERRQ(ierr); 186735509ce9Sstefano_zampini ierr = MatDestroy(&Bt_BB);CHKERRQ(ierr); 186835509ce9Sstefano_zampini } 186943371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_LocalWork[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 187035509ce9Sstefano_zampini 1871b96c3477SStefano Zampini /* SetUp coarse and local Neumann solvers */ 187299cc7994SStefano Zampini ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr); 1873b96c3477SStefano Zampini /* SetUp Scaling operator */ 18749d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1875674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 18760c7d97c5SJed Brown } 1877c703fcc7SStefano Zampini 18781dd7afcfSStefano Zampini /* mark topography as done */ 187956282151SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 18800369aaf7SStefano Zampini 18811dd7afcfSStefano Zampini /* wrap pcis->A_IB and pcis->A_BI if we did not change explicitly the variables on the pressures */ 18821dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_FALSE);CHKERRQ(ierr); 18831dd7afcfSStefano Zampini 188458a03d70SStefano Zampini if (pcbddc->dbg_flag) { 188558a03d70SStefano Zampini ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1886d9869140SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 18872b510759SStefano Zampini } 18880c7d97c5SJed Brown PetscFunctionReturn(0); 18890c7d97c5SJed Brown } 18900c7d97c5SJed Brown 18910c7d97c5SJed Brown /* 189250efa1b5SStefano Zampini PCApply_BDDC - Applies the BDDC operator to a vector. 18930c7d97c5SJed Brown 18940c7d97c5SJed Brown Input Parameters: 18950f202f7eSStefano Zampini + pc - the preconditioner context 18960f202f7eSStefano Zampini - r - input vector (global) 18970c7d97c5SJed Brown 18980c7d97c5SJed Brown Output Parameter: 18990c7d97c5SJed Brown . z - output vector (global) 19000c7d97c5SJed Brown 19010c7d97c5SJed Brown Application Interface Routine: PCApply() 19020c7d97c5SJed Brown */ 190353cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 19040c7d97c5SJed Brown { 19050c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 19060c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1907b3338236SStefano Zampini Mat lA = NULL; 1908b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 19090c7d97c5SJed Brown PetscErrorCode ierr; 19103b03a366Sstefano_zampini const PetscScalar one = 1.0; 19113b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 19122617d88aSStefano Zampini const PetscScalar zero = 0.0; 19130c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 19140c7d97c5SJed Brown NN interface preconditioner changed to BDDC 1915b097fa66SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static == PETSC_TRUE) */ 19160c7d97c5SJed Brown 19170c7d97c5SJed Brown PetscFunctionBegin; 1918f3d41395Sstefano_zampini ierr = PetscCitationsRegister(citation,&cited);CHKERRQ(ierr); 1919b3338236SStefano Zampini if (pcbddc->switch_static) { 1920b3338236SStefano Zampini ierr = MatISGetLocalMat(pc->useAmat ? pc->mat : pc->pmat,&lA);CHKERRQ(ierr); 1921b3338236SStefano Zampini } 1922b3338236SStefano Zampini 19231dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 19241dd7afcfSStefano Zampini Vec swap; 192527b6a85dSStefano Zampini 192627b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 19271dd7afcfSStefano Zampini swap = pcbddc->work_change; 19281dd7afcfSStefano Zampini pcbddc->work_change = r; 19291dd7afcfSStefano Zampini r = swap; 19301dd7afcfSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 19319cc2a9b1Sstefano_zampini if (pcbddc->benign_apply_coarse_only && pcbddc->use_exact_dirichlet_trick && pcbddc->change_interior) { 19321dd7afcfSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 19338860a134SJunchao Zhang ierr = VecLockReadPush(pcis->vec1_global);CHKERRQ(ierr); 19341dd7afcfSStefano Zampini } 19351dd7afcfSStefano Zampini } 193627b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 1937015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1938efc2fbd9SStefano Zampini } 1939bc960bbfSJed Brown if (pcbddc->interface_extension == PC_BDDC_INTERFACE_EXT_DIRICHLET && !pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 1940b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 19410c7d97c5SJed Brown /* First Dirichlet solve */ 19420c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19430c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19440c7d97c5SJed Brown /* 19450c7d97c5SJed Brown Assembling right hand side for BDDC operator 1946b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 1947674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 19480c7d97c5SJed Brown */ 1949b097fa66SStefano Zampini if (n_D) { 195055c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 1951b097fa66SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 195255c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 1953c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 19540c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 195516909a7fSStefano Zampini if (pcbddc->switch_static) { 195616909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 195716909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 195816909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 195916909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 1960b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 196116909a7fSStefano Zampini } else { 196216909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 1963b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 196416909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 196516909a7fSStefano Zampini } 196616909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 196716909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 196816909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 196916909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 197016909a7fSStefano Zampini } else { 1971b097fa66SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 197216909a7fSStefano Zampini } 1973b097fa66SStefano Zampini } else { 1974b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1975b097fa66SStefano Zampini } 19760c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19770c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1978674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 1979b76ba322SStefano Zampini } else { 19804fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 1981674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 1982b76ba322SStefano Zampini } 19834fee134fSStefano Zampini } 1984bc960bbfSJed Brown if (pcbddc->interface_extension == PC_BDDC_INTERFACE_EXT_LUMP) { 19852c71b3e2SJacob Faibussowitsch PetscCheckFalse(!pcbddc->switch_static,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"You forgot to pass -pc_bddc_switch_static"); 1986bc960bbfSJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1987bc960bbfSJed Brown ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1988bc960bbfSJed Brown } 1989b76ba322SStefano Zampini 19902617d88aSStefano Zampini /* Apply interface preconditioner 19912617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1992dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 19932617d88aSStefano Zampini 1994674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 1995674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 1996bc960bbfSJed Brown if (pcbddc->interface_extension == PC_BDDC_INTERFACE_EXT_LUMP) { 1997bc960bbfSJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1998bc960bbfSJed Brown ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1999bc960bbfSJed Brown PetscFunctionReturn(0); 2000bc960bbfSJed Brown } 20013b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 20020c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20030c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2004b097fa66SStefano Zampini if (n_B) { 200516909a7fSStefano Zampini if (pcbddc->switch_static) { 200616909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 200716909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 200816909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 200916909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 201016909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 2011b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 201216909a7fSStefano Zampini } else { 201316909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 2014b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 201516909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 201616909a7fSStefano Zampini } 201716909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 201816909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 201916909a7fSStefano Zampini } else { 20200c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 202116909a7fSStefano Zampini } 202216909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 202316909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 2024b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 202516909a7fSStefano Zampini } else { 202616909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 2027b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 202816909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 202916909a7fSStefano Zampini } 2030b097fa66SStefano Zampini } 203155c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 2032df187020SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 203355c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 2034c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec4_D);CHKERRQ(ierr); 2035efc2fbd9SStefano Zampini 20368ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2037b097fa66SStefano Zampini if (pcbddc->switch_static) { 2038b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 2039b097fa66SStefano Zampini } else { 2040b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 2041b097fa66SStefano Zampini } 20420c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20430c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2044b097fa66SStefano Zampini } else { 2045b097fa66SStefano Zampini if (pcbddc->switch_static) { 2046b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 2047b097fa66SStefano Zampini } else { 2048b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 2049b097fa66SStefano Zampini } 2050b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2051b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2052b097fa66SStefano Zampini } 205327b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 20541dd7afcfSStefano Zampini if (pcbddc->benign_apply_coarse_only) { 2055580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->benign_p0,pcbddc->benign_n);CHKERRQ(ierr); 20561dd7afcfSStefano Zampini } 2057015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 2058efc2fbd9SStefano Zampini } 20591f4df5f7SStefano Zampini 20601dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2061f913dca9SStefano Zampini pcbddc->work_change = r; 20621dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 20631dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 20641dd7afcfSStefano Zampini } 20650c7d97c5SJed Brown PetscFunctionReturn(0); 20660c7d97c5SJed Brown } 206750efa1b5SStefano Zampini 206850efa1b5SStefano Zampini /* 206950efa1b5SStefano Zampini PCApplyTranspose_BDDC - Applies the transpose of the BDDC operator to a vector. 207050efa1b5SStefano Zampini 207150efa1b5SStefano Zampini Input Parameters: 20720f202f7eSStefano Zampini + pc - the preconditioner context 20730f202f7eSStefano Zampini - r - input vector (global) 207450efa1b5SStefano Zampini 207550efa1b5SStefano Zampini Output Parameter: 207650efa1b5SStefano Zampini . z - output vector (global) 207750efa1b5SStefano Zampini 207850efa1b5SStefano Zampini Application Interface Routine: PCApplyTranspose() 207950efa1b5SStefano Zampini */ 208050efa1b5SStefano Zampini PetscErrorCode PCApplyTranspose_BDDC(PC pc,Vec r,Vec z) 208150efa1b5SStefano Zampini { 208250efa1b5SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 208350efa1b5SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 2084b3338236SStefano Zampini Mat lA = NULL; 2085b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 208650efa1b5SStefano Zampini PetscErrorCode ierr; 208750efa1b5SStefano Zampini const PetscScalar one = 1.0; 208850efa1b5SStefano Zampini const PetscScalar m_one = -1.0; 208950efa1b5SStefano Zampini const PetscScalar zero = 0.0; 209050efa1b5SStefano Zampini 209150efa1b5SStefano Zampini PetscFunctionBegin; 2092f3d41395Sstefano_zampini ierr = PetscCitationsRegister(citation,&cited);CHKERRQ(ierr); 2093b3338236SStefano Zampini if (pcbddc->switch_static) { 2094b3338236SStefano Zampini ierr = MatISGetLocalMat(pc->useAmat ? pc->mat : pc->pmat,&lA);CHKERRQ(ierr); 2095b3338236SStefano Zampini } 20961dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 20971dd7afcfSStefano Zampini Vec swap; 209827b6a85dSStefano Zampini 209927b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 21001dd7afcfSStefano Zampini swap = pcbddc->work_change; 21011dd7afcfSStefano Zampini pcbddc->work_change = r; 21021dd7afcfSStefano Zampini r = swap; 210327b6a85dSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 21048ae0ca82SStefano Zampini if (pcbddc->benign_apply_coarse_only && pcbddc->exact_dirichlet_trick_app && pcbddc->change_interior) { 210527b6a85dSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 21068860a134SJunchao Zhang ierr = VecLockReadPush(pcis->vec1_global);CHKERRQ(ierr); 21071dd7afcfSStefano Zampini } 210827b6a85dSStefano Zampini } 210927b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 2110537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 2111537c1cdfSStefano Zampini } 21128ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2113b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 211450efa1b5SStefano Zampini /* First Dirichlet solve */ 211550efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 211650efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 211750efa1b5SStefano Zampini /* 211850efa1b5SStefano Zampini Assembling right hand side for BDDC operator 2119b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 212050efa1b5SStefano Zampini - pcis->vec1_B the interface part of the global vector z 212150efa1b5SStefano Zampini */ 2122b097fa66SStefano Zampini if (n_D) { 212355c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 2124b097fa66SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 212555c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 2126c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 212750efa1b5SStefano Zampini ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 212816909a7fSStefano Zampini if (pcbddc->switch_static) { 212916909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 213016909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 213116909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 213216909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 2133b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 213416909a7fSStefano Zampini } else { 213516909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 2136b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 213716909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 213816909a7fSStefano Zampini } 213916909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 214016909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 214116909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 214216909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 214316909a7fSStefano Zampini } else { 2144b097fa66SStefano Zampini ierr = MatMultTranspose(pcis->A_IB,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 214516909a7fSStefano Zampini } 2146b097fa66SStefano Zampini } else { 2147b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 2148b097fa66SStefano Zampini } 214950efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 215050efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 215150efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 215250efa1b5SStefano Zampini } else { 215350efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 215450efa1b5SStefano Zampini } 215550efa1b5SStefano Zampini 215650efa1b5SStefano Zampini /* Apply interface preconditioner 215750efa1b5SStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 2158dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_TRUE);CHKERRQ(ierr); 215950efa1b5SStefano Zampini 216050efa1b5SStefano Zampini /* Apply transpose of partition of unity operator */ 216150efa1b5SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 216250efa1b5SStefano Zampini 216350efa1b5SStefano Zampini /* Second Dirichlet solve and assembling of output */ 216450efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 216550efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2166b097fa66SStefano Zampini if (n_B) { 216716909a7fSStefano Zampini if (pcbddc->switch_static) { 216816909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 216916909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 217016909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 217116909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 217216909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 2173b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 217416909a7fSStefano Zampini } else { 217516909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 2176b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 217716909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 217816909a7fSStefano Zampini } 217916909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 218016909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 218116909a7fSStefano Zampini } else { 218250efa1b5SStefano Zampini ierr = MatMultTranspose(pcis->A_BI,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 218316909a7fSStefano Zampini } 218416909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 218516909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 2186b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 218716909a7fSStefano Zampini } else { 218816909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 2189b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 219016909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 219116909a7fSStefano Zampini } 2192b097fa66SStefano Zampini } 219355c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 2194b0147a47SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 219555c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 2196c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec4_D);CHKERRQ(ierr); 21978ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2198b097fa66SStefano Zampini if (pcbddc->switch_static) { 2199b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 2200b097fa66SStefano Zampini } else { 2201b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 2202b097fa66SStefano Zampini } 220350efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 220450efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2205b097fa66SStefano Zampini } else { 2206b097fa66SStefano Zampini if (pcbddc->switch_static) { 2207b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 2208b097fa66SStefano Zampini } else { 2209b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 2210b097fa66SStefano Zampini } 2211b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2212b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2213b097fa66SStefano Zampini } 221427b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 2215537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 2216537c1cdfSStefano Zampini } 22171dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2218f913dca9SStefano Zampini pcbddc->work_change = r; 22191dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 22201dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 22211dd7afcfSStefano Zampini } 222250efa1b5SStefano Zampini PetscFunctionReturn(0); 222350efa1b5SStefano Zampini } 2224674ae819SStefano Zampini 22259326c5c6Sstefano_zampini PetscErrorCode PCReset_BDDC(PC pc) 2226da1bb401SStefano Zampini { 2227da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 22289326c5c6Sstefano_zampini PC_IS *pcis = (PC_IS*)pc->data; 22299326c5c6Sstefano_zampini KSP kspD,kspR,kspC; 2230da1bb401SStefano Zampini PetscErrorCode ierr; 2231da1bb401SStefano Zampini 2232da1bb401SStefano Zampini PetscFunctionBegin; 2233674ae819SStefano Zampini /* free BDDC custom data */ 2234674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 2235674ae819SStefano Zampini /* destroy objects related to topography */ 2236674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 223734a97f8cSStefano Zampini /* destroy objects for scaling operator */ 2238674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 2239674ae819SStefano Zampini /* free solvers stuff */ 2240674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 224162a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 224262a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 224362a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 22441dd7afcfSStefano Zampini /* free data created by PCIS */ 22451dd7afcfSStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 22469326c5c6Sstefano_zampini 22479326c5c6Sstefano_zampini /* restore defaults */ 22489326c5c6Sstefano_zampini kspD = pcbddc->ksp_D; 22499326c5c6Sstefano_zampini kspR = pcbddc->ksp_R; 22509326c5c6Sstefano_zampini kspC = pcbddc->coarse_ksp; 22519326c5c6Sstefano_zampini ierr = PetscMemzero(pc->data,sizeof(*pcbddc));CHKERRQ(ierr); 22529326c5c6Sstefano_zampini pcis->n_neigh = -1; 22539326c5c6Sstefano_zampini pcis->scaling_factor = 1.0; 22549326c5c6Sstefano_zampini pcis->reusesubmatrices = PETSC_TRUE; 22559326c5c6Sstefano_zampini pcbddc->use_local_adj = PETSC_TRUE; 22569326c5c6Sstefano_zampini pcbddc->use_vertices = PETSC_TRUE; 22579326c5c6Sstefano_zampini pcbddc->use_edges = PETSC_TRUE; 22589326c5c6Sstefano_zampini pcbddc->symmetric_primal = PETSC_TRUE; 22599326c5c6Sstefano_zampini pcbddc->vertex_size = 1; 22609326c5c6Sstefano_zampini pcbddc->recompute_topography = PETSC_TRUE; 22619326c5c6Sstefano_zampini pcbddc->coarse_size = -1; 22629326c5c6Sstefano_zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 22639326c5c6Sstefano_zampini pcbddc->coarsening_ratio = 8; 22649326c5c6Sstefano_zampini pcbddc->coarse_eqs_per_proc = 1; 22659326c5c6Sstefano_zampini pcbddc->benign_compute_correction = PETSC_TRUE; 22669326c5c6Sstefano_zampini pcbddc->nedfield = -1; 22679326c5c6Sstefano_zampini pcbddc->nedglobal = PETSC_TRUE; 22689326c5c6Sstefano_zampini pcbddc->graphmaxcount = PETSC_MAX_INT; 22699326c5c6Sstefano_zampini pcbddc->sub_schurs_layers = -1; 22709326c5c6Sstefano_zampini pcbddc->ksp_D = kspD; 22719326c5c6Sstefano_zampini pcbddc->ksp_R = kspR; 22729326c5c6Sstefano_zampini pcbddc->coarse_ksp = kspC; 22739326c5c6Sstefano_zampini PetscFunctionReturn(0); 22749326c5c6Sstefano_zampini } 22759326c5c6Sstefano_zampini 22769326c5c6Sstefano_zampini PetscErrorCode PCDestroy_BDDC(PC pc) 22779326c5c6Sstefano_zampini { 22789326c5c6Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 22799326c5c6Sstefano_zampini PetscErrorCode ierr; 22809326c5c6Sstefano_zampini 22819326c5c6Sstefano_zampini PetscFunctionBegin; 22829326c5c6Sstefano_zampini ierr = PCReset_BDDC(pc);CHKERRQ(ierr); 22839326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 22849326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 22859326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 2286a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",NULL);CHKERRQ(ierr); 2287a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",NULL);CHKERRQ(ierr); 2288906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",NULL);CHKERRQ(ierr); 2289674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 229030368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",NULL);CHKERRQ(ierr); 2291bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 22922b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr); 2293b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr); 22942b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr); 2295bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 229682ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2297bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 229882ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2299bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 230082ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2301bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 2302785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2303bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 230463602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",NULL);CHKERRQ(ierr); 2305bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 2306bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 2307bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 2308bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 2309a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",NULL);CHKERRQ(ierr); 2310ab8c8b98SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",NULL);CHKERRQ(ierr); 2311674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 2312da1bb401SStefano Zampini PetscFunctionReturn(0); 2313da1bb401SStefano Zampini } 23141e6b0712SBarry Smith 2315ab8c8b98SStefano Zampini static PetscErrorCode PCSetCoordinates_BDDC(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 2316ab8c8b98SStefano Zampini { 2317ab8c8b98SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2318ab8c8b98SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 2319ab8c8b98SStefano Zampini PetscErrorCode ierr; 2320ab8c8b98SStefano Zampini 2321ab8c8b98SStefano Zampini PetscFunctionBegin; 2322ab8c8b98SStefano Zampini ierr = PetscFree(mat_graph->coords);CHKERRQ(ierr); 2323ab8c8b98SStefano Zampini ierr = PetscMalloc1(nloc*dim,&mat_graph->coords);CHKERRQ(ierr); 2324580bdb30SBarry Smith ierr = PetscArraycpy(mat_graph->coords,coords,nloc*dim);CHKERRQ(ierr); 2325ab8c8b98SStefano Zampini mat_graph->cnloc = nloc; 2326ab8c8b98SStefano Zampini mat_graph->cdim = dim; 2327ab8c8b98SStefano Zampini mat_graph->cloc = PETSC_FALSE; 23284f819b78SStefano Zampini /* flg setup */ 23294f819b78SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 23304f819b78SStefano Zampini pcbddc->corner_selected = PETSC_FALSE; 2331ab8c8b98SStefano Zampini PetscFunctionReturn(0); 2332ab8c8b98SStefano Zampini } 2333ab8c8b98SStefano Zampini 2334a06fd7f2SStefano Zampini static PetscErrorCode PCPreSolveChangeRHS_BDDC(PC pc, PetscBool* change) 2335a06fd7f2SStefano Zampini { 2336a06fd7f2SStefano Zampini PetscFunctionBegin; 2337a06fd7f2SStefano Zampini *change = PETSC_TRUE; 2338a06fd7f2SStefano Zampini PetscFunctionReturn(0); 2339a06fd7f2SStefano Zampini } 2340a06fd7f2SStefano Zampini 23413425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 23423425bc38SStefano Zampini { 2343674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 2344266e20e9SStefano Zampini Vec work; 23453425bc38SStefano Zampini PC_IS* pcis; 23463425bc38SStefano Zampini PC_BDDC* pcbddc; 23473425bc38SStefano Zampini PetscErrorCode ierr; 23480c7d97c5SJed Brown 23493425bc38SStefano Zampini PetscFunctionBegin; 23503425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 23513425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 23523425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 23533425bc38SStefano Zampini 2354229984c5Sstefano_zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 2355229984c5Sstefano_zampini /* copy rhs since we may change it during PCPreSolve_BDDC */ 2356229984c5Sstefano_zampini if (!pcbddc->original_rhs) { 2357229984c5Sstefano_zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 2358229984c5Sstefano_zampini } 23596cc1294bSstefano_zampini if (mat_ctx->rhs_flip) { 23606cc1294bSstefano_zampini ierr = VecPointwiseMult(pcbddc->original_rhs,standard_rhs,mat_ctx->rhs_flip);CHKERRQ(ierr); 23616cc1294bSstefano_zampini } else { 2362229984c5Sstefano_zampini ierr = VecCopy(standard_rhs,pcbddc->original_rhs);CHKERRQ(ierr); 23636cc1294bSstefano_zampini } 2364af140850Sstefano_zampini if (mat_ctx->g2g_p) { 2365229984c5Sstefano_zampini /* interface pressure rhs */ 2366022d8d2bSstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,fetidp_flux_rhs,pcbddc->original_rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2367022d8d2bSstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,fetidp_flux_rhs,pcbddc->original_rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2368229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,standard_rhs,fetidp_flux_rhs,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2369229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,standard_rhs,fetidp_flux_rhs,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23706cc1294bSstefano_zampini if (!mat_ctx->rhs_flip) { 2371229984c5Sstefano_zampini ierr = VecScale(fetidp_flux_rhs,-1.);CHKERRQ(ierr); 2372229984c5Sstefano_zampini } 23736cc1294bSstefano_zampini } 2374c08af4c6SStefano Zampini /* 2375c08af4c6SStefano Zampini change of basis for physical rhs if needed 2376c08af4c6SStefano Zampini It also changes the rhs in case of dirichlet boundaries 2377c08af4c6SStefano Zampini */ 23783738a8e6SStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,pcbddc->original_rhs,NULL);CHKERRQ(ierr); 2379fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 23803738a8e6SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcbddc->original_rhs,pcbddc->work_change);CHKERRQ(ierr); 23813738a8e6SStefano Zampini work = pcbddc->work_change; 2382fc17d649SStefano Zampini } else { 23833738a8e6SStefano Zampini work = pcbddc->original_rhs; 2384fc17d649SStefano Zampini } 23853425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 2386266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2387266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2388fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 2389fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 2390266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2391266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2392674ae819SStefano Zampini /* Apply partition of unity */ 23933425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 2394266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 23958eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 23963425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 239755c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][0],mat_ctx->pc,0,0,0);CHKERRQ(ierr); 23983425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 239955c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][0],mat_ctx->pc,0,0,0);CHKERRQ(ierr); 2400c0decd05SBarry Smith /* Cannot propagate up error in KSPSolve() because there is no access to the PC */ 24013425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 24023425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 2403266e20e9SStefano Zampini ierr = VecSet(work,0.0);CHKERRQ(ierr); 2404266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2405266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2406266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 2407266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2408266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 24093425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 24103425bc38SStefano Zampini } 24113425bc38SStefano Zampini /* BDDC rhs */ 24123425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 24138eeda7d8SStefano Zampini if (pcbddc->switch_static) { 24143425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 24153425bc38SStefano Zampini } 24163425bc38SStefano Zampini /* apply BDDC */ 2417580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->benign_p0,pcbddc->benign_n);CHKERRQ(ierr); 2418dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2419580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->benign_p0,pcbddc->benign_n);CHKERRQ(ierr); 2420229984c5Sstefano_zampini 24213425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 24223425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 24233425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 24243425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2425229984c5Sstefano_zampini /* Add contribution to interface pressures */ 2426229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2427229984c5Sstefano_zampini ierr = MatMult(mat_ctx->B_BB,pcis->vec1_B,mat_ctx->vP);CHKERRQ(ierr); 2428229984c5Sstefano_zampini if (pcbddc->switch_static) { 2429229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->B_BI,pcis->vec1_D,mat_ctx->vP,mat_ctx->vP);CHKERRQ(ierr); 2430229984c5Sstefano_zampini } 2431229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->l2g_p,mat_ctx->vP,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2432229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->l2g_p,mat_ctx->vP,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2433229984c5Sstefano_zampini } 24343425bc38SStefano Zampini PetscFunctionReturn(0); 24353425bc38SStefano Zampini } 24361e6b0712SBarry Smith 24373425bc38SStefano Zampini /*@ 24380f202f7eSStefano Zampini PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETI-DP linear system using the physical right-hand side 24393425bc38SStefano Zampini 24403425bc38SStefano Zampini Collective 24413425bc38SStefano Zampini 24423425bc38SStefano Zampini Input Parameters: 24430f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix object obtained by a call to PCBDDCCreateFETIDPOperators 24440f202f7eSStefano Zampini - standard_rhs - the right-hand side of the original linear system 24453425bc38SStefano Zampini 24463425bc38SStefano Zampini Output Parameters: 24470f202f7eSStefano Zampini . fetidp_flux_rhs - the right-hand side for the FETI-DP linear system 24483425bc38SStefano Zampini 24493425bc38SStefano Zampini Level: developer 24503425bc38SStefano Zampini 24513425bc38SStefano Zampini Notes: 24523425bc38SStefano Zampini 24530f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetSolution 24543425bc38SStefano Zampini @*/ 24553425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 24563425bc38SStefano Zampini { 2457674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 24583425bc38SStefano Zampini PetscErrorCode ierr; 24593425bc38SStefano Zampini 24603425bc38SStefano Zampini PetscFunctionBegin; 2461266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2462266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_rhs,VEC_CLASSID,2); 2463266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_rhs,VEC_CLASSID,3); 24643425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2465163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 24663425bc38SStefano Zampini PetscFunctionReturn(0); 24673425bc38SStefano Zampini } 24681e6b0712SBarry Smith 24693425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 24703425bc38SStefano Zampini { 2471674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 24723425bc38SStefano Zampini PC_IS* pcis; 24733425bc38SStefano Zampini PC_BDDC* pcbddc; 24743425bc38SStefano Zampini PetscErrorCode ierr; 2475229984c5Sstefano_zampini Vec work; 24763425bc38SStefano Zampini 24773425bc38SStefano Zampini PetscFunctionBegin; 24783425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 24793425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 24803425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 24813425bc38SStefano Zampini 24823425bc38SStefano Zampini /* apply B_delta^T */ 2483af140850Sstefano_zampini ierr = VecSet(pcis->vec1_B,0.);CHKERRQ(ierr); 24843425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24853425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24863425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 2487229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2488229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->l2g_p,fetidp_flux_sol,mat_ctx->vP,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2489229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->l2g_p,fetidp_flux_sol,mat_ctx->vP,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2490229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->Bt_BB,mat_ctx->vP,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 2491229984c5Sstefano_zampini } 2492229984c5Sstefano_zampini 24933425bc38SStefano Zampini /* compute rhs for BDDC application */ 24943425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 24958eeda7d8SStefano Zampini if (pcbddc->switch_static) { 24963425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 2497229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2498229984c5Sstefano_zampini ierr = VecScale(mat_ctx->vP,-1.);CHKERRQ(ierr); 2499229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->Bt_BI,mat_ctx->vP,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); 25003425bc38SStefano Zampini } 2501229984c5Sstefano_zampini } 2502229984c5Sstefano_zampini 25033425bc38SStefano Zampini /* apply BDDC */ 2504580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->benign_p0,pcbddc->benign_n);CHKERRQ(ierr); 2505dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2506229984c5Sstefano_zampini 2507229984c5Sstefano_zampini /* put values into global vector */ 2508af140850Sstefano_zampini if (pcbddc->ChangeOfBasisMatrix) work = pcbddc->work_change; 2509af140850Sstefano_zampini else work = standard_sol; 2510229984c5Sstefano_zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2511229984c5Sstefano_zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 25128eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 25133425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 25143425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 251500f6b531SStefano Zampini ierr = VecAYPX(pcis->vec1_D,-1.0,mat_ctx->temp_solution_D);CHKERRQ(ierr); 251655c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][0],mat_ctx->pc,0,0,0);CHKERRQ(ierr); 251700f6b531SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); 251855c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][0],mat_ctx->pc,0,0,0);CHKERRQ(ierr); 2519c0decd05SBarry Smith /* Cannot propagate up error in KSPSolve() because there is no access to the PC */ 25203425bc38SStefano Zampini } 2521229984c5Sstefano_zampini 2522229984c5Sstefano_zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2523229984c5Sstefano_zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_D,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2524266e20e9SStefano Zampini /* add p0 solution to final solution */ 2525229984c5Sstefano_zampini ierr = PCBDDCBenignGetOrSetP0(mat_ctx->pc,work,PETSC_FALSE);CHKERRQ(ierr); 2526fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2527af140850Sstefano_zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,work,standard_sol);CHKERRQ(ierr); 2528fc17d649SStefano Zampini } 2529af140850Sstefano_zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 2530af140850Sstefano_zampini if (mat_ctx->g2g_p) { 2531229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,fetidp_flux_sol,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2532229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,fetidp_flux_sol,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2533229984c5Sstefano_zampini } 25343425bc38SStefano Zampini PetscFunctionReturn(0); 25353425bc38SStefano Zampini } 25361e6b0712SBarry Smith 25375a1e936bSStefano Zampini static PetscErrorCode PCView_BDDCIPC(PC pc, PetscViewer viewer) 25385a1e936bSStefano Zampini { 25395a1e936bSStefano Zampini PetscErrorCode ierr; 25405a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25415a1e936bSStefano Zampini PetscBool isascii; 25425a1e936bSStefano Zampini 25435a1e936bSStefano Zampini PetscFunctionBegin; 25443ec1f749SStefano Zampini ierr = PCShellGetContext(pc,&bddcipc_ctx);CHKERRQ(ierr); 25455a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 25465a1e936bSStefano Zampini if (isascii) { 25475a1e936bSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"BDDC interface preconditioner\n");CHKERRQ(ierr); 25485a1e936bSStefano Zampini } 25495a1e936bSStefano Zampini ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 25505a1e936bSStefano Zampini ierr = PCView(bddcipc_ctx->bddc,viewer);CHKERRQ(ierr); 25515a1e936bSStefano Zampini ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 25525a1e936bSStefano Zampini PetscFunctionReturn(0); 25535a1e936bSStefano Zampini } 25545a1e936bSStefano Zampini 25555a1e936bSStefano Zampini static PetscErrorCode PCSetUp_BDDCIPC(PC pc) 25565a1e936bSStefano Zampini { 25575a1e936bSStefano Zampini PetscErrorCode ierr; 25585a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25595a1e936bSStefano Zampini PetscBool isbddc; 25605a1e936bSStefano Zampini Vec vv; 25615a1e936bSStefano Zampini IS is; 25625a1e936bSStefano Zampini PC_IS *pcis; 25635a1e936bSStefano Zampini 25645a1e936bSStefano Zampini PetscFunctionBegin; 25653ec1f749SStefano Zampini ierr = PCShellGetContext(pc,&bddcipc_ctx);CHKERRQ(ierr); 25665a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)bddcipc_ctx->bddc,PCBDDC,&isbddc);CHKERRQ(ierr); 25672c71b3e2SJacob Faibussowitsch PetscCheckFalse(!isbddc,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid type %s. Must be of type bddc",((PetscObject)bddcipc_ctx->bddc)->type_name); 25685a1e936bSStefano Zampini ierr = PCSetUp(bddcipc_ctx->bddc);CHKERRQ(ierr); 25695a1e936bSStefano Zampini 25705a1e936bSStefano Zampini /* create interface scatter */ 25715a1e936bSStefano Zampini pcis = (PC_IS*)(bddcipc_ctx->bddc->data); 25725a1e936bSStefano Zampini ierr = VecScatterDestroy(&bddcipc_ctx->g2l);CHKERRQ(ierr); 25735a1e936bSStefano Zampini ierr = MatCreateVecs(pc->pmat,&vv,NULL);CHKERRQ(ierr); 25745a1e936bSStefano Zampini ierr = ISRenumber(pcis->is_B_global,NULL,NULL,&is);CHKERRQ(ierr); 25759448b7f1SJunchao Zhang ierr = VecScatterCreate(vv,is,pcis->vec1_B,NULL,&bddcipc_ctx->g2l);CHKERRQ(ierr); 25765a1e936bSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 25775a1e936bSStefano Zampini ierr = VecDestroy(&vv);CHKERRQ(ierr); 25785a1e936bSStefano Zampini PetscFunctionReturn(0); 25795a1e936bSStefano Zampini } 25805a1e936bSStefano Zampini 25815a1e936bSStefano Zampini static PetscErrorCode PCApply_BDDCIPC(PC pc, Vec r, Vec x) 25825a1e936bSStefano Zampini { 25835a1e936bSStefano Zampini PetscErrorCode ierr; 25845a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25855a1e936bSStefano Zampini PC_IS *pcis; 25865a1e936bSStefano Zampini VecScatter tmps; 25875a1e936bSStefano Zampini 25885a1e936bSStefano Zampini PetscFunctionBegin; 25893ec1f749SStefano Zampini ierr = PCShellGetContext(pc,&bddcipc_ctx);CHKERRQ(ierr); 25905a1e936bSStefano Zampini pcis = (PC_IS*)(bddcipc_ctx->bddc->data); 25915a1e936bSStefano Zampini tmps = pcis->global_to_B; 25925a1e936bSStefano Zampini pcis->global_to_B = bddcipc_ctx->g2l; 25935a1e936bSStefano Zampini ierr = PCBDDCScalingRestriction(bddcipc_ctx->bddc,r,pcis->vec1_B);CHKERRQ(ierr); 25945a1e936bSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(bddcipc_ctx->bddc,PETSC_FALSE);CHKERRQ(ierr); 25955a1e936bSStefano Zampini ierr = PCBDDCScalingExtension(bddcipc_ctx->bddc,pcis->vec1_B,x);CHKERRQ(ierr); 25965a1e936bSStefano Zampini pcis->global_to_B = tmps; 25975a1e936bSStefano Zampini PetscFunctionReturn(0); 25985a1e936bSStefano Zampini } 25995a1e936bSStefano Zampini 26005a1e936bSStefano Zampini static PetscErrorCode PCApplyTranspose_BDDCIPC(PC pc, Vec r, Vec x) 26015a1e936bSStefano Zampini { 26025a1e936bSStefano Zampini PetscErrorCode ierr; 26035a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 26045a1e936bSStefano Zampini PC_IS *pcis; 26055a1e936bSStefano Zampini VecScatter tmps; 26065a1e936bSStefano Zampini 26075a1e936bSStefano Zampini PetscFunctionBegin; 26083ec1f749SStefano Zampini ierr = PCShellGetContext(pc,&bddcipc_ctx);CHKERRQ(ierr); 26095a1e936bSStefano Zampini pcis = (PC_IS*)(bddcipc_ctx->bddc->data); 26105a1e936bSStefano Zampini tmps = pcis->global_to_B; 26115a1e936bSStefano Zampini pcis->global_to_B = bddcipc_ctx->g2l; 26125a1e936bSStefano Zampini ierr = PCBDDCScalingRestriction(bddcipc_ctx->bddc,r,pcis->vec1_B);CHKERRQ(ierr); 26135a1e936bSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(bddcipc_ctx->bddc,PETSC_TRUE);CHKERRQ(ierr); 26145a1e936bSStefano Zampini ierr = PCBDDCScalingExtension(bddcipc_ctx->bddc,pcis->vec1_B,x);CHKERRQ(ierr); 26155a1e936bSStefano Zampini pcis->global_to_B = tmps; 26165a1e936bSStefano Zampini PetscFunctionReturn(0); 26175a1e936bSStefano Zampini } 26185a1e936bSStefano Zampini 26195a1e936bSStefano Zampini static PetscErrorCode PCDestroy_BDDCIPC(PC pc) 26205a1e936bSStefano Zampini { 26215a1e936bSStefano Zampini PetscErrorCode ierr; 26225a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 26235a1e936bSStefano Zampini 26245a1e936bSStefano Zampini PetscFunctionBegin; 26253ec1f749SStefano Zampini ierr = PCShellGetContext(pc,&bddcipc_ctx);CHKERRQ(ierr); 26265a1e936bSStefano Zampini ierr = PCDestroy(&bddcipc_ctx->bddc);CHKERRQ(ierr); 26275a1e936bSStefano Zampini ierr = VecScatterDestroy(&bddcipc_ctx->g2l);CHKERRQ(ierr); 26285a1e936bSStefano Zampini ierr = PetscFree(bddcipc_ctx);CHKERRQ(ierr); 26295a1e936bSStefano Zampini PetscFunctionReturn(0); 26305a1e936bSStefano Zampini } 26315a1e936bSStefano Zampini 26323425bc38SStefano Zampini /*@ 26330f202f7eSStefano Zampini PCBDDCMatFETIDPGetSolution - Compute the physical solution using the solution of the FETI-DP linear system 26343425bc38SStefano Zampini 26353425bc38SStefano Zampini Collective 26363425bc38SStefano Zampini 26373425bc38SStefano Zampini Input Parameters: 26380f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix obtained by a call to PCBDDCCreateFETIDPOperators 26390f202f7eSStefano Zampini - fetidp_flux_sol - the solution of the FETI-DP linear system 26403425bc38SStefano Zampini 26413425bc38SStefano Zampini Output Parameters: 26420f202f7eSStefano Zampini . standard_sol - the solution defined on the physical domain 26433425bc38SStefano Zampini 26443425bc38SStefano Zampini Level: developer 26453425bc38SStefano Zampini 26463425bc38SStefano Zampini Notes: 26473425bc38SStefano Zampini 26480f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetRHS 26493425bc38SStefano Zampini @*/ 26503425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 26513425bc38SStefano Zampini { 2652674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 26533425bc38SStefano Zampini PetscErrorCode ierr; 26543425bc38SStefano Zampini 26553425bc38SStefano Zampini PetscFunctionBegin; 2656266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2657266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_sol,VEC_CLASSID,2); 2658266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_sol,VEC_CLASSID,3); 26593425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2660163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 26613425bc38SStefano Zampini PetscFunctionReturn(0); 26623425bc38SStefano Zampini } 26631e6b0712SBarry Smith 2664547c9a8eSstefano_zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, PetscBool fully_redundant, const char* prefix, Mat *fetidp_mat, PC *fetidp_pc) 26653425bc38SStefano Zampini { 2666674ae819SStefano Zampini 2667674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 26683425bc38SStefano Zampini Mat newmat; 2669674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 26703425bc38SStefano Zampini PC newpc; 2671ce94432eSBarry Smith MPI_Comm comm; 26723425bc38SStefano Zampini PetscErrorCode ierr; 26733425bc38SStefano Zampini 26743425bc38SStefano Zampini PetscFunctionBegin; 2675ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 267615579a77SStefano Zampini /* FETI-DP matrix */ 26773425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 26781720468bSStefano Zampini fetidpmat_ctx->fully_redundant = fully_redundant; 26793425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 2680a5bb87b3Sstefano_zampini ierr = MatCreateShell(comm,fetidpmat_ctx->n,fetidpmat_ctx->n,fetidpmat_ctx->N,fetidpmat_ctx->N,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 268115579a77SStefano Zampini ierr = PetscObjectSetName((PetscObject)newmat,!fetidpmat_ctx->l2g_lambda_only ? "F" : "G");CHKERRQ(ierr); 26823425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 2683edf7251bSStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT_TRANSPOSE,(void (*)(void))FETIDPMatMultTranspose);CHKERRQ(ierr); 26843425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 268515579a77SStefano Zampini /* propagate MatOptions */ 268615579a77SStefano Zampini { 268715579a77SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)fetidpmat_ctx->pc->data; 268815579a77SStefano Zampini PetscBool issym; 268915579a77SStefano Zampini 269015579a77SStefano Zampini ierr = MatGetOption(pc->mat,MAT_SYMMETRIC,&issym);CHKERRQ(ierr); 269115579a77SStefano Zampini if (issym || pcbddc->symmetric_primal) { 269215579a77SStefano Zampini ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 269315579a77SStefano Zampini } 269415579a77SStefano Zampini } 2695547c9a8eSstefano_zampini ierr = MatSetOptionsPrefix(newmat,prefix);CHKERRQ(ierr); 2696547c9a8eSstefano_zampini ierr = MatAppendOptionsPrefix(newmat,"fetidp_");CHKERRQ(ierr); 26973425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 269815579a77SStefano Zampini /* FETI-DP preconditioner */ 26993425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 27003425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 27013425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 2702e1214c54Sstefano_zampini ierr = PCSetOperators(newpc,newmat,newmat);CHKERRQ(ierr); 2703e1214c54Sstefano_zampini ierr = PCSetOptionsPrefix(newpc,prefix);CHKERRQ(ierr); 2704e1214c54Sstefano_zampini ierr = PCAppendOptionsPrefix(newpc,"fetidp_");CHKERRQ(ierr); 2705399ffe99SStefano Zampini ierr = PCSetErrorIfFailure(newpc,pc->erroriffailure);CHKERRQ(ierr); 270615579a77SStefano Zampini if (!fetidpmat_ctx->l2g_lambda_only) { /* standard FETI-DP */ 27073425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 270815579a77SStefano Zampini ierr = PCShellSetName(newpc,"FETI-DP multipliers");CHKERRQ(ierr); 27093425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 27103425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 2711edf7251bSStefano Zampini ierr = PCShellSetApplyTranspose(newpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 2712c45b8d2dSstefano_zampini ierr = PCShellSetView(newpc,FETIDPPCView);CHKERRQ(ierr); 27133425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 27145a1e936bSStefano Zampini } else { /* saddle-point FETI-DP */ 27155a1e936bSStefano Zampini Mat M; 27165a1e936bSStefano Zampini PetscInt psize; 27175a1e936bSStefano Zampini PetscBool fake = PETSC_FALSE, isfieldsplit; 2718e1214c54Sstefano_zampini 271915579a77SStefano Zampini ierr = ISViewFromOptions(fetidpmat_ctx->lagrange,NULL,"-lag_view");CHKERRQ(ierr); 272015579a77SStefano Zampini ierr = ISViewFromOptions(fetidpmat_ctx->pressure,NULL,"-press_view");CHKERRQ(ierr); 2721e1214c54Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_PPmat",(PetscObject*)&M);CHKERRQ(ierr); 2722e1214c54Sstefano_zampini ierr = PCSetType(newpc,PCFIELDSPLIT);CHKERRQ(ierr); 2723e1214c54Sstefano_zampini ierr = PCFieldSplitSetIS(newpc,"lag",fetidpmat_ctx->lagrange);CHKERRQ(ierr); 2724e1214c54Sstefano_zampini ierr = PCFieldSplitSetIS(newpc,"p",fetidpmat_ctx->pressure);CHKERRQ(ierr); 2725e1214c54Sstefano_zampini ierr = PCFieldSplitSetType(newpc,PC_COMPOSITE_SCHUR);CHKERRQ(ierr); 272640c75d76SStefano Zampini ierr = PCFieldSplitSetSchurFactType(newpc,PC_FIELDSPLIT_SCHUR_FACT_DIAG);CHKERRQ(ierr); 27275a1e936bSStefano Zampini ierr = ISGetSize(fetidpmat_ctx->pressure,&psize);CHKERRQ(ierr); 27285a1e936bSStefano Zampini if (psize != M->rmap->N) { 27295a1e936bSStefano Zampini Mat M2; 27305a1e936bSStefano Zampini PetscInt lpsize; 27315a1e936bSStefano Zampini 27325a1e936bSStefano Zampini fake = PETSC_TRUE; 27335a1e936bSStefano Zampini ierr = ISGetLocalSize(fetidpmat_ctx->pressure,&lpsize);CHKERRQ(ierr); 27345a1e936bSStefano Zampini ierr = MatCreate(comm,&M2);CHKERRQ(ierr); 27355a1e936bSStefano Zampini ierr = MatSetType(M2,MATAIJ);CHKERRQ(ierr); 27365a1e936bSStefano Zampini ierr = MatSetSizes(M2,lpsize,lpsize,psize,psize);CHKERRQ(ierr); 27375a1e936bSStefano Zampini ierr = MatSetUp(M2);CHKERRQ(ierr); 27385a1e936bSStefano Zampini ierr = MatAssemblyBegin(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27395a1e936bSStefano Zampini ierr = MatAssemblyEnd(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27405a1e936bSStefano Zampini ierr = PCFieldSplitSetSchurPre(newpc,PC_FIELDSPLIT_SCHUR_PRE_USER,M2);CHKERRQ(ierr); 27415a1e936bSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 27425a1e936bSStefano Zampini } else { 2743e1214c54Sstefano_zampini ierr = PCFieldSplitSetSchurPre(newpc,PC_FIELDSPLIT_SCHUR_PRE_USER,M);CHKERRQ(ierr); 27445a1e936bSStefano Zampini } 2745c096484dSStefano Zampini ierr = PCFieldSplitSetSchurScale(newpc,1.0);CHKERRQ(ierr); 274615579a77SStefano Zampini 274715579a77SStefano Zampini /* we need to setfromoptions and setup here to access the blocks */ 2748e1214c54Sstefano_zampini ierr = PCSetFromOptions(newpc);CHKERRQ(ierr); 2749e1214c54Sstefano_zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 2750e1214c54Sstefano_zampini 27515a1e936bSStefano Zampini /* user may have changed the type (e.g. -fetidp_pc_type none) */ 27525a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)newpc,PCFIELDSPLIT,&isfieldsplit);CHKERRQ(ierr); 27535a1e936bSStefano Zampini if (isfieldsplit) { 27545a1e936bSStefano Zampini KSP *ksps; 27555a1e936bSStefano Zampini PC ppc,lagpc; 27565a1e936bSStefano Zampini PetscInt nn; 2757064a4176SStefano Zampini PetscBool ismatis,matisok = PETSC_FALSE,check = PETSC_FALSE; 27585a1e936bSStefano Zampini 2759e1214c54Sstefano_zampini /* set the solver for the (0,0) block */ 27605a1e936bSStefano Zampini ierr = PCFieldSplitSchurGetSubKSP(newpc,&nn,&ksps);CHKERRQ(ierr); 27615a1e936bSStefano Zampini if (!nn) { /* not of type PC_COMPOSITE_SCHUR */ 276240c75d76SStefano Zampini ierr = PCFieldSplitGetSubKSP(newpc,&nn,&ksps);CHKERRQ(ierr); 27635a1e936bSStefano Zampini if (!fake) { /* pass pmat to the pressure solver */ 27645a1e936bSStefano Zampini Mat F; 27655a1e936bSStefano Zampini 27665a1e936bSStefano Zampini ierr = KSPGetOperators(ksps[1],&F,NULL);CHKERRQ(ierr); 27675a1e936bSStefano Zampini ierr = KSPSetOperators(ksps[1],F,M);CHKERRQ(ierr); 27685a1e936bSStefano Zampini } 27695a1e936bSStefano Zampini } else { 27705a1e936bSStefano Zampini PetscBool issym; 27715a1e936bSStefano Zampini Mat S; 27725a1e936bSStefano Zampini 27735a1e936bSStefano Zampini ierr = PCFieldSplitSchurGetS(newpc,&S);CHKERRQ(ierr); 27745a1e936bSStefano Zampini 27755a1e936bSStefano Zampini ierr = MatGetOption(newmat,MAT_SYMMETRIC,&issym);CHKERRQ(ierr); 27765a1e936bSStefano Zampini if (issym) { 27775a1e936bSStefano Zampini ierr = MatSetOption(S,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 27785a1e936bSStefano Zampini } 27795a1e936bSStefano Zampini } 27805a1e936bSStefano Zampini ierr = KSPGetPC(ksps[0],&lagpc);CHKERRQ(ierr); 2781e1214c54Sstefano_zampini ierr = PCSetType(lagpc,PCSHELL);CHKERRQ(ierr); 27825a1e936bSStefano Zampini ierr = PCShellSetName(lagpc,"FETI-DP multipliers");CHKERRQ(ierr); 2783e1214c54Sstefano_zampini ierr = PCShellSetContext(lagpc,fetidppc_ctx);CHKERRQ(ierr); 2784e1214c54Sstefano_zampini ierr = PCShellSetApply(lagpc,FETIDPPCApply);CHKERRQ(ierr); 2785e1214c54Sstefano_zampini ierr = PCShellSetApplyTranspose(lagpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 2786e1214c54Sstefano_zampini ierr = PCShellSetView(lagpc,FETIDPPCView);CHKERRQ(ierr); 2787e1214c54Sstefano_zampini ierr = PCShellSetDestroy(lagpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 27885a1e936bSStefano Zampini 27895a1e936bSStefano Zampini /* Olof's idea: interface Schur complement preconditioner for the mass matrix */ 27905a1e936bSStefano Zampini ierr = KSPGetPC(ksps[1],&ppc);CHKERRQ(ierr); 27915a1e936bSStefano Zampini if (fake) { 27925a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 2793ff11fd76SStefano Zampini PetscContainer c; 27945a1e936bSStefano Zampini 27955a1e936bSStefano Zampini matisok = PETSC_TRUE; 27965a1e936bSStefano Zampini 27975a1e936bSStefano Zampini /* create inner BDDC solver */ 27985a1e936bSStefano Zampini ierr = PetscNew(&bddcipc_ctx);CHKERRQ(ierr); 27995a1e936bSStefano Zampini ierr = PCCreate(comm,&bddcipc_ctx->bddc);CHKERRQ(ierr); 28005a1e936bSStefano Zampini ierr = PCSetType(bddcipc_ctx->bddc,PCBDDC);CHKERRQ(ierr); 28015a1e936bSStefano Zampini ierr = PCSetOperators(bddcipc_ctx->bddc,M,M);CHKERRQ(ierr); 2802ff11fd76SStefano Zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_pCSR",(PetscObject*)&c);CHKERRQ(ierr); 2803ff11fd76SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)M,MATIS,&ismatis);CHKERRQ(ierr); 2804ff11fd76SStefano Zampini if (c && ismatis) { 2805ff11fd76SStefano Zampini Mat lM; 2806ff11fd76SStefano Zampini PetscInt *csr,n; 2807ff11fd76SStefano Zampini 2808ff11fd76SStefano Zampini ierr = MatISGetLocalMat(M,&lM);CHKERRQ(ierr); 2809ff11fd76SStefano Zampini ierr = MatGetSize(lM,&n,NULL);CHKERRQ(ierr); 2810ff11fd76SStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&csr);CHKERRQ(ierr); 2811ff11fd76SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(bddcipc_ctx->bddc,n,csr,csr + (n + 1),PETSC_COPY_VALUES);CHKERRQ(ierr); 2812ff11fd76SStefano Zampini ierr = MatISRestoreLocalMat(M,&lM);CHKERRQ(ierr); 2813ff11fd76SStefano Zampini } 28145a1e936bSStefano Zampini ierr = PCSetOptionsPrefix(bddcipc_ctx->bddc,((PetscObject)ksps[1])->prefix);CHKERRQ(ierr); 28155a1e936bSStefano Zampini ierr = PCSetErrorIfFailure(bddcipc_ctx->bddc,pc->erroriffailure);CHKERRQ(ierr); 28165a1e936bSStefano Zampini ierr = PCSetFromOptions(bddcipc_ctx->bddc);CHKERRQ(ierr); 28175a1e936bSStefano Zampini 28185a1e936bSStefano Zampini /* wrap the interface application */ 28195a1e936bSStefano Zampini ierr = PCSetType(ppc,PCSHELL);CHKERRQ(ierr); 28205a1e936bSStefano Zampini ierr = PCShellSetName(ppc,"FETI-DP pressure");CHKERRQ(ierr); 28215a1e936bSStefano Zampini ierr = PCShellSetContext(ppc,bddcipc_ctx);CHKERRQ(ierr); 28225a1e936bSStefano Zampini ierr = PCShellSetSetUp(ppc,PCSetUp_BDDCIPC);CHKERRQ(ierr); 28235a1e936bSStefano Zampini ierr = PCShellSetApply(ppc,PCApply_BDDCIPC);CHKERRQ(ierr); 28245a1e936bSStefano Zampini ierr = PCShellSetApplyTranspose(ppc,PCApplyTranspose_BDDCIPC);CHKERRQ(ierr); 28255a1e936bSStefano Zampini ierr = PCShellSetView(ppc,PCView_BDDCIPC);CHKERRQ(ierr); 28265a1e936bSStefano Zampini ierr = PCShellSetDestroy(ppc,PCDestroy_BDDCIPC);CHKERRQ(ierr); 28275a1e936bSStefano Zampini } 28285a1e936bSStefano Zampini 28295a1e936bSStefano Zampini /* determine if we need to assemble M to construct a preconditioner */ 28305a1e936bSStefano Zampini if (!matisok) { 28315a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)M,MATIS,&ismatis);CHKERRQ(ierr); 28325a1e936bSStefano Zampini ierr = PetscObjectTypeCompareAny((PetscObject)ppc,&matisok,PCBDDC,PCJACOBI,PCNONE,PCMG,"");CHKERRQ(ierr); 28335a1e936bSStefano Zampini if (ismatis && !matisok) { 28345a1e936bSStefano Zampini ierr = MatConvert(M,MATAIJ,MAT_INPLACE_MATRIX,&M);CHKERRQ(ierr); 28355a1e936bSStefano Zampini } 28365a1e936bSStefano Zampini } 2837064a4176SStefano Zampini 2838064a4176SStefano Zampini /* run the subproblems to check convergence */ 2839064a4176SStefano Zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)newmat)->prefix,"-check_saddlepoint",&check,NULL);CHKERRQ(ierr); 2840064a4176SStefano Zampini if (check) { 2841064a4176SStefano Zampini PetscInt i; 2842064a4176SStefano Zampini 2843064a4176SStefano Zampini for (i=0;i<nn;i++) { 2844064a4176SStefano Zampini KSP kspC; 2845064a4176SStefano Zampini PC pc; 2846064a4176SStefano Zampini Mat F,pF; 2847064a4176SStefano Zampini Vec x,y; 2848064a4176SStefano Zampini PetscBool isschur,prec = PETSC_TRUE; 2849064a4176SStefano Zampini 2850064a4176SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)ksps[i]),&kspC);CHKERRQ(ierr); 2851064a4176SStefano Zampini ierr = KSPSetOptionsPrefix(kspC,((PetscObject)ksps[i])->prefix);CHKERRQ(ierr); 2852064a4176SStefano Zampini ierr = KSPAppendOptionsPrefix(kspC,"check_");CHKERRQ(ierr); 2853064a4176SStefano Zampini ierr = KSPGetOperators(ksps[i],&F,&pF);CHKERRQ(ierr); 2854064a4176SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)F,MATSCHURCOMPLEMENT,&isschur);CHKERRQ(ierr); 2855064a4176SStefano Zampini if (isschur) { 2856064a4176SStefano Zampini KSP kspS,kspS2; 2857064a4176SStefano Zampini Mat A00,pA00,A10,A01,A11; 2858064a4176SStefano Zampini char prefix[256]; 2859064a4176SStefano Zampini 2860064a4176SStefano Zampini ierr = MatSchurComplementGetKSP(F,&kspS);CHKERRQ(ierr); 2861064a4176SStefano Zampini ierr = MatSchurComplementGetSubMatrices(F,&A00,&pA00,&A01,&A10,&A11);CHKERRQ(ierr); 2862064a4176SStefano Zampini ierr = MatCreateSchurComplement(A00,pA00,A01,A10,A11,&F);CHKERRQ(ierr); 2863064a4176SStefano Zampini ierr = MatSchurComplementGetKSP(F,&kspS2);CHKERRQ(ierr); 2864064a4176SStefano Zampini ierr = PetscSNPrintf(prefix,sizeof(prefix),"%sschur_",((PetscObject)kspC)->prefix);CHKERRQ(ierr); 2865064a4176SStefano Zampini ierr = KSPSetOptionsPrefix(kspS2,prefix);CHKERRQ(ierr); 2866064a4176SStefano Zampini ierr = KSPGetPC(kspS2,&pc);CHKERRQ(ierr); 2867064a4176SStefano Zampini ierr = PCSetType(pc,PCKSP);CHKERRQ(ierr); 2868064a4176SStefano Zampini ierr = PCKSPSetKSP(pc,kspS);CHKERRQ(ierr); 2869064a4176SStefano Zampini ierr = KSPSetFromOptions(kspS2);CHKERRQ(ierr); 2870064a4176SStefano Zampini ierr = KSPGetPC(kspS2,&pc);CHKERRQ(ierr); 2871064a4176SStefano Zampini ierr = PCSetUseAmat(pc,PETSC_TRUE);CHKERRQ(ierr); 2872064a4176SStefano Zampini } else { 2873064a4176SStefano Zampini ierr = PetscObjectReference((PetscObject)F);CHKERRQ(ierr); 2874064a4176SStefano Zampini } 2875064a4176SStefano Zampini ierr = KSPSetFromOptions(kspC);CHKERRQ(ierr); 2876064a4176SStefano Zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)kspC)->prefix,"-preconditioned",&prec,NULL);CHKERRQ(ierr); 2877064a4176SStefano Zampini if (prec) { 2878064a4176SStefano Zampini ierr = KSPGetPC(ksps[i],&pc);CHKERRQ(ierr); 2879064a4176SStefano Zampini ierr = KSPSetPC(kspC,pc);CHKERRQ(ierr); 2880064a4176SStefano Zampini } 2881064a4176SStefano Zampini ierr = KSPSetOperators(kspC,F,pF);CHKERRQ(ierr); 2882064a4176SStefano Zampini ierr = MatCreateVecs(F,&x,&y);CHKERRQ(ierr); 2883064a4176SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 2884064a4176SStefano Zampini ierr = MatMult(F,x,y);CHKERRQ(ierr); 2885064a4176SStefano Zampini ierr = KSPSolve(kspC,y,x);CHKERRQ(ierr); 2886c0decd05SBarry Smith ierr = KSPCheckSolve(kspC,pc,x);CHKERRQ(ierr); 2887064a4176SStefano Zampini ierr = KSPDestroy(&kspC);CHKERRQ(ierr); 2888064a4176SStefano Zampini ierr = MatDestroy(&F);CHKERRQ(ierr); 2889064a4176SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2890064a4176SStefano Zampini ierr = VecDestroy(&y);CHKERRQ(ierr); 2891064a4176SStefano Zampini } 2892064a4176SStefano Zampini } 2893e1214c54Sstefano_zampini ierr = PetscFree(ksps);CHKERRQ(ierr); 2894e1214c54Sstefano_zampini } 28955a1e936bSStefano Zampini } 28963425bc38SStefano Zampini /* return pointers for objects created */ 28973425bc38SStefano Zampini *fetidp_mat = newmat; 28983425bc38SStefano Zampini *fetidp_pc = newpc; 28993425bc38SStefano Zampini PetscFunctionReturn(0); 29003425bc38SStefano Zampini } 29011e6b0712SBarry Smith 290294ef8ddeSSatish Balay /*@C 29030f202f7eSStefano Zampini PCBDDCCreateFETIDPOperators - Create FETI-DP operators 29043425bc38SStefano Zampini 29053425bc38SStefano Zampini Collective 29063425bc38SStefano Zampini 29073425bc38SStefano Zampini Input Parameters: 29081720468bSStefano Zampini + pc - the BDDC preconditioning context (setup should have been called before) 2909547c9a8eSstefano_zampini . fully_redundant - true for a fully redundant set of Lagrange multipliers 2910547c9a8eSstefano_zampini - prefix - optional options database prefix for the objects to be created (can be NULL) 291128509bceSStefano Zampini 291228509bceSStefano Zampini Output Parameters: 29130f202f7eSStefano Zampini + fetidp_mat - shell FETI-DP matrix object 29140f202f7eSStefano Zampini - fetidp_pc - shell Dirichlet preconditioner for FETI-DP matrix 291528509bceSStefano Zampini 29163425bc38SStefano Zampini Level: developer 29173425bc38SStefano Zampini 29183425bc38SStefano Zampini Notes: 29190f202f7eSStefano Zampini Currently the only operations provided for FETI-DP matrix are MatMult and MatMultTranspose 29203425bc38SStefano Zampini 29210f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCMatFETIDPGetRHS, PCBDDCMatFETIDPGetSolution 29223425bc38SStefano Zampini @*/ 2923547c9a8eSstefano_zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, PetscBool fully_redundant, const char *prefix, Mat *fetidp_mat, PC *fetidp_pc) 29243425bc38SStefano Zampini { 29253425bc38SStefano Zampini PetscErrorCode ierr; 29263425bc38SStefano Zampini 29273425bc38SStefano Zampini PetscFunctionBegin; 29283425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 29293425bc38SStefano Zampini if (pc->setupcalled) { 2930547c9a8eSstefano_zampini ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,PetscBool,const char*,Mat*,PC*),(pc,fully_redundant,prefix,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 29316080607fSStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"You must call PCSetup_BDDC() first"); 29323425bc38SStefano Zampini PetscFunctionReturn(0); 29333425bc38SStefano Zampini } 29340c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2935da1bb401SStefano Zampini /*MC 2936da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 29370c7d97c5SJed Brown 2938be4a8d98Sprj- An implementation of the BDDC preconditioner based on the bibliography found below. 293928509bceSStefano Zampini 294028509bceSStefano Zampini The matrix to be preconditioned (Pmat) must be of type MATIS. 294128509bceSStefano Zampini 29420f202f7eSStefano Zampini Currently works with MATIS matrices with local matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers. 294328509bceSStefano Zampini 294428509bceSStefano Zampini It also works with unsymmetric and indefinite problems. 294528509bceSStefano Zampini 2946b6fdb6dfSStefano 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. 2947b6fdb6dfSStefano Zampini 2948c7017625SStefano Zampini Approximate local solvers are automatically adapted (see [1]) if the user has attached a nullspace object to the subdomain matrices, and informed BDDC of using approximate solvers (via the command line). 294928509bceSStefano Zampini 29500f202f7eSStefano 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() 295130368db7SStefano Zampini Additional information on dofs can be provided by using PCBDDCSetDofsSplitting(), PCBDDCSetDirichletBoundaries(), PCBDDCSetNeumannBoundaries(), and PCBDDCSetPrimalVerticesIS() and their local counterparts. 295228509bceSStefano Zampini 29530f202f7eSStefano Zampini Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace(). Non-singular modes are retained via SVD. 295428509bceSStefano Zampini 29550f202f7eSStefano 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. 29560f202f7eSStefano Zampini User defined change of basis can be passed to PCBDDC by using PCBDDCSetChangeOfBasisMat() 295728509bceSStefano Zampini 29580f202f7eSStefano Zampini The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using a MatPartitioning object. 295928509bceSStefano Zampini 2960df4d28bfSStefano 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. 296128509bceSStefano Zampini 29620f202f7eSStefano 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. 29630f202f7eSStefano Zampini 2964d314f959SVaclav Hapla Options Database Keys (some of them, run with -help for a complete list): 29650f202f7eSStefano Zampini 2966a2b725a8SWilliam Gropp + -pc_bddc_use_vertices <true> - use or not vertices in primal space 29670f202f7eSStefano Zampini . -pc_bddc_use_edges <true> - use or not edges in primal space 29680f202f7eSStefano Zampini . -pc_bddc_use_faces <false> - use or not faces in primal space 29690f202f7eSStefano Zampini . -pc_bddc_symmetric <true> - symmetric computation of primal basis functions. Specify false for unsymmetric problems 29700f202f7eSStefano Zampini . -pc_bddc_use_change_of_basis <false> - use change of basis approach (on edges only) 29710f202f7eSStefano Zampini . -pc_bddc_use_change_on_faces <false> - use change of basis approach on faces if change of basis has been requested 29720f202f7eSStefano Zampini . -pc_bddc_switch_static <false> - switches from M_2 (default) to M_3 operator (see reference article [1]) 297328509bceSStefano Zampini . -pc_bddc_levels <0> - maximum number of levels for multilevel 29740f202f7eSStefano 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) 29755459c157SBarry Smith . -pc_bddc_coarse_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) 29760f202f7eSStefano Zampini . -pc_bddc_use_deluxe_scaling <false> - use deluxe scaling 297771f2caa7Sprj- . -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) 2978bd2a564bSStefano Zampini . -pc_bddc_adaptive_threshold <0.0> - when a value different than zero is specified, adaptive selection of constraints is performed on edges and faces (requires deluxe scaling and MUMPS or MKL_PARDISO installed) 297928509bceSStefano Zampini - -pc_bddc_check_level <0> - set verbosity level of debugging output 298028509bceSStefano Zampini 298128509bceSStefano Zampini Options for Dirichlet, Neumann or coarse solver can be set with 298228509bceSStefano Zampini .vb 298328509bceSStefano Zampini -pc_bddc_dirichlet_ 298428509bceSStefano Zampini -pc_bddc_neumann_ 298528509bceSStefano Zampini -pc_bddc_coarse_ 298628509bceSStefano Zampini .ve 2987f9ff08acSPierre Jolivet e.g. -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg. PCBDDC uses by default KSPPREONLY and PCLU. 298828509bceSStefano Zampini 29890f202f7eSStefano Zampini When using a multilevel approach, solvers' options at the N-th level (N > 1) can be specified as 299028509bceSStefano Zampini .vb 2991312be037SStefano Zampini -pc_bddc_dirichlet_lN_ 2992312be037SStefano Zampini -pc_bddc_neumann_lN_ 2993312be037SStefano Zampini -pc_bddc_coarse_lN_ 299428509bceSStefano Zampini .ve 29950f202f7eSStefano Zampini Note that level number ranges from the finest (0) to the coarsest (N). 29960f202f7eSStefano 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. 29970f202f7eSStefano Zampini .vb 29980f202f7eSStefano Zampini -pc_bddc_coarse_pc_bddc_adaptive_threshold 5 -pc_bddc_coarse_l1_pc_bddc_redistribute 3 29990f202f7eSStefano Zampini .ve 30000f202f7eSStefano 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 3001da1bb401SStefano Zampini 3002be4a8d98Sprj- References: 3003*606c0280SSatish Balay + * - C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149--168, March 2007 3004*606c0280SSatish Balay . * - A. Klawonn and O. B. Widlund. "Dual-Primal FETI Methods for Linear Elasticity", Communications on Pure and Applied Mathematics Volume 59, Issue 11, pages 1523--1572, November 2006 3005*606c0280SSatish Balay . * - J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", Computing Volume 83, Issue 2--3, pages 55--85, November 2008 3006*606c0280SSatish Balay - * - 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 3007be4a8d98Sprj- 3008da1bb401SStefano Zampini Level: intermediate 3009da1bb401SStefano Zampini 3010e94cfbe0SPatrick Sanan Developer Notes: 3011da1bb401SStefano Zampini 3012da1bb401SStefano Zampini Contributed by Stefano Zampini 3013da1bb401SStefano Zampini 3014da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 3015da1bb401SStefano Zampini M*/ 3016b2573a8aSBarry Smith 30178cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 3018da1bb401SStefano Zampini { 3019da1bb401SStefano Zampini PetscErrorCode ierr; 3020da1bb401SStefano Zampini PC_BDDC *pcbddc; 3021da1bb401SStefano Zampini 3022da1bb401SStefano Zampini PetscFunctionBegin; 3023b00a9115SJed Brown ierr = PetscNewLog(pc,&pcbddc);CHKERRQ(ierr); 30243ec1f749SStefano Zampini pc->data = pcbddc; 3025da1bb401SStefano Zampini 3026da1bb401SStefano Zampini /* create PCIS data structure */ 3027da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 3028da1bb401SStefano Zampini 30299326c5c6Sstefano_zampini /* create local graph structure */ 30309326c5c6Sstefano_zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 30319326c5c6Sstefano_zampini 30329326c5c6Sstefano_zampini /* BDDC nonzero defaults */ 30336d9e27e4SStefano Zampini pcbddc->use_nnsp = PETSC_TRUE; 303408a5cf49SStefano Zampini pcbddc->use_local_adj = PETSC_TRUE; 303547d04d0dSStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 303647d04d0dSStefano Zampini pcbddc->use_edges = PETSC_TRUE; 30373301b35fSStefano Zampini pcbddc->symmetric_primal = PETSC_TRUE; 303814f95afaSStefano Zampini pcbddc->vertex_size = 1; 3039c703fcc7SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 304068457ee5SStefano Zampini pcbddc->coarse_size = -1; 304185c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 304247d04d0dSStefano Zampini pcbddc->coarsening_ratio = 8; 304357de7509SStefano Zampini pcbddc->coarse_eqs_per_proc = 1; 304427b6a85dSStefano Zampini pcbddc->benign_compute_correction = PETSC_TRUE; 30451e0482f5SStefano Zampini pcbddc->nedfield = -1; 30461e0482f5SStefano Zampini pcbddc->nedglobal = PETSC_TRUE; 3047be12c134Sstefano_zampini pcbddc->graphmaxcount = PETSC_MAX_INT; 3048b96c3477SStefano Zampini pcbddc->sub_schurs_layers = -1; 3049bd2a564bSStefano Zampini pcbddc->adaptive_threshold[0] = 0.0; 3050bd2a564bSStefano Zampini pcbddc->adaptive_threshold[1] = 0.0; 3051b7eb3628SStefano Zampini 3052da1bb401SStefano Zampini /* function pointers */ 3053da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 305493bd9ae7SStefano Zampini pc->ops->applytranspose = PCApplyTranspose_BDDC; 3055da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 3056da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 3057da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 30586b78500eSPatrick Sanan pc->ops->view = PCView_BDDC; 30590a545947SLisandro Dalcin pc->ops->applyrichardson = NULL; 30600a545947SLisandro Dalcin pc->ops->applysymmetricleft = NULL; 30610a545947SLisandro Dalcin pc->ops->applysymmetricright = NULL; 3062534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 3063534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 30649326c5c6Sstefano_zampini pc->ops->reset = PCReset_BDDC; 3065da1bb401SStefano Zampini 3066da1bb401SStefano Zampini /* composing function */ 3067a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",PCBDDCSetDiscreteGradient_BDDC);CHKERRQ(ierr); 3068a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",PCBDDCSetDivergenceMat_BDDC);CHKERRQ(ierr); 3069906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",PCBDDCSetChangeOfBasisMat_BDDC);CHKERRQ(ierr); 3070674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 307130368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",PCBDDCSetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 30723100ebe3SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetPrimalVerticesLocalIS_C",PCBDDCGetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 30733100ebe3SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetPrimalVerticesIS_C",PCBDDCGetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 3074bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 30752b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr); 3076b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr); 30772b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr); 3078bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 307982ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 3080bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 308182ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 3082bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 308382ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 3084bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 308582ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 3086bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 308763602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",PCBDDCSetDofsSplittingLocal_BDDC);CHKERRQ(ierr); 3088bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 3089bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 3090bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 3091bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 3092a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",PCPreSolveChangeRHS_BDDC);CHKERRQ(ierr); 3093ab8c8b98SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_BDDC);CHKERRQ(ierr); 3094da1bb401SStefano Zampini PetscFunctionReturn(0); 3095da1bb401SStefano Zampini } 309643371fb9SStefano Zampini 309743371fb9SStefano Zampini /*@C 309843371fb9SStefano Zampini PCBDDCInitializePackage - This function initializes everything in the PCBDDC package. It is called 30998a690491SBarry Smith from PCInitializePackage(). 310043371fb9SStefano Zampini 310143371fb9SStefano Zampini Level: developer 310243371fb9SStefano Zampini 310343371fb9SStefano Zampini .seealso: PetscInitialize() 310443371fb9SStefano Zampini @*/ 310543371fb9SStefano Zampini PetscErrorCode PCBDDCInitializePackage(void) 310643371fb9SStefano Zampini { 310743371fb9SStefano Zampini PetscErrorCode ierr; 310843371fb9SStefano Zampini int i; 310943371fb9SStefano Zampini 311043371fb9SStefano Zampini PetscFunctionBegin; 311143371fb9SStefano Zampini if (PCBDDCPackageInitialized) PetscFunctionReturn(0); 311243371fb9SStefano Zampini PCBDDCPackageInitialized = PETSC_TRUE; 311343371fb9SStefano Zampini ierr = PetscRegisterFinalize(PCBDDCFinalizePackage);CHKERRQ(ierr); 311443371fb9SStefano Zampini 311543371fb9SStefano Zampini /* general events */ 311643371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCTopo",PC_CLASSID,&PC_BDDC_Topology[0]);CHKERRQ(ierr); 311743371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCLKSP",PC_CLASSID,&PC_BDDC_LocalSolvers[0]);CHKERRQ(ierr); 311843371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCLWor",PC_CLASSID,&PC_BDDC_LocalWork[0]);CHKERRQ(ierr); 311943371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCorr",PC_CLASSID,&PC_BDDC_CorrectionSetUp[0]);CHKERRQ(ierr); 31208ead10e4SStefano Zampini ierr = PetscLogEventRegister("PCBDDCASet",PC_CLASSID,&PC_BDDC_ApproxSetUp[0]);CHKERRQ(ierr); 31218ead10e4SStefano Zampini ierr = PetscLogEventRegister("PCBDDCAApp",PC_CLASSID,&PC_BDDC_ApproxApply[0]);CHKERRQ(ierr); 312243371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCSet",PC_CLASSID,&PC_BDDC_CoarseSetUp[0]);CHKERRQ(ierr); 312343371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCKSP",PC_CLASSID,&PC_BDDC_CoarseSolver[0]);CHKERRQ(ierr); 312443371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCAdap",PC_CLASSID,&PC_BDDC_AdaptiveSetUp[0]);CHKERRQ(ierr); 312543371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCScal",PC_CLASSID,&PC_BDDC_Scaling[0]);CHKERRQ(ierr); 312643371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCSchr",PC_CLASSID,&PC_BDDC_Schurs[0]);CHKERRQ(ierr); 312755c176c0SStefano Zampini ierr = PetscLogEventRegister("PCBDDCDirS",PC_CLASSID,&PC_BDDC_Solves[0][0]);CHKERRQ(ierr); 312855c176c0SStefano Zampini ierr = PetscLogEventRegister("PCBDDCNeuS",PC_CLASSID,&PC_BDDC_Solves[0][1]);CHKERRQ(ierr); 312955c176c0SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCoaS",PC_CLASSID,&PC_BDDC_Solves[0][2]);CHKERRQ(ierr); 313043371fb9SStefano Zampini for (i=1;i<PETSC_PCBDDC_MAXLEVELS;i++) { 313143371fb9SStefano Zampini char ename[32]; 313243371fb9SStefano Zampini 313343371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCTopo l%02d",i);CHKERRQ(ierr); 313443371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Topology[i]);CHKERRQ(ierr); 313543371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCLKSP l%02d",i);CHKERRQ(ierr); 313643371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_LocalSolvers[i]);CHKERRQ(ierr); 313743371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCLWor l%02d",i);CHKERRQ(ierr); 313843371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_LocalWork[i]);CHKERRQ(ierr); 313943371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCorr l%02d",i);CHKERRQ(ierr); 314043371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CorrectionSetUp[i]);CHKERRQ(ierr); 31418ead10e4SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCASet l%02d",i);CHKERRQ(ierr); 31428ead10e4SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_ApproxSetUp[i]);CHKERRQ(ierr); 31438ead10e4SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCAApp l%02d",i);CHKERRQ(ierr); 31448ead10e4SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_ApproxApply[i]);CHKERRQ(ierr); 314543371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCSet l%02d",i);CHKERRQ(ierr); 314643371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CoarseSetUp[i]);CHKERRQ(ierr); 314743371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCKSP l%02d",i);CHKERRQ(ierr); 314843371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CoarseSolver[i]);CHKERRQ(ierr); 314943371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCAdap l%02d",i);CHKERRQ(ierr); 315043371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_AdaptiveSetUp[i]);CHKERRQ(ierr); 315143371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCScal l%02d",i);CHKERRQ(ierr); 315243371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Scaling[i]);CHKERRQ(ierr); 315343371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCSchr l%02d",i);CHKERRQ(ierr); 315443371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Schurs[i]);CHKERRQ(ierr); 315555c176c0SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCDirS l%02d",i);CHKERRQ(ierr); 315655c176c0SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Solves[i][0]);CHKERRQ(ierr); 315755c176c0SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCNeuS l%02d",i);CHKERRQ(ierr); 315855c176c0SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Solves[i][1]);CHKERRQ(ierr); 315955c176c0SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCoaS l%02d",i);CHKERRQ(ierr); 316055c176c0SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Solves[i][2]);CHKERRQ(ierr); 316143371fb9SStefano Zampini } 316243371fb9SStefano Zampini PetscFunctionReturn(0); 316343371fb9SStefano Zampini } 316443371fb9SStefano Zampini 316543371fb9SStefano Zampini /*@C 316643371fb9SStefano Zampini PCBDDCFinalizePackage - This function frees everything from the PCBDDC package. It is 316743371fb9SStefano Zampini called from PetscFinalize() automatically. 316843371fb9SStefano Zampini 316943371fb9SStefano Zampini Level: developer 317043371fb9SStefano Zampini 317143371fb9SStefano Zampini .seealso: PetscFinalize() 317243371fb9SStefano Zampini @*/ 317343371fb9SStefano Zampini PetscErrorCode PCBDDCFinalizePackage(void) 317443371fb9SStefano Zampini { 317543371fb9SStefano Zampini PetscFunctionBegin; 317643371fb9SStefano Zampini PCBDDCPackageInitialized = PETSC_FALSE; 317743371fb9SStefano Zampini PetscFunctionReturn(0); 317843371fb9SStefano Zampini } 3179