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 } 16850e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use vertices: %d (vertex size %D)\n",pcbddc->use_vertices,pcbddc->vertex_size);CHKERRQ(ierr); 169efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use edges: %d\n",pcbddc->use_edges);CHKERRQ(ierr); 170efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use faces: %d\n",pcbddc->use_faces);CHKERRQ(ierr); 171efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use true near null space: %d\n",pcbddc->use_nnsp_true);CHKERRQ(ierr); 172efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use QR for single constraints on cc: %d\n",pcbddc->use_qr_single);CHKERRQ(ierr); 173efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use change of basis on local edge nodes: %d\n",pcbddc->use_change_of_basis);CHKERRQ(ierr); 174efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use change of basis on local face nodes: %d\n",pcbddc->use_change_on_faces);CHKERRQ(ierr); 175efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," User defined change of basis matrix: %d\n",!!pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 176efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Has change of basis matrix: %d\n",!!pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 177efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eliminate dirichlet boundary dofs: %d\n",pcbddc->eliminate_dirdofs);CHKERRQ(ierr); 178efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Switch on static condensation ops around the interface preconditioner: %d\n",pcbddc->switch_static);CHKERRQ(ierr); 179efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use exact dirichlet trick: %d\n",pcbddc->use_exact_dirichlet_trick);CHKERRQ(ierr); 180bc960bbfSJed Brown ierr = PetscViewerASCIIPrintf(viewer," Interface extension: %s\n",PCBDDCInterfaceExtTypes[pcbddc->interface_extension]);CHKERRQ(ierr); 18150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Multilevel max levels: %D\n",pcbddc->max_levels);CHKERRQ(ierr); 18250e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Multilevel coarsening ratio: %D\n",pcbddc->coarsening_ratio);CHKERRQ(ierr); 183efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use estimated eigs for coarse problem: %d\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 184efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe scaling: %d\n",pcbddc->use_deluxe_scaling);CHKERRQ(ierr); 185efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe zerorows: %d\n",pcbddc->deluxe_zerorows);CHKERRQ(ierr); 186efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe singlemat: %d\n",pcbddc->deluxe_singlemat);CHKERRQ(ierr); 187efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Rebuild interface graph for Schur principal minors: %d\n",pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 18850e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Number of dofs' layers for the computation of principal minors: %D\n",pcbddc->sub_schurs_layers);CHKERRQ(ierr); 189efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use user CSR graph to compute successive layers: %d\n",pcbddc->sub_schurs_use_useradj);CHKERRQ(ierr); 190bd2a564bSStefano Zampini if (pcbddc->adaptive_threshold[1] != pcbddc->adaptive_threshold[0]) { 191bd2a564bSStefano 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); 192bd2a564bSStefano Zampini } else { 193bd2a564bSStefano 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); 194bd2a564bSStefano Zampini } 19550e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Min constraints / connected component: %D\n",pcbddc->adaptive_nmin);CHKERRQ(ierr); 19650e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Max constraints / connected component: %D\n",pcbddc->adaptive_nmax);CHKERRQ(ierr); 197efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Invert exact Schur complement for adaptive selection: %d\n",pcbddc->sub_schurs_exact_schur);CHKERRQ(ierr); 198efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Symmetric computation of primal basis functions: %d\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 19950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Num. Procs. to map coarse adjacency list: %D\n",pcbddc->coarse_adj_red);CHKERRQ(ierr); 20050e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Coarse eqs per proc (significant at the coarsest level): %D\n",pcbddc->coarse_eqs_per_proc);CHKERRQ(ierr); 2018361f951SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Detect disconnected: %d (filter %d)\n",pcbddc->detect_disconnected,pcbddc->detect_disconnected_filter);CHKERRQ(ierr); 202efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Benign subspace trick: %d (change explicit %d)\n",pcbddc->benign_saddle_point,pcbddc->benign_change_explicit);CHKERRQ(ierr); 203efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Benign subspace trick is active: %d\n",pcbddc->benign_have_null);CHKERRQ(ierr); 20415579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Algebraic computation of no-net-flux: %d\n",pcbddc->compute_nonetflux);CHKERRQ(ierr); 205b74ba07aSstefano_zampini if (!pc->setupcalled) PetscFunctionReturn(0); 2066b78500eSPatrick Sanan 207fbad9177SStefano Zampini /* compute interface size */ 208e9627c49SStefano Zampini ierr = VecSet(pcis->vec1_B,1.0);CHKERRQ(ierr); 2090a545947SLisandro Dalcin ierr = MatCreateVecs(pc->pmat,&counter,NULL);CHKERRQ(ierr); 210e9627c49SStefano Zampini ierr = VecSet(counter,0.0);CHKERRQ(ierr); 211e9627c49SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 212e9627c49SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 213e9627c49SStefano Zampini ierr = VecSum(counter,&interface_size);CHKERRQ(ierr); 214e9627c49SStefano Zampini ierr = VecDestroy(&counter);CHKERRQ(ierr); 215fbad9177SStefano Zampini 216fbad9177SStefano Zampini /* compute some statistics on the domain decomposition */ 217e9627c49SStefano Zampini gsum[0] = 1; 218fbad9177SStefano Zampini gsum[1] = gsum[2] = gsum[3] = gsum[4] = gsum[5] = 0; 219e9627c49SStefano Zampini loc[0] = !!pcis->n; 220e9627c49SStefano Zampini loc[1] = pcis->n - pcis->n_B; 221e9627c49SStefano Zampini loc[2] = pcis->n_B; 222e9627c49SStefano Zampini loc[3] = pcbddc->local_primal_size; 223345ecf6cSStefano Zampini loc[4] = pcis->n; 224fbad9177SStefano Zampini loc[5] = pcbddc->n_local_subs > 0 ? pcbddc->n_local_subs : (pcis->n ? 1 : 0); 225fbad9177SStefano Zampini loc[6] = pcbddc->benign_n; 226ffc4695bSBarry Smith ierr = MPI_Reduce(loc,gsum,6,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRMPI(ierr); 227fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = -1; 228ffc4695bSBarry Smith ierr = MPI_Reduce(loc,gmax,6,MPIU_INT64,MPI_MAX,0,PetscObjectComm((PetscObject)pc));CHKERRMPI(ierr); 229fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = PETSC_MAX_INT; 230ffc4695bSBarry Smith ierr = MPI_Reduce(loc,gmin,6,MPIU_INT64,MPI_MIN,0,PetscObjectComm((PetscObject)pc));CHKERRMPI(ierr); 231ffc4695bSBarry Smith ierr = MPI_Reduce(&loc[6],&totbenign,1,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRMPI(ierr); 232e9627c49SStefano Zampini if (pcbddc->coarse_size) { 233e9627c49SStefano Zampini ratio1 = pc->pmat->rmap->N/(1.*pcbddc->coarse_size); 234e9627c49SStefano Zampini ratio2 = PetscRealPart(interface_size)/pcbddc->coarse_size; 235e9627c49SStefano Zampini } 236efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"********************************** STATISTICS AT LEVEL %d **********************************\n",pcbddc->current_level);CHKERRQ(ierr); 23750e0721cSStefano 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); 23850e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Coarsening ratios: all/coarse %D interface/coarse %D\n",(PetscInt)ratio1,(PetscInt)ratio2);CHKERRQ(ierr); 23950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Active processes : %D\n",(PetscInt)gsum[0]);CHKERRQ(ierr); 24050e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Total subdomains : %D\n",(PetscInt)gsum[5]);CHKERRQ(ierr); 241345ecf6cSStefano Zampini if (pcbddc->benign_have_null) { 24250e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Benign subs : %D\n",(PetscInt)totbenign);CHKERRQ(ierr); 243345ecf6cSStefano Zampini } 24450e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Dofs type :\tMIN\tMAX\tMEAN\n");CHKERRQ(ierr); 24550e0721cSStefano 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); 24650e0721cSStefano 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); 24750e0721cSStefano 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); 24850e0721cSStefano 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); 24950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Local subs :\t%D\t%D\n" ,(PetscInt)gmin[5],(PetscInt)gmax[5]);CHKERRQ(ierr); 25015579a77SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 25115579a77SStefano Zampini 252ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRMPI(ierr); 25315579a77SStefano Zampini 25415579a77SStefano Zampini /* local solvers */ 25515579a77SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscObjectComm((PetscObject)pcbddc->ksp_D),&subviewer);CHKERRQ(ierr); 256dd400576SPatrick Sanan if (rank == 0) { 25715579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Interior solver (rank 0)\n");CHKERRQ(ierr); 25815579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 25915579a77SStefano Zampini ierr = KSPView(pcbddc->ksp_D,subviewer);CHKERRQ(ierr); 26015579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 26115579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Correction solver (rank 0)\n");CHKERRQ(ierr); 26215579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 26315579a77SStefano Zampini ierr = KSPView(pcbddc->ksp_R,subviewer);CHKERRQ(ierr); 26415579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 26515579a77SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 26615579a77SStefano Zampini } 26715579a77SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscObjectComm((PetscObject)pcbddc->ksp_D),&subviewer);CHKERRQ(ierr); 26827b6a85dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 269e9627c49SStefano Zampini 270fbad9177SStefano Zampini /* the coarse problem can be handled by a different communicator */ 271e9627c49SStefano Zampini if (pcbddc->coarse_ksp) color = 1; 272e9627c49SStefano Zampini else color = 0; 273ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRMPI(ierr); 274e9627c49SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)pc),&subcomm);CHKERRQ(ierr); 2754b2aedd3SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,PetscMin(size,2));CHKERRQ(ierr); 276e9627c49SStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 277e9627c49SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 278e9627c49SStefano Zampini if (color == 1) { 27915579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Coarse solver\n");CHKERRQ(ierr); 28015579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 281e9627c49SStefano Zampini ierr = KSPView(pcbddc->coarse_ksp,subviewer);CHKERRQ(ierr); 28215579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 283e9627c49SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 284e9627c49SStefano Zampini } 285e9627c49SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 286e9627c49SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 287e9627c49SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 288e9627c49SStefano Zampini } 2896b78500eSPatrick Sanan PetscFunctionReturn(0); 2906b78500eSPatrick Sanan } 291a13144ffSStefano Zampini 2921e0482f5SStefano Zampini static PetscErrorCode PCBDDCSetDiscreteGradient_BDDC(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 293a13144ffSStefano Zampini { 294a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 295a13144ffSStefano Zampini PetscErrorCode ierr; 296a13144ffSStefano Zampini 297a13144ffSStefano Zampini PetscFunctionBegin; 298a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr); 299a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 300a13144ffSStefano Zampini pcbddc->discretegradient = G; 301a13144ffSStefano Zampini pcbddc->nedorder = order > 0 ? order : -order; 302495a2a07SStefano Zampini pcbddc->nedfield = field; 3031e0482f5SStefano Zampini pcbddc->nedglobal = global; 3041e0482f5SStefano Zampini pcbddc->conforming = conforming; 305a13144ffSStefano Zampini PetscFunctionReturn(0); 306a13144ffSStefano Zampini } 307a13144ffSStefano Zampini 308a13144ffSStefano Zampini /*@ 309a13144ffSStefano Zampini PCBDDCSetDiscreteGradient - Sets the discrete gradient 310a13144ffSStefano Zampini 311a13144ffSStefano Zampini Collective on PC 312a13144ffSStefano Zampini 313a13144ffSStefano Zampini Input Parameters: 314a13144ffSStefano Zampini + pc - the preconditioning context 315a13144ffSStefano Zampini . G - the discrete gradient matrix (should be in AIJ format) 316a13144ffSStefano Zampini . order - the order of the Nedelec space (1 for the lowest order) 317495a2a07SStefano Zampini . field - the field id of the Nedelec dofs (not used if the fields have not been specified) 3181e0482f5SStefano Zampini . global - the type of global ordering for the rows of G 319a13144ffSStefano Zampini - conforming - whether the mesh is conforming or not 320a13144ffSStefano Zampini 321a13144ffSStefano Zampini Level: advanced 322a13144ffSStefano Zampini 32395452b02SPatrick Sanan Notes: 32495452b02SPatrick Sanan The discrete gradient matrix G is used to analyze the subdomain edges, and it should not contain any zero entry. 325495a2a07SStefano Zampini For variable order spaces, the order should be set to zero. 3261e0482f5SStefano Zampini If global is true, the rows of G should be given in global ordering for the whole dofs; 3271e0482f5SStefano Zampini if false, the ordering should be global for the Nedelec field. 3281e0482f5SStefano 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 3291e0482f5SStefano Zampini and geid the one for the Nedelec field. 330a13144ffSStefano Zampini 331495a2a07SStefano Zampini .seealso: PCBDDC,PCBDDCSetDofsSplitting(),PCBDDCSetDofsSplittingLocal() 332a13144ffSStefano Zampini @*/ 3331e0482f5SStefano Zampini PetscErrorCode PCBDDCSetDiscreteGradient(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 334a13144ffSStefano Zampini { 335a13144ffSStefano Zampini PetscErrorCode ierr; 336a13144ffSStefano Zampini 337a13144ffSStefano Zampini PetscFunctionBegin; 338a13144ffSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 339a13144ffSStefano Zampini PetscValidHeaderSpecific(G,MAT_CLASSID,2); 340a13144ffSStefano Zampini PetscValidLogicalCollectiveInt(pc,order,3); 3411e0482f5SStefano Zampini PetscValidLogicalCollectiveInt(pc,field,4); 3421e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,global,5); 3431e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,conforming,6); 3441e0482f5SStefano Zampini PetscCheckSameComm(pc,1,G,2); 3451e0482f5SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDiscreteGradient_C",(PC,Mat,PetscInt,PetscInt,PetscBool,PetscBool),(pc,G,order,field,global,conforming));CHKERRQ(ierr); 346a13144ffSStefano Zampini PetscFunctionReturn(0); 347a13144ffSStefano Zampini } 348a13144ffSStefano Zampini 3498ae0ca82SStefano Zampini static PetscErrorCode PCBDDCSetDivergenceMat_BDDC(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 350a198735bSStefano Zampini { 351a198735bSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 352a198735bSStefano Zampini PetscErrorCode ierr; 3536b78500eSPatrick Sanan 354a198735bSStefano Zampini PetscFunctionBegin; 355a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)divudotp);CHKERRQ(ierr); 356a198735bSStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 357a198735bSStefano Zampini pcbddc->divudotp = divudotp; 3588ae0ca82SStefano Zampini pcbddc->divudotp_trans = trans; 359a198735bSStefano Zampini pcbddc->compute_nonetflux = PETSC_TRUE; 360a198735bSStefano Zampini if (vl2l) { 361a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2l);CHKERRQ(ierr); 362fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 363a198735bSStefano Zampini pcbddc->divudotp_vl2l = vl2l; 364a198735bSStefano Zampini } 365a198735bSStefano Zampini PetscFunctionReturn(0); 366a198735bSStefano Zampini } 3673d996552SStefano Zampini 368a198735bSStefano Zampini /*@ 369a198735bSStefano Zampini PCBDDCSetDivergenceMat - Sets the linear operator representing \int_\Omega \div {\bf u} \cdot p dx 370a198735bSStefano Zampini 371a198735bSStefano Zampini Collective on PC 372a198735bSStefano Zampini 373a198735bSStefano Zampini Input Parameters: 374a198735bSStefano Zampini + pc - the preconditioning context 375a198735bSStefano Zampini . divudotp - the matrix (must be of type MATIS) 3768ae0ca82SStefano Zampini . trans - if trans if false (resp. true), then pressures are in the test (trial) space and velocities are in the trial (test) space. 37705a3bf82SStefano 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 378a198735bSStefano Zampini 379a198735bSStefano Zampini Level: advanced 380a198735bSStefano Zampini 38195452b02SPatrick Sanan Notes: 38295452b02SPatrick Sanan This auxiliary matrix is used to compute quadrature weights representing the net-flux across subdomain boundaries 38305a3bf82SStefano Zampini If vl2l is NULL, the local ordering for velocities in divudotp should match that of the preconditioning matrix 384a198735bSStefano Zampini 385a198735bSStefano Zampini .seealso: PCBDDC 386a198735bSStefano Zampini @*/ 3878ae0ca82SStefano Zampini PetscErrorCode PCBDDCSetDivergenceMat(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 388a198735bSStefano Zampini { 389a198735bSStefano Zampini PetscBool ismatis; 390a198735bSStefano Zampini PetscErrorCode ierr; 391a198735bSStefano Zampini 392a198735bSStefano Zampini PetscFunctionBegin; 393a198735bSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 394a198735bSStefano Zampini PetscValidHeaderSpecific(divudotp,MAT_CLASSID,2); 395a198735bSStefano Zampini PetscCheckSameComm(pc,1,divudotp,2); 3968ae0ca82SStefano Zampini PetscValidLogicalCollectiveBool(pc,trans,3); 3971b24a7afSStefano Zampini if (vl2l) PetscValidHeaderSpecific(vl2l,IS_CLASSID,4); 398a198735bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)divudotp,MATIS,&ismatis);CHKERRQ(ierr); 399a198735bSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Divergence matrix needs to be of type MATIS"); 4008ae0ca82SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDivergenceMat_C",(PC,Mat,PetscBool,IS),(pc,divudotp,trans,vl2l));CHKERRQ(ierr); 401a198735bSStefano Zampini PetscFunctionReturn(0); 402a198735bSStefano Zampini } 4032d505d7fSStefano Zampini 4041dd7afcfSStefano Zampini static PetscErrorCode PCBDDCSetChangeOfBasisMat_BDDC(PC pc, Mat change, PetscBool interior) 405b9b85e73SStefano Zampini { 406b9b85e73SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 407b9b85e73SStefano Zampini PetscErrorCode ierr; 408b9b85e73SStefano Zampini 409b9b85e73SStefano Zampini PetscFunctionBegin; 410b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)change);CHKERRQ(ierr); 41156282151SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 412b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = change; 4131dd7afcfSStefano Zampini pcbddc->change_interior = interior; 414b9b85e73SStefano Zampini PetscFunctionReturn(0); 415b9b85e73SStefano Zampini } 416b9b85e73SStefano Zampini /*@ 417906d46d4SStefano Zampini PCBDDCSetChangeOfBasisMat - Set user defined change of basis for dofs 418b9b85e73SStefano Zampini 419b9b85e73SStefano Zampini Collective on PC 420b9b85e73SStefano Zampini 421b9b85e73SStefano Zampini Input Parameters: 422b9b85e73SStefano Zampini + pc - the preconditioning context 4231dd7afcfSStefano Zampini . change - the change of basis matrix 4241dd7afcfSStefano Zampini - interior - whether or not the change of basis modifies interior dofs 425b9b85e73SStefano Zampini 426b9b85e73SStefano Zampini Level: intermediate 427b9b85e73SStefano Zampini 428b9b85e73SStefano Zampini Notes: 429b9b85e73SStefano Zampini 430b9b85e73SStefano Zampini .seealso: PCBDDC 431b9b85e73SStefano Zampini @*/ 4321dd7afcfSStefano Zampini PetscErrorCode PCBDDCSetChangeOfBasisMat(PC pc, Mat change, PetscBool interior) 433b9b85e73SStefano Zampini { 434b9b85e73SStefano Zampini PetscErrorCode ierr; 435b9b85e73SStefano Zampini 436b9b85e73SStefano Zampini PetscFunctionBegin; 437b9b85e73SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 438b9b85e73SStefano Zampini PetscValidHeaderSpecific(change,MAT_CLASSID,2); 439906d46d4SStefano Zampini PetscCheckSameComm(pc,1,change,2); 440906d46d4SStefano Zampini if (pc->mat) { 441906d46d4SStefano Zampini PetscInt rows_c,cols_c,rows,cols; 442906d46d4SStefano Zampini ierr = MatGetSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 443906d46d4SStefano Zampini ierr = MatGetSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 444*98921bdaSJacob Faibussowitsch if (rows_c != rows) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of rows for change of basis matrix! %D != %D",rows_c,rows); 445*98921bdaSJacob Faibussowitsch if (cols_c != cols) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of columns for change of basis matrix! %D != %D",cols_c,cols); 446906d46d4SStefano Zampini ierr = MatGetLocalSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 447906d46d4SStefano Zampini ierr = MatGetLocalSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 448*98921bdaSJacob Faibussowitsch if (rows_c != rows) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of local rows for change of basis matrix! %D != %D",rows_c,rows); 449*98921bdaSJacob Faibussowitsch if (cols_c != cols) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of local columns for change of basis matrix! %D != %D",cols_c,cols); 450906d46d4SStefano Zampini } 4511dd7afcfSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetChangeOfBasisMat_C",(PC,Mat,PetscBool),(pc,change,interior));CHKERRQ(ierr); 452b9b85e73SStefano Zampini PetscFunctionReturn(0); 453b9b85e73SStefano Zampini } 4542d505d7fSStefano Zampini 45530368db7SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesIS_BDDC(PC pc, IS PrimalVertices) 45630368db7SStefano Zampini { 45730368db7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 45856282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 45930368db7SStefano Zampini PetscErrorCode ierr; 46030368db7SStefano Zampini 46130368db7SStefano Zampini PetscFunctionBegin; 46256282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 46356282151SStefano Zampini if (pcbddc->user_primal_vertices) { 46456282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices,&isequal);CHKERRQ(ierr); 46556282151SStefano Zampini } 46630368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 46730368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 46830368db7SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 46956282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 47030368db7SStefano Zampini PetscFunctionReturn(0); 47130368db7SStefano Zampini } 472ab8c8b98SStefano Zampini 47330368db7SStefano Zampini /*@ 47430368db7SStefano Zampini PCBDDCSetPrimalVerticesIS - Set additional user defined primal vertices in PCBDDC 47530368db7SStefano Zampini 47630368db7SStefano Zampini Collective 47730368db7SStefano Zampini 47830368db7SStefano Zampini Input Parameters: 47930368db7SStefano Zampini + pc - the preconditioning context 48030368db7SStefano Zampini - PrimalVertices - index set of primal vertices in global numbering (can be empty) 48130368db7SStefano Zampini 48230368db7SStefano Zampini Level: intermediate 48330368db7SStefano Zampini 48430368db7SStefano Zampini Notes: 48530368db7SStefano Zampini Any process can list any global node 48630368db7SStefano Zampini 4873100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCGetPrimalVerticesIS(), PCBDDCSetPrimalVerticesLocalIS(), PCBDDCGetPrimalVerticesLocalIS() 48830368db7SStefano Zampini @*/ 48930368db7SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesIS(PC pc, IS PrimalVertices) 49030368db7SStefano Zampini { 49130368db7SStefano Zampini PetscErrorCode ierr; 49230368db7SStefano Zampini 49330368db7SStefano Zampini PetscFunctionBegin; 49430368db7SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 49530368db7SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 49630368db7SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 49730368db7SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 49830368db7SStefano Zampini PetscFunctionReturn(0); 49930368db7SStefano Zampini } 5002d505d7fSStefano Zampini 5013100ebe3SStefano Zampini static PetscErrorCode PCBDDCGetPrimalVerticesIS_BDDC(PC pc, IS *is) 5023100ebe3SStefano Zampini { 5033100ebe3SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5043100ebe3SStefano Zampini 5053100ebe3SStefano Zampini PetscFunctionBegin; 5063100ebe3SStefano Zampini *is = pcbddc->user_primal_vertices; 5073100ebe3SStefano Zampini PetscFunctionReturn(0); 5083100ebe3SStefano Zampini } 5093100ebe3SStefano Zampini 5103100ebe3SStefano Zampini /*@ 5113100ebe3SStefano Zampini PCBDDCGetPrimalVerticesIS - Get user defined primal vertices set with PCBDDCSetPrimalVerticesIS() 5123100ebe3SStefano Zampini 5133100ebe3SStefano Zampini Collective 5143100ebe3SStefano Zampini 5153100ebe3SStefano Zampini Input Parameters: 5163100ebe3SStefano Zampini . pc - the preconditioning context 5173100ebe3SStefano Zampini 5183100ebe3SStefano Zampini Output Parameters: 5193100ebe3SStefano Zampini . is - index set of primal vertices in global numbering (NULL if not set) 5203100ebe3SStefano Zampini 5213100ebe3SStefano Zampini Level: intermediate 5223100ebe3SStefano Zampini 5233100ebe3SStefano Zampini Notes: 5243100ebe3SStefano Zampini 5253100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCSetPrimalVerticesIS(), PCBDDCSetPrimalVerticesLocalIS(), PCBDDCGetPrimalVerticesLocalIS() 5263100ebe3SStefano Zampini @*/ 5273100ebe3SStefano Zampini PetscErrorCode PCBDDCGetPrimalVerticesIS(PC pc, IS *is) 5283100ebe3SStefano Zampini { 5293100ebe3SStefano Zampini PetscErrorCode ierr; 5303100ebe3SStefano Zampini 5313100ebe3SStefano Zampini PetscFunctionBegin; 5323100ebe3SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5333100ebe3SStefano Zampini PetscValidPointer(is,2); 5343100ebe3SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetPrimalVerticesIS_C",(PC,IS*),(pc,is));CHKERRQ(ierr); 5353100ebe3SStefano Zampini PetscFunctionReturn(0); 5363100ebe3SStefano Zampini } 5373100ebe3SStefano Zampini 538674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 539674ae819SStefano Zampini { 540674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 54156282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 542674ae819SStefano Zampini PetscErrorCode ierr; 5431e6b0712SBarry Smith 544674ae819SStefano Zampini PetscFunctionBegin; 54556282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 54656282151SStefano Zampini if (pcbddc->user_primal_vertices_local) { 54756282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices_local,&isequal);CHKERRQ(ierr); 54856282151SStefano Zampini } 549674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 55030368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 55130368db7SStefano Zampini pcbddc->user_primal_vertices_local = PrimalVertices; 55256282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 553674ae819SStefano Zampini PetscFunctionReturn(0); 554674ae819SStefano Zampini } 5553100ebe3SStefano Zampini 556674ae819SStefano Zampini /*@ 55728509bceSStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC 558674ae819SStefano Zampini 55917eb1463SStefano Zampini Collective 560674ae819SStefano Zampini 561674ae819SStefano Zampini Input Parameters: 562674ae819SStefano Zampini + pc - the preconditioning context 56317eb1463SStefano Zampini - PrimalVertices - index set of primal vertices in local numbering (can be empty) 564674ae819SStefano Zampini 565674ae819SStefano Zampini Level: intermediate 566674ae819SStefano Zampini 567674ae819SStefano Zampini Notes: 568674ae819SStefano Zampini 5693100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCSetPrimalVerticesIS(), PCBDDCGetPrimalVerticesIS(), PCBDDCGetPrimalVerticesLocalIS() 570674ae819SStefano Zampini @*/ 571674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 572674ae819SStefano Zampini { 573674ae819SStefano Zampini PetscErrorCode ierr; 574674ae819SStefano Zampini 575674ae819SStefano Zampini PetscFunctionBegin; 576674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 577674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 57817eb1463SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 579674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 580674ae819SStefano Zampini PetscFunctionReturn(0); 581674ae819SStefano Zampini } 5822d505d7fSStefano Zampini 5833100ebe3SStefano Zampini static PetscErrorCode PCBDDCGetPrimalVerticesLocalIS_BDDC(PC pc, IS *is) 5843100ebe3SStefano Zampini { 5853100ebe3SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5863100ebe3SStefano Zampini 5873100ebe3SStefano Zampini PetscFunctionBegin; 5883100ebe3SStefano Zampini *is = pcbddc->user_primal_vertices_local; 5893100ebe3SStefano Zampini PetscFunctionReturn(0); 5903100ebe3SStefano Zampini } 5913100ebe3SStefano Zampini 5923100ebe3SStefano Zampini /*@ 5933100ebe3SStefano Zampini PCBDDCGetPrimalVerticesLocalIS - Get user defined primal vertices set with PCBDDCSetPrimalVerticesLocalIS() 5943100ebe3SStefano Zampini 5953100ebe3SStefano Zampini Collective 5963100ebe3SStefano Zampini 5973100ebe3SStefano Zampini Input Parameters: 5983100ebe3SStefano Zampini . pc - the preconditioning context 5993100ebe3SStefano Zampini 6003100ebe3SStefano Zampini Output Parameters: 6013100ebe3SStefano Zampini . is - index set of primal vertices in local numbering (NULL if not set) 6023100ebe3SStefano Zampini 6033100ebe3SStefano Zampini Level: intermediate 6043100ebe3SStefano Zampini 6053100ebe3SStefano Zampini Notes: 6063100ebe3SStefano Zampini 6073100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCSetPrimalVerticesIS(), PCBDDCGetPrimalVerticesIS(), PCBDDCSetPrimalVerticesLocalIS() 6083100ebe3SStefano Zampini @*/ 6093100ebe3SStefano Zampini PetscErrorCode PCBDDCGetPrimalVerticesLocalIS(PC pc, IS *is) 6103100ebe3SStefano Zampini { 6113100ebe3SStefano Zampini PetscErrorCode ierr; 6123100ebe3SStefano Zampini 6133100ebe3SStefano Zampini PetscFunctionBegin; 6143100ebe3SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6153100ebe3SStefano Zampini PetscValidPointer(is,2); 6163100ebe3SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetPrimalVerticesLocalIS_C",(PC,IS*),(pc,is));CHKERRQ(ierr); 6173100ebe3SStefano Zampini PetscFunctionReturn(0); 6183100ebe3SStefano Zampini } 6193100ebe3SStefano Zampini 6204fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 6214fad6a16SStefano Zampini { 6224fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6234fad6a16SStefano Zampini 6244fad6a16SStefano Zampini PetscFunctionBegin; 6254fad6a16SStefano Zampini pcbddc->coarsening_ratio = k; 6264fad6a16SStefano Zampini PetscFunctionReturn(0); 6274fad6a16SStefano Zampini } 6281e6b0712SBarry Smith 6294fad6a16SStefano Zampini /*@ 63028509bceSStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel 6314fad6a16SStefano Zampini 6324fad6a16SStefano Zampini Logically collective on PC 6334fad6a16SStefano Zampini 6344fad6a16SStefano Zampini Input Parameters: 6354fad6a16SStefano Zampini + pc - the preconditioning context 63628509bceSStefano Zampini - k - coarsening ratio (H/h at the coarser level) 6374fad6a16SStefano Zampini 6380f202f7eSStefano Zampini Options Database Keys: 6390f202f7eSStefano Zampini . -pc_bddc_coarsening_ratio 6404fad6a16SStefano Zampini 6414fad6a16SStefano Zampini Level: intermediate 6424fad6a16SStefano Zampini 6434fad6a16SStefano Zampini Notes: 6440f202f7eSStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level 6454fad6a16SStefano Zampini 6460f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetLevels() 6474fad6a16SStefano Zampini @*/ 6484fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 6494fad6a16SStefano Zampini { 6504fad6a16SStefano Zampini PetscErrorCode ierr; 6514fad6a16SStefano Zampini 6524fad6a16SStefano Zampini PetscFunctionBegin; 6534fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6542b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,k,2); 6554fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 6564fad6a16SStefano Zampini PetscFunctionReturn(0); 6574fad6a16SStefano Zampini } 6582b510759SStefano Zampini 659b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */ 660b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg) 661b8ffe317SStefano Zampini { 662b8ffe317SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 663b8ffe317SStefano Zampini 664b8ffe317SStefano Zampini PetscFunctionBegin; 66585c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = flg; 666b8ffe317SStefano Zampini PetscFunctionReturn(0); 667b8ffe317SStefano Zampini } 668b8ffe317SStefano Zampini 669b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg) 6702b510759SStefano Zampini { 6712b510759SStefano Zampini PetscErrorCode ierr; 6722b510759SStefano Zampini 6732b510759SStefano Zampini PetscFunctionBegin; 6742b510759SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 675b8ffe317SStefano Zampini PetscValidLogicalCollectiveBool(pc,flg,2); 676b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr); 6772b510759SStefano Zampini PetscFunctionReturn(0); 6782b510759SStefano Zampini } 6791e6b0712SBarry Smith 6802b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level) 6814fad6a16SStefano Zampini { 6824fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6834fad6a16SStefano Zampini 6844fad6a16SStefano Zampini PetscFunctionBegin; 6852b510759SStefano Zampini pcbddc->current_level = level; 6864fad6a16SStefano Zampini PetscFunctionReturn(0); 6874fad6a16SStefano Zampini } 6881e6b0712SBarry Smith 689b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 690b8ffe317SStefano Zampini { 691b8ffe317SStefano Zampini PetscErrorCode ierr; 692b8ffe317SStefano Zampini 693b8ffe317SStefano Zampini PetscFunctionBegin; 694b8ffe317SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 695b8ffe317SStefano Zampini PetscValidLogicalCollectiveInt(pc,level,2); 696b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr); 697b8ffe317SStefano Zampini PetscFunctionReturn(0); 698b8ffe317SStefano Zampini } 699b8ffe317SStefano Zampini 7002b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels) 7012b510759SStefano Zampini { 7022b510759SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 7032b510759SStefano Zampini 7042b510759SStefano Zampini PetscFunctionBegin; 705*98921bdaSJacob Faibussowitsch if (levels > PETSC_PCBDDC_MAXLEVELS-1) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Maximum number of additional levels for BDDC is %d",PETSC_PCBDDC_MAXLEVELS-1); 7062b510759SStefano Zampini pcbddc->max_levels = levels; 7072b510759SStefano Zampini PetscFunctionReturn(0); 7082b510759SStefano Zampini } 7092b510759SStefano Zampini 7104fad6a16SStefano Zampini /*@ 71137ebbdf7SStefano Zampini PCBDDCSetLevels - Sets the maximum number of additional levels allowed for multilevel BDDC 7124fad6a16SStefano Zampini 7134fad6a16SStefano Zampini Logically collective on PC 7144fad6a16SStefano Zampini 7154fad6a16SStefano Zampini Input Parameters: 7164fad6a16SStefano Zampini + pc - the preconditioning context 71737ebbdf7SStefano Zampini - levels - the maximum number of levels 7184fad6a16SStefano Zampini 7190f202f7eSStefano Zampini Options Database Keys: 7200f202f7eSStefano Zampini . -pc_bddc_levels 7214fad6a16SStefano Zampini 7224fad6a16SStefano Zampini Level: intermediate 7234fad6a16SStefano Zampini 7244fad6a16SStefano Zampini Notes: 72537ebbdf7SStefano Zampini The default value is 0, that gives the classical two-levels BDDC 7264fad6a16SStefano Zampini 7270f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetCoarseningRatio() 7284fad6a16SStefano Zampini @*/ 7292b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels) 7304fad6a16SStefano Zampini { 7314fad6a16SStefano Zampini PetscErrorCode ierr; 7324fad6a16SStefano Zampini 7334fad6a16SStefano Zampini PetscFunctionBegin; 7344fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 7352b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,levels,2); 7362b510759SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr); 7374fad6a16SStefano Zampini PetscFunctionReturn(0); 7384fad6a16SStefano Zampini } 7391e6b0712SBarry Smith 7403b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 7413b03a366Sstefano_zampini { 7423b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 74356282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 7443b03a366Sstefano_zampini PetscErrorCode ierr; 7453b03a366Sstefano_zampini 7463b03a366Sstefano_zampini PetscFunctionBegin; 74756282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 74856282151SStefano Zampini if (pcbddc->DirichletBoundaries) { 74956282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundaries,&isequal);CHKERRQ(ierr); 75056282151SStefano Zampini } 751a5b23f4aSJose E. Roman /* last user setting takes precedence -> destroy any other customization */ 752785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 7533b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 75436e030ebSStefano Zampini pcbddc->DirichletBoundaries = DirichletBoundaries; 75556282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7563b03a366Sstefano_zampini PetscFunctionReturn(0); 7573b03a366Sstefano_zampini } 7581e6b0712SBarry Smith 7593b03a366Sstefano_zampini /*@ 76028509bceSStefano Zampini PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem. 7613b03a366Sstefano_zampini 762785d1243SStefano Zampini Collective 7633b03a366Sstefano_zampini 7643b03a366Sstefano_zampini Input Parameters: 7653b03a366Sstefano_zampini + pc - the preconditioning context 766785d1243SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries 7673b03a366Sstefano_zampini 7683b03a366Sstefano_zampini Level: intermediate 7693b03a366Sstefano_zampini 7700f202f7eSStefano Zampini Notes: 7710f202f7eSStefano Zampini Provide the information if you used MatZeroRows/Columns routines. Any process can list any global node 7723b03a366Sstefano_zampini 7730f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundariesLocal(), MatZeroRows(), MatZeroRowsColumns() 7743b03a366Sstefano_zampini @*/ 7753b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 7763b03a366Sstefano_zampini { 7773b03a366Sstefano_zampini PetscErrorCode ierr; 7783b03a366Sstefano_zampini 7793b03a366Sstefano_zampini PetscFunctionBegin; 7803b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 781674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 782785d1243SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 7833b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 7843b03a366Sstefano_zampini PetscFunctionReturn(0); 7853b03a366Sstefano_zampini } 7861e6b0712SBarry Smith 78782ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries) 7883b03a366Sstefano_zampini { 7893b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 79056282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 7913b03a366Sstefano_zampini PetscErrorCode ierr; 7923b03a366Sstefano_zampini 7933b03a366Sstefano_zampini PetscFunctionBegin; 79456282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 79556282151SStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 79656282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundariesLocal,&isequal);CHKERRQ(ierr); 79756282151SStefano Zampini } 798a5b23f4aSJose E. Roman /* last user setting takes precedence -> destroy any other customization */ 799785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 8003b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 801785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = DirichletBoundaries; 80256282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 8033b03a366Sstefano_zampini PetscFunctionReturn(0); 8043b03a366Sstefano_zampini } 8053b03a366Sstefano_zampini 8063b03a366Sstefano_zampini /*@ 80782ba6b80SStefano Zampini PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering. 8083b03a366Sstefano_zampini 809785d1243SStefano Zampini Collective 8103b03a366Sstefano_zampini 8113b03a366Sstefano_zampini Input Parameters: 8123b03a366Sstefano_zampini + pc - the preconditioning context 81382ba6b80SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering) 8143b03a366Sstefano_zampini 8153b03a366Sstefano_zampini Level: intermediate 8163b03a366Sstefano_zampini 8173b03a366Sstefano_zampini Notes: 8183b03a366Sstefano_zampini 8190f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundaries(), MatZeroRows(), MatZeroRowsColumns() 8203b03a366Sstefano_zampini @*/ 82182ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries) 8223b03a366Sstefano_zampini { 8233b03a366Sstefano_zampini PetscErrorCode ierr; 8243b03a366Sstefano_zampini 8253b03a366Sstefano_zampini PetscFunctionBegin; 8263b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 8273b03a366Sstefano_zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 82882ba6b80SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 82982ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 8303b03a366Sstefano_zampini PetscFunctionReturn(0); 8313b03a366Sstefano_zampini } 8323b03a366Sstefano_zampini 83353cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 8340c7d97c5SJed Brown { 8350c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 83656282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 83753cdbc3dSStefano Zampini PetscErrorCode ierr; 8380c7d97c5SJed Brown 8390c7d97c5SJed Brown PetscFunctionBegin; 84056282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 84156282151SStefano Zampini if (pcbddc->NeumannBoundaries) { 84256282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundaries,&isequal);CHKERRQ(ierr); 84356282151SStefano Zampini } 844a5b23f4aSJose E. Roman /* last user setting takes precedence -> destroy any other customization */ 845785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 84653cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 84736e030ebSStefano Zampini pcbddc->NeumannBoundaries = NeumannBoundaries; 84856282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 8490c7d97c5SJed Brown PetscFunctionReturn(0); 8500c7d97c5SJed Brown } 8511e6b0712SBarry Smith 85257527edcSJed Brown /*@ 85328509bceSStefano Zampini PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem. 85457527edcSJed Brown 855785d1243SStefano Zampini Collective 85657527edcSJed Brown 85757527edcSJed Brown Input Parameters: 85857527edcSJed Brown + pc - the preconditioning context 859785d1243SStefano Zampini - NeumannBoundaries - parallel IS defining the Neumann boundaries 86057527edcSJed Brown 86157527edcSJed Brown Level: intermediate 86257527edcSJed Brown 8630f202f7eSStefano Zampini Notes: 8640f202f7eSStefano Zampini Any process can list any global node 86557527edcSJed Brown 8660f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundariesLocal() 86757527edcSJed Brown @*/ 86853cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 8690c7d97c5SJed Brown { 8700c7d97c5SJed Brown PetscErrorCode ierr; 8710c7d97c5SJed Brown 8720c7d97c5SJed Brown PetscFunctionBegin; 8730c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 874674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 875785d1243SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 87653cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 87753cdbc3dSStefano Zampini PetscFunctionReturn(0); 87853cdbc3dSStefano Zampini } 8791e6b0712SBarry Smith 88082ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries) 8810c7d97c5SJed Brown { 8820c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 88356282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 8840c7d97c5SJed Brown PetscErrorCode ierr; 8850c7d97c5SJed Brown 8860c7d97c5SJed Brown PetscFunctionBegin; 88756282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 88856282151SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 88956282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundariesLocal,&isequal);CHKERRQ(ierr); 89056282151SStefano Zampini } 891a5b23f4aSJose E. Roman /* last user setting takes precedence -> destroy any other customization */ 892785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 8930c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 894785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = NeumannBoundaries; 89556282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 8960c7d97c5SJed Brown PetscFunctionReturn(0); 8970c7d97c5SJed Brown } 8980c7d97c5SJed Brown 8990c7d97c5SJed Brown /*@ 90082ba6b80SStefano Zampini PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering. 9010c7d97c5SJed Brown 902785d1243SStefano Zampini Collective 9030c7d97c5SJed Brown 9040c7d97c5SJed Brown Input Parameters: 9050c7d97c5SJed Brown + pc - the preconditioning context 90682ba6b80SStefano Zampini - NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering) 9070c7d97c5SJed Brown 9080c7d97c5SJed Brown Level: intermediate 9090c7d97c5SJed Brown 9100c7d97c5SJed Brown Notes: 9110c7d97c5SJed Brown 9120f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundaries() 9130c7d97c5SJed Brown @*/ 91482ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries) 9150c7d97c5SJed Brown { 9160c7d97c5SJed Brown PetscErrorCode ierr; 9170c7d97c5SJed Brown 9180c7d97c5SJed Brown PetscFunctionBegin; 9190c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 9200c7d97c5SJed Brown PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 92182ba6b80SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 92282ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 92353cdbc3dSStefano Zampini PetscFunctionReturn(0); 92453cdbc3dSStefano Zampini } 92553cdbc3dSStefano Zampini 926da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 927da1bb401SStefano Zampini { 928da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 929da1bb401SStefano Zampini 930da1bb401SStefano Zampini PetscFunctionBegin; 931da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 932da1bb401SStefano Zampini PetscFunctionReturn(0); 933da1bb401SStefano Zampini } 9341e6b0712SBarry Smith 935da1bb401SStefano Zampini /*@ 936785d1243SStefano Zampini PCBDDCGetDirichletBoundaries - Get parallel IS for Dirichlet boundaries 937da1bb401SStefano Zampini 938785d1243SStefano Zampini Collective 939785d1243SStefano Zampini 940785d1243SStefano Zampini Input Parameters: 941785d1243SStefano Zampini . pc - the preconditioning context 942785d1243SStefano Zampini 943785d1243SStefano Zampini Output Parameters: 944785d1243SStefano Zampini . DirichletBoundaries - index set defining the Dirichlet boundaries 945785d1243SStefano Zampini 946785d1243SStefano Zampini Level: intermediate 947785d1243SStefano Zampini 9480f202f7eSStefano Zampini Notes: 9490f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetDirichletBoundaries 950785d1243SStefano Zampini 951785d1243SStefano Zampini .seealso: PCBDDC 952785d1243SStefano Zampini @*/ 953785d1243SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 954785d1243SStefano Zampini { 955785d1243SStefano Zampini PetscErrorCode ierr; 956785d1243SStefano Zampini 957785d1243SStefano Zampini PetscFunctionBegin; 958785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 959785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 960785d1243SStefano Zampini PetscFunctionReturn(0); 961785d1243SStefano Zampini } 962785d1243SStefano Zampini 963785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries) 964785d1243SStefano Zampini { 965785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 966785d1243SStefano Zampini 967785d1243SStefano Zampini PetscFunctionBegin; 968785d1243SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundariesLocal; 969785d1243SStefano Zampini PetscFunctionReturn(0); 970785d1243SStefano Zampini } 971785d1243SStefano Zampini 972da1bb401SStefano Zampini /*@ 97382ba6b80SStefano Zampini PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering) 974da1bb401SStefano Zampini 975785d1243SStefano Zampini Collective 976da1bb401SStefano Zampini 977da1bb401SStefano Zampini Input Parameters: 97828509bceSStefano Zampini . pc - the preconditioning context 979da1bb401SStefano Zampini 980da1bb401SStefano Zampini Output Parameters: 98128509bceSStefano Zampini . DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 982da1bb401SStefano Zampini 983da1bb401SStefano Zampini Level: intermediate 984da1bb401SStefano Zampini 985da1bb401SStefano Zampini Notes: 9860f202f7eSStefano 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). 9870f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 988da1bb401SStefano Zampini 989da1bb401SStefano Zampini .seealso: PCBDDC 990da1bb401SStefano Zampini @*/ 99182ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries) 992da1bb401SStefano Zampini { 993da1bb401SStefano Zampini PetscErrorCode ierr; 994da1bb401SStefano Zampini 995da1bb401SStefano Zampini PetscFunctionBegin; 996da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 99782ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 998da1bb401SStefano Zampini PetscFunctionReturn(0); 999da1bb401SStefano Zampini } 10001e6b0712SBarry Smith 100153cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 100253cdbc3dSStefano Zampini { 100353cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 100453cdbc3dSStefano Zampini 100553cdbc3dSStefano Zampini PetscFunctionBegin; 100653cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 100753cdbc3dSStefano Zampini PetscFunctionReturn(0); 100853cdbc3dSStefano Zampini } 10091e6b0712SBarry Smith 101053cdbc3dSStefano Zampini /*@ 1011785d1243SStefano Zampini PCBDDCGetNeumannBoundaries - Get parallel IS for Neumann boundaries 101253cdbc3dSStefano Zampini 1013785d1243SStefano Zampini Collective 1014785d1243SStefano Zampini 1015785d1243SStefano Zampini Input Parameters: 1016785d1243SStefano Zampini . pc - the preconditioning context 1017785d1243SStefano Zampini 1018785d1243SStefano Zampini Output Parameters: 1019785d1243SStefano Zampini . NeumannBoundaries - index set defining the Neumann boundaries 1020785d1243SStefano Zampini 1021785d1243SStefano Zampini Level: intermediate 1022785d1243SStefano Zampini 10230f202f7eSStefano Zampini Notes: 10240f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetNeumannBoundaries 1025785d1243SStefano Zampini 1026785d1243SStefano Zampini .seealso: PCBDDC 1027785d1243SStefano Zampini @*/ 1028785d1243SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 1029785d1243SStefano Zampini { 1030785d1243SStefano Zampini PetscErrorCode ierr; 1031785d1243SStefano Zampini 1032785d1243SStefano Zampini PetscFunctionBegin; 1033785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1034785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 1035785d1243SStefano Zampini PetscFunctionReturn(0); 1036785d1243SStefano Zampini } 1037785d1243SStefano Zampini 1038785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries) 1039785d1243SStefano Zampini { 1040785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1041785d1243SStefano Zampini 1042785d1243SStefano Zampini PetscFunctionBegin; 1043785d1243SStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundariesLocal; 1044785d1243SStefano Zampini PetscFunctionReturn(0); 1045785d1243SStefano Zampini } 1046785d1243SStefano Zampini 104753cdbc3dSStefano Zampini /*@ 104882ba6b80SStefano Zampini PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering) 104953cdbc3dSStefano Zampini 1050785d1243SStefano Zampini Collective 105153cdbc3dSStefano Zampini 105253cdbc3dSStefano Zampini Input Parameters: 105328509bceSStefano Zampini . pc - the preconditioning context 105453cdbc3dSStefano Zampini 105553cdbc3dSStefano Zampini Output Parameters: 105628509bceSStefano Zampini . NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 105753cdbc3dSStefano Zampini 105853cdbc3dSStefano Zampini Level: intermediate 105953cdbc3dSStefano Zampini 106053cdbc3dSStefano Zampini Notes: 10610f202f7eSStefano 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). 10620f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 106353cdbc3dSStefano Zampini 106453cdbc3dSStefano Zampini .seealso: PCBDDC 106553cdbc3dSStefano Zampini @*/ 106682ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries) 106753cdbc3dSStefano Zampini { 106853cdbc3dSStefano Zampini PetscErrorCode ierr; 106953cdbc3dSStefano Zampini 107053cdbc3dSStefano Zampini PetscFunctionBegin; 107153cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 107282ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 10730c7d97c5SJed Brown PetscFunctionReturn(0); 10740c7d97c5SJed Brown } 10751e6b0712SBarry Smith 10761a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 107736e030ebSStefano Zampini { 107836e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1079da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 108056282151SStefano Zampini PetscBool same_data = PETSC_FALSE; 1081da1bb401SStefano Zampini PetscErrorCode ierr; 108236e030ebSStefano Zampini 108336e030ebSStefano Zampini PetscFunctionBegin; 10848687889aSStefano Zampini if (!nvtxs) { 108504194a47SStefano Zampini if (copymode == PETSC_OWN_POINTER) { 108604194a47SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 108704194a47SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 108804194a47SStefano Zampini } 10898687889aSStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 10908687889aSStefano Zampini PetscFunctionReturn(0); 10918687889aSStefano Zampini } 109266da6bd7Sstefano_zampini if (mat_graph->nvtxs == nvtxs && mat_graph->freecsr) { /* we own the data */ 109356282151SStefano Zampini if (mat_graph->xadj == xadj && mat_graph->adjncy == adjncy) same_data = PETSC_TRUE; 109456282151SStefano Zampini if (!same_data && mat_graph->xadj[nvtxs] == xadj[nvtxs]) { 1095580bdb30SBarry Smith ierr = PetscArraycmp(xadj,mat_graph->xadj,nvtxs+1,&same_data);CHKERRQ(ierr); 10962d505d7fSStefano Zampini if (same_data) { 1097580bdb30SBarry Smith ierr = PetscArraycmp(adjncy,mat_graph->adjncy,xadj[nvtxs],&same_data);CHKERRQ(ierr); 10982d505d7fSStefano Zampini } 109956282151SStefano Zampini } 110056282151SStefano Zampini } 110156282151SStefano Zampini if (!same_data) { 1102674ae819SStefano Zampini /* free old CSR */ 1103674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 1104674ae819SStefano Zampini /* get CSR into graph structure */ 1105da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 1106854ce69bSBarry Smith ierr = PetscMalloc1(nvtxs+1,&mat_graph->xadj);CHKERRQ(ierr); 1107785e854fSJed Brown ierr = PetscMalloc1(xadj[nvtxs],&mat_graph->adjncy);CHKERRQ(ierr); 1108580bdb30SBarry Smith ierr = PetscArraycpy(mat_graph->xadj,xadj,nvtxs+1);CHKERRQ(ierr); 1109580bdb30SBarry Smith ierr = PetscArraycpy(mat_graph->adjncy,adjncy,xadj[nvtxs]);CHKERRQ(ierr); 1110a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 1111da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 11121a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 11131a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 1114a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 1115a1dbd327SStefano Zampini } else if (copymode == PETSC_USE_POINTER) { 1116a1dbd327SStefano Zampini mat_graph->xadj = (PetscInt*)xadj; 1117a1dbd327SStefano Zampini mat_graph->adjncy = (PetscInt*)adjncy; 1118a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_FALSE; 1119*98921bdaSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %D",copymode); 1120575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 112156282151SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 112256282151SStefano Zampini } 112336e030ebSStefano Zampini PetscFunctionReturn(0); 112436e030ebSStefano Zampini } 11251e6b0712SBarry Smith 112636e030ebSStefano Zampini /*@ 112754fffbccSStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local degrees of freedom. 112836e030ebSStefano Zampini 112936e030ebSStefano Zampini Not collective 113036e030ebSStefano Zampini 113136e030ebSStefano Zampini Input Parameters: 113254fffbccSStefano Zampini + pc - the preconditioning context. 113354fffbccSStefano Zampini . nvtxs - number of local vertices of the graph (i.e., the number of local dofs). 113454fffbccSStefano Zampini . xadj, adjncy - the connectivity of the dofs in CSR format. 113554fffbccSStefano Zampini - copymode - supported modes are PETSC_COPY_VALUES, PETSC_USE_POINTER or PETSC_OWN_POINTER. 113636e030ebSStefano Zampini 113736e030ebSStefano Zampini Level: intermediate 113836e030ebSStefano Zampini 113995452b02SPatrick Sanan Notes: 114095452b02SPatrick Sanan A dof is considered connected with all local dofs if xadj[dof+1]-xadj[dof] == 1 and adjncy[xadj[dof]] is negative. 114136e030ebSStefano Zampini 114228509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode 114336e030ebSStefano Zampini @*/ 11441a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 114536e030ebSStefano Zampini { 11460a545947SLisandro Dalcin void (*f)(void) = NULL; 114736e030ebSStefano Zampini PetscErrorCode ierr; 114836e030ebSStefano Zampini 114936e030ebSStefano Zampini PetscFunctionBegin; 115036e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 11518687889aSStefano Zampini if (nvtxs) { 1152674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 11531633d1f0SStefano Zampini if (xadj[nvtxs]) PetscValidIntPointer(adjncy,4); 11548687889aSStefano Zampini } 11551a83f524SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 1156575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 1157575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 1158575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 1159575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 1160575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 1161da1bb401SStefano Zampini } 116236e030ebSStefano Zampini PetscFunctionReturn(0); 116336e030ebSStefano Zampini } 11641e6b0712SBarry Smith 116563602bcaSStefano Zampini static PetscErrorCode PCBDDCSetDofsSplittingLocal_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 116663602bcaSStefano Zampini { 116763602bcaSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 116863602bcaSStefano Zampini PetscInt i; 116956282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 117063602bcaSStefano Zampini PetscErrorCode ierr; 117163602bcaSStefano Zampini 117263602bcaSStefano Zampini PetscFunctionBegin; 117356282151SStefano Zampini if (pcbddc->n_ISForDofsLocal == n_is) { 117456282151SStefano Zampini for (i=0;i<n_is;i++) { 117556282151SStefano Zampini PetscBool isequalt; 117656282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofsLocal[i],&isequalt);CHKERRQ(ierr); 117756282151SStefano Zampini if (!isequalt) break; 117856282151SStefano Zampini } 117956282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 118056282151SStefano Zampini } 118156282151SStefano Zampini for (i=0;i<n_is;i++) { 118256282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 118356282151SStefano Zampini } 118463602bcaSStefano Zampini /* Destroy ISes if they were already set */ 118563602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 118663602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 118763602bcaSStefano Zampini } 118863602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1189a5b23f4aSJose E. Roman /* last user setting takes precedence -> destroy any other customization */ 119063602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 119163602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 119263602bcaSStefano Zampini } 119363602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 119463602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 119563602bcaSStefano Zampini /* allocate space then set */ 1196d02579f5SStefano Zampini if (n_is) { 1197d02579f5SStefano Zampini ierr = PetscMalloc1(n_is,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1198d02579f5SStefano Zampini } 119963602bcaSStefano Zampini for (i=0;i<n_is;i++) { 120063602bcaSStefano Zampini pcbddc->ISForDofsLocal[i] = ISForDofs[i]; 120163602bcaSStefano Zampini } 120263602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = n_is; 120363602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 120456282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 120563602bcaSStefano Zampini PetscFunctionReturn(0); 120663602bcaSStefano Zampini } 120763602bcaSStefano Zampini 120863602bcaSStefano Zampini /*@ 120963602bcaSStefano Zampini PCBDDCSetDofsSplittingLocal - Set index sets defining fields of the local subdomain matrix 121063602bcaSStefano Zampini 121163602bcaSStefano Zampini Collective 121263602bcaSStefano Zampini 121363602bcaSStefano Zampini Input Parameters: 121463602bcaSStefano Zampini + pc - the preconditioning context 12150f202f7eSStefano Zampini . n_is - number of index sets defining the fields 12160f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in local ordering 121763602bcaSStefano Zampini 121863602bcaSStefano Zampini Level: intermediate 121963602bcaSStefano Zampini 12200f202f7eSStefano Zampini Notes: 12210f202f7eSStefano Zampini n_is should be the same among processes. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 122263602bcaSStefano Zampini 122363602bcaSStefano Zampini .seealso: PCBDDC 122463602bcaSStefano Zampini @*/ 122563602bcaSStefano Zampini PetscErrorCode PCBDDCSetDofsSplittingLocal(PC pc,PetscInt n_is, IS ISForDofs[]) 122663602bcaSStefano Zampini { 122763602bcaSStefano Zampini PetscInt i; 122863602bcaSStefano Zampini PetscErrorCode ierr; 122963602bcaSStefano Zampini 123063602bcaSStefano Zampini PetscFunctionBegin; 123163602bcaSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 123263602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 123363602bcaSStefano Zampini for (i=0;i<n_is;i++) { 123463602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 123563602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 123663602bcaSStefano Zampini } 1237e71e7a71SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplittingLocal_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 123863602bcaSStefano Zampini PetscFunctionReturn(0); 123963602bcaSStefano Zampini } 124063602bcaSStefano Zampini 12419c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 12429c0446d6SStefano Zampini { 12439c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 12449c0446d6SStefano Zampini PetscInt i; 124556282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 12469c0446d6SStefano Zampini PetscErrorCode ierr; 12479c0446d6SStefano Zampini 12489c0446d6SStefano Zampini PetscFunctionBegin; 124956282151SStefano Zampini if (pcbddc->n_ISForDofs == n_is) { 125056282151SStefano Zampini for (i=0;i<n_is;i++) { 125156282151SStefano Zampini PetscBool isequalt; 125256282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofs[i],&isequalt);CHKERRQ(ierr); 125356282151SStefano Zampini if (!isequalt) break; 125456282151SStefano Zampini } 125556282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 125656282151SStefano Zampini } 125756282151SStefano Zampini for (i=0;i<n_is;i++) { 125856282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 125956282151SStefano Zampini } 1260da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 12619c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 12629c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 12639c0446d6SStefano Zampini } 1264d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 1265a5b23f4aSJose E. Roman /* last user setting takes precedence -> destroy any other customization */ 126663602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 126763602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 126863602bcaSStefano Zampini } 126963602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 127063602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 1271da1bb401SStefano Zampini /* allocate space then set */ 1272d02579f5SStefano Zampini if (n_is) { 1273785e854fSJed Brown ierr = PetscMalloc1(n_is,&pcbddc->ISForDofs);CHKERRQ(ierr); 1274d02579f5SStefano Zampini } 12759c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 1276da1bb401SStefano Zampini pcbddc->ISForDofs[i] = ISForDofs[i]; 12779c0446d6SStefano Zampini } 12789c0446d6SStefano Zampini pcbddc->n_ISForDofs = n_is; 127963602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 128056282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 12819c0446d6SStefano Zampini PetscFunctionReturn(0); 12829c0446d6SStefano Zampini } 12831e6b0712SBarry Smith 12849c0446d6SStefano Zampini /*@ 128563602bcaSStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of the global matrix 12869c0446d6SStefano Zampini 128763602bcaSStefano Zampini Collective 12889c0446d6SStefano Zampini 12899c0446d6SStefano Zampini Input Parameters: 12909c0446d6SStefano Zampini + pc - the preconditioning context 12910f202f7eSStefano Zampini . n_is - number of index sets defining the fields 12920f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in global ordering 12939c0446d6SStefano Zampini 12949c0446d6SStefano Zampini Level: intermediate 12959c0446d6SStefano Zampini 12960f202f7eSStefano Zampini Notes: 12970f202f7eSStefano Zampini Any process can list any global node. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 12989c0446d6SStefano Zampini 12999c0446d6SStefano Zampini .seealso: PCBDDC 13009c0446d6SStefano Zampini @*/ 13019c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 13029c0446d6SStefano Zampini { 13032b510759SStefano Zampini PetscInt i; 13049c0446d6SStefano Zampini PetscErrorCode ierr; 13059c0446d6SStefano Zampini 13069c0446d6SStefano Zampini PetscFunctionBegin; 13079c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 130863602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 13092b510759SStefano Zampini for (i=0;i<n_is;i++) { 131063602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 1311a011d5a7Sstefano_zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 13122b510759SStefano Zampini } 13139c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 13149c0446d6SStefano Zampini PetscFunctionReturn(0); 13159c0446d6SStefano Zampini } 1316906d46d4SStefano Zampini 1317534831adSStefano Zampini /* 1318534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 1319534831adSStefano Zampini guess if a transformation of basis approach has been selected. 13209c0446d6SStefano Zampini 1321534831adSStefano Zampini Input Parameter: 1322966d8056SPierre Jolivet + pc - the preconditioner context 1323534831adSStefano Zampini 1324534831adSStefano Zampini Application Interface Routine: PCPreSolve() 1325534831adSStefano Zampini 1326534831adSStefano Zampini Notes: 1327534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 1328534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1329534831adSStefano Zampini */ 1330534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1331534831adSStefano Zampini { 1332534831adSStefano Zampini PetscErrorCode ierr; 1333534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1334534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 13353972b0daSStefano Zampini Vec used_vec; 13364df7a6bfSStefano Zampini PetscBool iscg = PETSC_FALSE, save_rhs = PETSC_TRUE, benign_correction_computed; 1337534831adSStefano Zampini 1338534831adSStefano Zampini PetscFunctionBegin; 13391f4df5f7SStefano Zampini /* if we are working with CG, one dirichlet solve can be avoided during Krylov iterations */ 134085c4d303SStefano Zampini if (ksp) { 13414df7a6bfSStefano Zampini PetscBool isgroppcg, ispipecg, ispipelcg, ispipecgrr; 13424df7a6bfSStefano Zampini 134385c4d303SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr); 134427b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPGROPPCG,&isgroppcg);CHKERRQ(ierr); 134527b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECG,&ispipecg);CHKERRQ(ierr); 13464df7a6bfSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECG,&ispipelcg);CHKERRQ(ierr); 1347f94e96cbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECGRR,&ispipecgrr);CHKERRQ(ierr); 13484df7a6bfSStefano Zampini iscg = (PetscBool)(iscg || isgroppcg || ispipecg || ispipelcg || ispipecgrr); 13493bf6e316SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static || !iscg || pc->mat != pc->pmat) { 135085c4d303SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 135185c4d303SStefano Zampini } 135285c4d303SStefano Zampini } 13533bf6e316SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static || pc->mat != pc->pmat) { 1354fc17d649SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 1355fc17d649SStefano Zampini } 13561f4df5f7SStefano Zampini 135785c4d303SStefano Zampini /* Creates parallel work vectors used in presolve */ 135862a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 135962a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 136062a6ff1dSStefano Zampini } 136162a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 136262a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 136362a6ff1dSStefano Zampini } 13648d00608fSStefano Zampini 136527b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_FALSE; 13663972b0daSStefano Zampini if (x) { 13673972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 13683972b0daSStefano Zampini used_vec = x; 13698d00608fSStefano Zampini } else { /* it can only happen when calling PCBDDCMatFETIDPGetRHS */ 13703972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 13713972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 13723972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 137327b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 1374266e20e9SStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 1375266e20e9SStefano Zampini save_rhs = PETSC_FALSE; 1376266e20e9SStefano Zampini pcbddc->eliminate_dirdofs = PETSC_TRUE; 13773972b0daSStefano Zampini } 13788efcfb23SStefano Zampini 13798efcfb23SStefano Zampini /* hack into ksp data structure since PCPreSolve comes earlier than setting to zero the guess in src/ksp/ksp/interface/itfunc.c */ 13803972b0daSStefano Zampini if (ksp) { 1381a0cb1b98SStefano Zampini /* store the flag for the initial guess since it will be restored back during PCPostSolve_BDDC */ 13828efcfb23SStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 13838efcfb23SStefano Zampini if (!pcbddc->ksp_guess_nonzero) { 13843972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 13853972b0daSStefano Zampini } 13863972b0daSStefano Zampini } 13873308cffdSStefano Zampini 13888d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 13893972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 139070c64980SStefano Zampini if (rhs && pcbddc->eliminate_dirdofs) { 13913975b054SStefano Zampini IS dirIS = NULL; 13923975b054SStefano Zampini 1393a07ea27aSStefano Zampini /* DirichletBoundariesLocal may not be consistent among neighbours; gets a dirichlet dofs IS from graph (may be cached) */ 13943975b054SStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 13953975b054SStefano Zampini if (dirIS) { 1396906d46d4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1397785d1243SStefano Zampini PetscInt dirsize,i,*is_indices; 13982b095fd8SStefano Zampini PetscScalar *array_x; 13992b095fd8SStefano Zampini const PetscScalar *array_diagonal; 1400785d1243SStefano Zampini 14013972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 14023972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 1403e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1404e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1405e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1406e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 140782ba6b80SStefano Zampini ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr); 14083972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 14092b095fd8SStefano Zampini ierr = VecGetArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 14103972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 14112fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 14123972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 14132b095fd8SStefano Zampini ierr = VecRestoreArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 14143972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 1415e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1416e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 14178d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 14181b968477SStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 14198efcfb23SStefano Zampini } 1420a07ea27aSStefano Zampini } 1421b76ba322SStefano Zampini 14228efcfb23SStefano Zampini /* remove the computed solution or the initial guess from the rhs */ 14238d00608fSStefano Zampini if (pcbddc->rhs_change || (ksp && pcbddc->ksp_guess_nonzero)) { 142427b6a85dSStefano Zampini /* save the original rhs */ 142527b6a85dSStefano Zampini if (save_rhs) { 142627b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 142727b6a85dSStefano Zampini save_rhs = PETSC_FALSE; 14288d00608fSStefano Zampini } 14298d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 14303972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 143127b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,used_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 14323972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 14338efcfb23SStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 143427b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 14357acc28cbSStefano Zampini if (ksp) { 14367acc28cbSStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_FALSE);CHKERRQ(ierr); 14377acc28cbSStefano Zampini } 14383308cffdSStefano Zampini } 14398efcfb23SStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 1440b76ba322SStefano Zampini 1441fc17d649SStefano Zampini /* compute initial vector in benign space if needed 144227b6a85dSStefano Zampini and remove non-benign solution from the rhs */ 144327b6a85dSStefano Zampini benign_correction_computed = PETSC_FALSE; 144408af2428SStefano Zampini if (rhs && pcbddc->benign_compute_correction && (pcbddc->benign_have_null || pcbddc->benign_apply_coarse_only)) { 14451f4df5f7SStefano Zampini /* compute u^*_h using ideas similar to those in Xuemin Tu's PhD thesis (see Section 4.8.1) 14461f4df5f7SStefano Zampini Recursively apply BDDC in the multilevel case */ 14470369aaf7SStefano Zampini if (!pcbddc->benign_vec) { 14480369aaf7SStefano Zampini ierr = VecDuplicate(rhs,&pcbddc->benign_vec);CHKERRQ(ierr); 14490369aaf7SStefano Zampini } 1450c69e9cc1SStefano Zampini /* keep applying coarse solver unless we no longer have benign subdomains */ 1451c69e9cc1SStefano Zampini pcbddc->benign_apply_coarse_only = pcbddc->benign_have_null ? PETSC_TRUE : PETSC_FALSE; 145227b6a85dSStefano Zampini if (!pcbddc->benign_skip_correction) { 14531dd7afcfSStefano Zampini ierr = PCApply_BDDC(pc,rhs,pcbddc->benign_vec);CHKERRQ(ierr); 14543bca92a6SStefano Zampini benign_correction_computed = PETSC_TRUE; 14551f4df5f7SStefano Zampini if (pcbddc->temp_solution_used) { 14561f4df5f7SStefano Zampini ierr = VecAXPY(pcbddc->temp_solution,1.0,pcbddc->benign_vec);CHKERRQ(ierr); 14571f4df5f7SStefano Zampini } 14581f4df5f7SStefano Zampini ierr = VecScale(pcbddc->benign_vec,-1.0);CHKERRQ(ierr); 145927b6a85dSStefano Zampini /* store the original rhs if not done earlier */ 146027b6a85dSStefano Zampini if (save_rhs) { 146127b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 146292e3dcfbSStefano Zampini } 146327b6a85dSStefano Zampini if (pcbddc->rhs_change) { 14640369aaf7SStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,rhs,rhs);CHKERRQ(ierr); 146527b6a85dSStefano Zampini } else { 146627b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 146727b6a85dSStefano Zampini } 14680369aaf7SStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 146927b6a85dSStefano Zampini } 147027b6a85dSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_FALSE; 14714df7a6bfSStefano Zampini } else { 14724df7a6bfSStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 14730369aaf7SStefano Zampini } 14742d4c4fecSStefano Zampini 14752d4c4fecSStefano Zampini /* dbg output */ 1476a198735bSStefano Zampini if (pcbddc->dbg_flag && benign_correction_computed) { 14771f4df5f7SStefano Zampini Vec v; 1478c69e9cc1SStefano Zampini 14791f4df5f7SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&v);CHKERRQ(ierr); 1480c69e9cc1SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 14811f4df5f7SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,v);CHKERRQ(ierr); 1482c69e9cc1SStefano Zampini } else { 1483c69e9cc1SStefano Zampini ierr = VecCopy(rhs,v);CHKERRQ(ierr); 1484c69e9cc1SStefano Zampini } 14851f4df5f7SStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,v,PETSC_TRUE);CHKERRQ(ierr); 1486e0fe2d75SToby Isaac ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"LEVEL %D: is the correction benign?\n",pcbddc->current_level);CHKERRQ(ierr); 1487c69e9cc1SStefano Zampini ierr = PetscScalarView(pcbddc->benign_n,pcbddc->benign_p0,pcbddc->dbg_viewer);CHKERRQ(ierr); 1488c69e9cc1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 14891f4df5f7SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 14901f4df5f7SStefano Zampini } 14910369aaf7SStefano Zampini 14920369aaf7SStefano Zampini /* set initial guess if using PCG */ 14938ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 14940369aaf7SStefano Zampini if (x && pcbddc->use_exact_dirichlet_trick) { 14950369aaf7SStefano Zampini ierr = VecSet(x,0.0);CHKERRQ(ierr); 14961dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 149727b6a85dSStefano Zampini if (benign_correction_computed) { /* we have already saved the changed rhs */ 14988860a134SJunchao Zhang ierr = VecLockReadPop(pcis->vec1_global);CHKERRQ(ierr); 14991dd7afcfSStefano Zampini } else { 15001dd7afcfSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,pcis->vec1_global);CHKERRQ(ierr); 15011dd7afcfSStefano Zampini } 15021dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15031dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15041dd7afcfSStefano Zampini } else { 15050369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15060369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15071dd7afcfSStefano Zampini } 150855c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 15090369aaf7SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 151055c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 1511c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 15121dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 15131dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.);CHKERRQ(ierr); 15141dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15151dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15161dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x);CHKERRQ(ierr); 15171dd7afcfSStefano Zampini } else { 15180369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15190369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15201dd7afcfSStefano Zampini } 15210369aaf7SStefano Zampini if (ksp) { 15220369aaf7SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 15230369aaf7SStefano Zampini } 15248ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_TRUE; 1525266e20e9SStefano Zampini } else if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior && benign_correction_computed && pcbddc->use_exact_dirichlet_trick) { 15268860a134SJunchao Zhang ierr = VecLockReadPop(pcis->vec1_global);CHKERRQ(ierr); 15270369aaf7SStefano Zampini } 1528534831adSStefano Zampini PetscFunctionReturn(0); 1529534831adSStefano Zampini } 1530906d46d4SStefano Zampini 1531534831adSStefano Zampini /* 1532534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 1533534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 1534534831adSStefano Zampini 1535534831adSStefano Zampini Input Parameter: 1536966d8056SPierre Jolivet + pc - the preconditioner context 1537534831adSStefano Zampini 1538534831adSStefano Zampini Application Interface Routine: PCPostSolve() 1539534831adSStefano Zampini 1540534831adSStefano Zampini Notes: 1541534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 1542534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1543534831adSStefano Zampini */ 1544534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1545534831adSStefano Zampini { 1546534831adSStefano Zampini PetscErrorCode ierr; 1547534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1548534831adSStefano Zampini 1549534831adSStefano Zampini PetscFunctionBegin; 15503972b0daSStefano Zampini /* add solution removed in presolve */ 15516bcfc461SStefano Zampini if (x && pcbddc->rhs_change) { 155227b6a85dSStefano Zampini if (pcbddc->temp_solution_used) { 15533425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 1554af140850Sstefano_zampini } else if (pcbddc->benign_compute_correction && pcbddc->benign_vec) { 155527b6a85dSStefano Zampini ierr = VecAXPY(x,-1.0,pcbddc->benign_vec);CHKERRQ(ierr); 15563425bc38SStefano Zampini } 1557af140850Sstefano_zampini /* restore to original state (not for FETI-DP) */ 1558af140850Sstefano_zampini if (ksp) pcbddc->temp_solution_used = PETSC_FALSE; 155927b6a85dSStefano Zampini } 156027b6a85dSStefano Zampini 1561266e20e9SStefano Zampini /* restore rhs to its original state (not needed for FETI-DP) */ 15628d00608fSStefano Zampini if (rhs && pcbddc->rhs_change) { 156327b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 15648d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 1565af140850Sstefano_zampini } 15668efcfb23SStefano Zampini /* restore ksp guess state */ 15678efcfb23SStefano Zampini if (ksp) { 15688efcfb23SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 15698ae0ca82SStefano Zampini /* reset flag for exact dirichlet trick */ 15708ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 1571af140850Sstefano_zampini } 1572534831adSStefano Zampini PetscFunctionReturn(0); 1573534831adSStefano Zampini } 1574af140850Sstefano_zampini 15750c7d97c5SJed Brown /* 15760c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 15770c7d97c5SJed Brown by setting data structures and options. 15780c7d97c5SJed Brown 15790c7d97c5SJed Brown Input Parameter: 158053cdbc3dSStefano Zampini + pc - the preconditioner context 15810c7d97c5SJed Brown 15820c7d97c5SJed Brown Application Interface Routine: PCSetUp() 15830c7d97c5SJed Brown 15840c7d97c5SJed Brown Notes: 15850c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 15860c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 15870c7d97c5SJed Brown */ 158853cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 15890c7d97c5SJed Brown { 15900c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1591c703fcc7SStefano Zampini PCBDDCSubSchurs sub_schurs; 15925e8657edSStefano Zampini Mat_IS* matis; 159308122e43SStefano Zampini MatNullSpace nearnullspace; 159435509ce9Sstefano_zampini Mat lA; 159535509ce9Sstefano_zampini IS lP,zerodiag = NULL; 159691e8d312SStefano Zampini PetscInt nrows,ncols; 159786bfa4cfSStefano Zampini PetscMPIInt size; 1598c703fcc7SStefano Zampini PetscBool computesubschurs; 15998de1fae6SStefano Zampini PetscBool computeconstraintsmatrix; 16003b03f7bbSStefano Zampini PetscBool new_nearnullspace_provided,ismatis,rl; 1601c703fcc7SStefano Zampini PetscErrorCode ierr; 16020c7d97c5SJed Brown 16030c7d97c5SJed Brown PetscFunctionBegin; 16045e8657edSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATIS,&ismatis);CHKERRQ(ierr); 16056c4ed002SBarry Smith if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner requires matrix of type MATIS"); 160691e8d312SStefano Zampini ierr = MatGetSize(pc->pmat,&nrows,&ncols);CHKERRQ(ierr); 16076c4ed002SBarry Smith if (nrows != ncols) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PCBDDC preconditioner requires a square preconditioning matrix"); 1608ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRMPI(ierr); 160986bfa4cfSStefano Zampini 16105e8657edSStefano Zampini matis = (Mat_IS*)pc->pmat->data; 1611f4ddd8eeSStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other future nonoverlapping preconditioners */ 16123b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 161371582508SStefano Zampini Also, BDDC builds its own KSP for the Dirichlet problem */ 16143b03f7bbSStefano Zampini rl = pcbddc->recompute_topography; 16153b03f7bbSStefano Zampini if (!pc->setupcalled || pc->flag == DIFFERENT_NONZERO_PATTERN) rl = PETSC_TRUE; 1616820f2d46SBarry Smith ierr = MPIU_Allreduce(&rl,&pcbddc->recompute_topography,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRMPI(ierr); 1617c83e1ba7SStefano Zampini if (pcbddc->recompute_topography) { 1618c83e1ba7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 1619c83e1ba7SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1620c83e1ba7SStefano Zampini } else { 16218de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_FALSE; 1622c83e1ba7SStefano Zampini } 1623b087196eSStefano Zampini 1624b087196eSStefano Zampini /* check parameters' compatibility */ 1625b7ab4a40SStefano Zampini if (!pcbddc->use_deluxe_scaling) pcbddc->deluxe_zerorows = PETSC_FALSE; 1626bd2a564bSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_threshold[0] != 0.0 || pcbddc->adaptive_threshold[1] != 0.0); 162786bfa4cfSStefano Zampini pcbddc->use_deluxe_scaling = (PetscBool)(pcbddc->use_deluxe_scaling && size > 1); 162886bfa4cfSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_selection && size > 1); 1629bf3a8328SStefano Zampini pcbddc->adaptive_userdefined = (PetscBool)(pcbddc->adaptive_selection && pcbddc->adaptive_userdefined); 1630862806e4SStefano Zampini if (pcbddc->adaptive_selection) pcbddc->use_faces = PETSC_TRUE; 1631862806e4SStefano Zampini 16325a95e1ceSStefano Zampini computesubschurs = (PetscBool)(pcbddc->adaptive_selection || pcbddc->use_deluxe_scaling); 163316909a7fSStefano Zampini 163471582508SStefano Zampini /* activate all connected components if the netflux has been requested */ 1635bb05f991SStefano Zampini if (pcbddc->compute_nonetflux) { 1636bb05f991SStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 1637bb05f991SStefano Zampini pcbddc->use_edges = PETSC_TRUE; 1638bb05f991SStefano Zampini pcbddc->use_faces = PETSC_TRUE; 1639bb05f991SStefano Zampini } 1640bb05f991SStefano Zampini 1641f4ddd8eeSStefano Zampini /* Get stdout for dbg */ 164270cf5478SStefano Zampini if (pcbddc->dbg_flag) { 164370cf5478SStefano Zampini if (!pcbddc->dbg_viewer) { 164458a03d70SStefano Zampini pcbddc->dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pc)); 1645f4ddd8eeSStefano Zampini } 1646d9869140SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 164758a03d70SStefano Zampini ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1648f4ddd8eeSStefano Zampini } 1649f4ddd8eeSStefano Zampini 1650c703fcc7SStefano Zampini /* process topology information */ 165143371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Topology[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 165271582508SStefano Zampini if (pcbddc->recompute_topography) { 165371582508SStefano Zampini ierr = PCBDDCComputeLocalTopologyInfo(pc);CHKERRQ(ierr); 1654c703fcc7SStefano Zampini if (pcbddc->discretegradient) { 1655a13144ffSStefano Zampini ierr = PCBDDCNedelecSupport(pc);CHKERRQ(ierr); 1656a13144ffSStefano Zampini } 1657c703fcc7SStefano Zampini } 16584f819b78SStefano Zampini if (pcbddc->corner_selected) pcbddc->use_vertices = PETSC_TRUE; 1659a13144ffSStefano Zampini 1660c703fcc7SStefano Zampini /* change basis if requested by the user */ 16615e8657edSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 16625e8657edSStefano Zampini /* use_change_of_basis flag is used to automatically compute a change of basis from constraints */ 16635e8657edSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 16645e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 16655e8657edSStefano Zampini } else { 1666b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 16675e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 16685e8657edSStefano Zampini pcbddc->local_mat = matis->A; 1669d16cbb6bSStefano Zampini } 1670d16cbb6bSStefano Zampini 16714f1b2e48SStefano Zampini /* 1672c703fcc7SStefano Zampini Compute change of basis on local pressures (aka zerodiag dofs) with the benign trick 16734f1b2e48SStefano Zampini This should come earlier then PCISSetUp for extracting the correct subdomain matrices 16744f1b2e48SStefano Zampini */ 16751dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 1676d16cbb6bSStefano Zampini if (pcbddc->benign_saddle_point) { 16779f47a83aSStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 16789f47a83aSStefano Zampini 167905b28244SStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->use_change_of_basis || !computesubschurs) pcbddc->benign_change_explicit = PETSC_TRUE; 16803b03f7bbSStefano Zampini /* detect local saddle point and change the basis in pcbddc->local_mat */ 16813b03f7bbSStefano Zampini ierr = PCBDDCBenignDetectSaddlePoint(pc,(PetscBool)(!pcbddc->recompute_topography),&zerodiag);CHKERRQ(ierr); 1682a3df083aSStefano Zampini /* pop B0 mat from local mat */ 1683c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 16841dd7afcfSStefano Zampini /* give pcis a hint to not reuse submatrices during PCISCreate */ 16851dd7afcfSStefano Zampini if (pc->flag == SAME_NONZERO_PATTERN && pcis->reusesubmatrices == PETSC_TRUE) { 16861dd7afcfSStefano Zampini if (pcbddc->benign_n && (pcbddc->benign_change_explicit || pcbddc->dbg_flag)) { 16871dd7afcfSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 16881dd7afcfSStefano Zampini } else { 1689a3df083aSStefano Zampini pcis->reusesubmatrices = PETSC_TRUE; 16901dd7afcfSStefano Zampini } 1691a3df083aSStefano Zampini } else { 16929f47a83aSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 1693674ae819SStefano Zampini } 1694a3df083aSStefano Zampini } 169527b6a85dSStefano Zampini 16968037d520SStefano Zampini /* propagate relevant information */ 169706a4e24aSStefano Zampini if (matis->A->symmetric_set) { 169806a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 169906a4e24aSStefano Zampini } 170006a4e24aSStefano Zampini if (matis->A->spd_set) { 170106a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SPD,matis->A->spd);CHKERRQ(ierr); 170206a4e24aSStefano Zampini } 1703e496cd5dSStefano Zampini 17045e8657edSStefano Zampini /* Set up all the "iterative substructuring" common block without computing solvers */ 17055e8657edSStefano Zampini { 17065e8657edSStefano Zampini Mat temp_mat; 17075e8657edSStefano Zampini 17085e8657edSStefano Zampini temp_mat = matis->A; 17095e8657edSStefano Zampini matis->A = pcbddc->local_mat; 1710d9869140SStefano Zampini ierr = PCISSetUp(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 17115e8657edSStefano Zampini pcbddc->local_mat = matis->A; 17125e8657edSStefano Zampini matis->A = temp_mat; 17135e8657edSStefano Zampini } 1714684f6988SStefano Zampini 171581d14e9dSStefano Zampini /* Analyze interface */ 171664ac59b8SStefano Zampini if (!pcbddc->graphanalyzed) { 1717674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 17188de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1719345ecf6cSStefano Zampini if (pcbddc->adaptive_selection && !pcbddc->use_deluxe_scaling && !pcbddc->mat_graph->twodim) { 17204247aa23Sstefano_zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot compute the adaptive primal space for a problem with 3D edges without deluxe scaling"); 1721345ecf6cSStefano Zampini } 1722a198735bSStefano Zampini if (pcbddc->compute_nonetflux) { 1723669cc0f4SStefano Zampini MatNullSpace nnfnnsp; 1724669cc0f4SStefano Zampini 172521ef3d20SStefano Zampini if (!pcbddc->divudotp) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Missing divudotp operator"); 17268ae0ca82SStefano Zampini ierr = PCBDDCComputeNoNetFlux(pc->pmat,pcbddc->divudotp,pcbddc->divudotp_trans,pcbddc->divudotp_vl2l,pcbddc->mat_graph,&nnfnnsp);CHKERRQ(ierr); 172771582508SStefano Zampini /* TODO what if a nearnullspace is already attached? */ 17288037d520SStefano Zampini if (nnfnnsp) { 1729669cc0f4SStefano Zampini ierr = MatSetNearNullSpace(pc->pmat,nnfnnsp);CHKERRQ(ierr); 1730669cc0f4SStefano Zampini ierr = MatNullSpaceDestroy(&nnfnnsp);CHKERRQ(ierr); 1731669cc0f4SStefano Zampini } 1732674ae819SStefano Zampini } 17338037d520SStefano Zampini } 173443371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Topology[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 1735fb8d54d4SStefano Zampini 17365408967cSStefano Zampini /* check existence of a divergence free extension, i.e. 17375408967cSStefano Zampini b(v_I,p_0) = 0 for all v_I (raise error if not). 17385408967cSStefano Zampini Also, check that PCBDDCBenignGetOrSetP0 works */ 1739ff1f7e73Sstefano_zampini if (pcbddc->benign_saddle_point && pcbddc->dbg_flag > 1) { 17405408967cSStefano Zampini ierr = PCBDDCBenignCheck(pc,zerodiag);CHKERRQ(ierr); 174109f581a4SStefano Zampini } 17424f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 174306f24817SStefano Zampini 1744b96c3477SStefano Zampini /* Setup local dirichlet solver ksp_D and sub_schurs solvers */ 1745c703fcc7SStefano Zampini if (computesubschurs && pcbddc->recompute_topography) { 174608122e43SStefano Zampini ierr = PCBDDCInitSubSchurs(pc);CHKERRQ(ierr); 1747b1b3d7a2SStefano Zampini } 17489d54b7f4SStefano Zampini /* SetUp Scaling operator (scaling matrices could be needed in SubSchursSetUp)*/ 17499d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) { 17509d54b7f4SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 17519d54b7f4SStefano Zampini } 1752c703fcc7SStefano Zampini 1753c703fcc7SStefano Zampini /* finish setup solvers and do adaptive selection of constraints */ 1754b334f244SStefano Zampini sub_schurs = pcbddc->sub_schurs; 1755b334f244SStefano Zampini if (sub_schurs && sub_schurs->schur_explicit) { 17562070dbb6SStefano Zampini if (computesubschurs) { 175708122e43SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 17582070dbb6SStefano Zampini } 1759d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 1760d5574798SStefano Zampini } else { 1761d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 17622070dbb6SStefano Zampini if (computesubschurs) { 1763d5574798SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 1764d5574798SStefano Zampini } 17652070dbb6SStefano Zampini } 176608122e43SStefano Zampini if (pcbddc->adaptive_selection) { 176708122e43SStefano Zampini ierr = PCBDDCAdaptiveSelection(pc);CHKERRQ(ierr); 17688de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1769b7eb3628SStefano Zampini } 1770684f6988SStefano Zampini 1771f4ddd8eeSStefano Zampini /* infer if NullSpace object attached to Mat via MatSetNearNullSpace has changed */ 1772fb8d54d4SStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1773f4ddd8eeSStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullspace);CHKERRQ(ierr); 1774f4ddd8eeSStefano Zampini if (pcbddc->onearnullspace) { /* already used nearnullspace */ 1775f4ddd8eeSStefano Zampini if (!nearnullspace) { /* near null space attached to mat has been destroyed */ 1776f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1777f4ddd8eeSStefano Zampini } else { 1778f4ddd8eeSStefano Zampini /* determine if the two nullspaces are different (should be lightweight) */ 1779f4ddd8eeSStefano Zampini if (nearnullspace != pcbddc->onearnullspace) { 1780f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1781165b64e2SStefano Zampini } else { /* maybe the user has changed the content of the nearnullspace so check vectors ObjectStateId */ 1782f4ddd8eeSStefano Zampini PetscInt i; 1783165b64e2SStefano Zampini const Vec *nearnullvecs; 1784165b64e2SStefano Zampini PetscObjectState state; 1785165b64e2SStefano Zampini PetscInt nnsp_size; 1786165b64e2SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullspace,NULL,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1787f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1788f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&state);CHKERRQ(ierr); 1789165b64e2SStefano Zampini if (pcbddc->onearnullvecs_state[i] != state) { 1790f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1791f4ddd8eeSStefano Zampini break; 1792f4ddd8eeSStefano Zampini } 1793f4ddd8eeSStefano Zampini } 1794f4ddd8eeSStefano Zampini } 1795f4ddd8eeSStefano Zampini } 1796f4ddd8eeSStefano Zampini } else { 1797f4ddd8eeSStefano Zampini if (!nearnullspace) { /* both nearnullspaces are null */ 1798f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1799f4ddd8eeSStefano Zampini } else { /* nearnullspace attached later */ 1800f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1801f4ddd8eeSStefano Zampini } 1802f4ddd8eeSStefano Zampini } 1803f4ddd8eeSStefano Zampini 1804f4ddd8eeSStefano Zampini /* Setup constraints and related work vectors */ 1805727cdba6SStefano Zampini /* reset primal space flags */ 180643371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_LocalWork[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 1807f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 1808727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 18098de1fae6SStefano Zampini if (computeconstraintsmatrix || new_nearnullspace_provided) { 1810727cdba6SStefano Zampini /* It also sets the primal space flags */ 1811674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 18129543d0ffSStefano Zampini } 1813e7b262bdSStefano Zampini /* Allocate needed local vectors (which depends on quantities defined during ConstraintsSetUp) */ 1814f4ddd8eeSStefano Zampini ierr = PCBDDCSetUpLocalWorkVectors(pc);CHKERRQ(ierr); 18155e8657edSStefano Zampini 18165e8657edSStefano Zampini if (pcbddc->use_change_of_basis) { 18175e8657edSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 18185e8657edSStefano Zampini 18195e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 18204f1b2e48SStefano Zampini if (pcbddc->benign_change) { 18211dd7afcfSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 1822c263805aSStefano Zampini /* pop B0 from pcbddc->local_mat */ 1823c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 1824c263805aSStefano Zampini } 18255e8657edSStefano Zampini /* get submatrices */ 18265e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 18275e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 18285e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 18297dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 18307dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 18317dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 18323975b054SStefano Zampini /* set flag in pcis to not reuse submatrices during PCISCreate */ 18333975b054SStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 18349c6a02ceSStefano Zampini } else if (!pcbddc->user_ChangeOfBasisMatrix && !pcbddc->benign_change) { 1835b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 18365e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 18375e8657edSStefano Zampini pcbddc->local_mat = matis->A; 18385e8657edSStefano Zampini } 183935509ce9Sstefano_zampini 184035509ce9Sstefano_zampini /* interface pressure block row for B_C */ 184135509ce9Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lP" ,(PetscObject*)&lP);CHKERRQ(ierr); 184235509ce9Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject*)&lA);CHKERRQ(ierr); 184335509ce9Sstefano_zampini if (lA && lP) { 184435509ce9Sstefano_zampini PC_IS* pcis = (PC_IS*)pc->data; 184535509ce9Sstefano_zampini Mat B_BI,B_BB,Bt_BI,Bt_BB; 184635509ce9Sstefano_zampini PetscBool issym; 184735509ce9Sstefano_zampini ierr = MatIsSymmetric(lA,PETSC_SMALL,&issym);CHKERRQ(ierr); 18486cc1294bSstefano_zampini if (issym) { 18497dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_I_local,MAT_INITIAL_MATRIX,&B_BI);CHKERRQ(ierr); 18507dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_B_local,MAT_INITIAL_MATRIX,&B_BB);CHKERRQ(ierr); 185135509ce9Sstefano_zampini ierr = MatCreateTranspose(B_BI,&Bt_BI);CHKERRQ(ierr); 185235509ce9Sstefano_zampini ierr = MatCreateTranspose(B_BB,&Bt_BB);CHKERRQ(ierr); 185335509ce9Sstefano_zampini } else { 18547dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_I_local,MAT_INITIAL_MATRIX,&B_BI);CHKERRQ(ierr); 18557dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_B_local,MAT_INITIAL_MATRIX,&B_BB);CHKERRQ(ierr); 18567dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,pcis->is_I_local,lP,MAT_INITIAL_MATRIX,&Bt_BI);CHKERRQ(ierr); 18577dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,pcis->is_B_local,lP,MAT_INITIAL_MATRIX,&Bt_BB);CHKERRQ(ierr); 185835509ce9Sstefano_zampini } 185935509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_B_BI",(PetscObject)B_BI);CHKERRQ(ierr); 186035509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_B_BB",(PetscObject)B_BB);CHKERRQ(ierr); 186135509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_Bt_BI",(PetscObject)Bt_BI);CHKERRQ(ierr); 186235509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_Bt_BB",(PetscObject)Bt_BB);CHKERRQ(ierr); 186335509ce9Sstefano_zampini ierr = MatDestroy(&B_BI);CHKERRQ(ierr); 186435509ce9Sstefano_zampini ierr = MatDestroy(&B_BB);CHKERRQ(ierr); 186535509ce9Sstefano_zampini ierr = MatDestroy(&Bt_BI);CHKERRQ(ierr); 186635509ce9Sstefano_zampini ierr = MatDestroy(&Bt_BB);CHKERRQ(ierr); 186735509ce9Sstefano_zampini } 186843371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_LocalWork[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 186935509ce9Sstefano_zampini 1870b96c3477SStefano Zampini /* SetUp coarse and local Neumann solvers */ 187199cc7994SStefano Zampini ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr); 1872b96c3477SStefano Zampini /* SetUp Scaling operator */ 18739d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1874674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 18750c7d97c5SJed Brown } 1876c703fcc7SStefano Zampini 18771dd7afcfSStefano Zampini /* mark topography as done */ 187856282151SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 18790369aaf7SStefano Zampini 18801dd7afcfSStefano Zampini /* wrap pcis->A_IB and pcis->A_BI if we did not change explicitly the variables on the pressures */ 18811dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_FALSE);CHKERRQ(ierr); 18821dd7afcfSStefano Zampini 188358a03d70SStefano Zampini if (pcbddc->dbg_flag) { 188458a03d70SStefano Zampini ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1885d9869140SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 18862b510759SStefano Zampini } 18870c7d97c5SJed Brown PetscFunctionReturn(0); 18880c7d97c5SJed Brown } 18890c7d97c5SJed Brown 18900c7d97c5SJed Brown /* 189150efa1b5SStefano Zampini PCApply_BDDC - Applies the BDDC operator to a vector. 18920c7d97c5SJed Brown 18930c7d97c5SJed Brown Input Parameters: 18940f202f7eSStefano Zampini + pc - the preconditioner context 18950f202f7eSStefano Zampini - r - input vector (global) 18960c7d97c5SJed Brown 18970c7d97c5SJed Brown Output Parameter: 18980c7d97c5SJed Brown . z - output vector (global) 18990c7d97c5SJed Brown 19000c7d97c5SJed Brown Application Interface Routine: PCApply() 19010c7d97c5SJed Brown */ 190253cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 19030c7d97c5SJed Brown { 19040c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 19050c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1906b3338236SStefano Zampini Mat lA = NULL; 1907b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 19080c7d97c5SJed Brown PetscErrorCode ierr; 19093b03a366Sstefano_zampini const PetscScalar one = 1.0; 19103b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 19112617d88aSStefano Zampini const PetscScalar zero = 0.0; 19120c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 19130c7d97c5SJed Brown NN interface preconditioner changed to BDDC 1914b097fa66SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static == PETSC_TRUE) */ 19150c7d97c5SJed Brown 19160c7d97c5SJed Brown PetscFunctionBegin; 1917f3d41395Sstefano_zampini ierr = PetscCitationsRegister(citation,&cited);CHKERRQ(ierr); 1918b3338236SStefano Zampini if (pcbddc->switch_static) { 1919b3338236SStefano Zampini ierr = MatISGetLocalMat(pc->useAmat ? pc->mat : pc->pmat,&lA);CHKERRQ(ierr); 1920b3338236SStefano Zampini } 1921b3338236SStefano Zampini 19221dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 19231dd7afcfSStefano Zampini Vec swap; 192427b6a85dSStefano Zampini 192527b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 19261dd7afcfSStefano Zampini swap = pcbddc->work_change; 19271dd7afcfSStefano Zampini pcbddc->work_change = r; 19281dd7afcfSStefano Zampini r = swap; 19291dd7afcfSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 19309cc2a9b1Sstefano_zampini if (pcbddc->benign_apply_coarse_only && pcbddc->use_exact_dirichlet_trick && pcbddc->change_interior) { 19311dd7afcfSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 19328860a134SJunchao Zhang ierr = VecLockReadPush(pcis->vec1_global);CHKERRQ(ierr); 19331dd7afcfSStefano Zampini } 19341dd7afcfSStefano Zampini } 193527b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 1936015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1937efc2fbd9SStefano Zampini } 1938bc960bbfSJed Brown if (pcbddc->interface_extension == PC_BDDC_INTERFACE_EXT_DIRICHLET && !pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 1939b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 19400c7d97c5SJed Brown /* First Dirichlet solve */ 19410c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19420c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19430c7d97c5SJed Brown /* 19440c7d97c5SJed Brown Assembling right hand side for BDDC operator 1945b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 1946674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 19470c7d97c5SJed Brown */ 1948b097fa66SStefano Zampini if (n_D) { 194955c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 1950b097fa66SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 195155c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 1952c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 19530c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 195416909a7fSStefano Zampini if (pcbddc->switch_static) { 195516909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 195616909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 195716909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 195816909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 1959b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 196016909a7fSStefano Zampini } else { 196116909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 1962b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 196316909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 196416909a7fSStefano Zampini } 196516909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 196616909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 196716909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 196816909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 196916909a7fSStefano Zampini } else { 1970b097fa66SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 197116909a7fSStefano Zampini } 1972b097fa66SStefano Zampini } else { 1973b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1974b097fa66SStefano Zampini } 19750c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19760c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1977674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 1978b76ba322SStefano Zampini } else { 19794fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 1980674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 1981b76ba322SStefano Zampini } 19824fee134fSStefano Zampini } 1983bc960bbfSJed Brown if (pcbddc->interface_extension == PC_BDDC_INTERFACE_EXT_LUMP) { 1984bc960bbfSJed Brown if (!pcbddc->switch_static) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"You forgot to pass -pc_bddc_switch_static"); 1985bc960bbfSJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1986bc960bbfSJed Brown ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1987bc960bbfSJed Brown } 1988b76ba322SStefano Zampini 19892617d88aSStefano Zampini /* Apply interface preconditioner 19902617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1991dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 19922617d88aSStefano Zampini 1993674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 1994674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 1995bc960bbfSJed Brown if (pcbddc->interface_extension == PC_BDDC_INTERFACE_EXT_LUMP) { 1996bc960bbfSJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1997bc960bbfSJed Brown ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1998bc960bbfSJed Brown PetscFunctionReturn(0); 1999bc960bbfSJed Brown } 20003b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 20010c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20020c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2003b097fa66SStefano Zampini if (n_B) { 200416909a7fSStefano Zampini if (pcbddc->switch_static) { 200516909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 200616909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 200716909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 200816909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 200916909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 2010b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 201116909a7fSStefano Zampini } else { 201216909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 2013b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 201416909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 201516909a7fSStefano Zampini } 201616909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 201716909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 201816909a7fSStefano Zampini } else { 20190c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 202016909a7fSStefano Zampini } 202116909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 202216909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 2023b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 202416909a7fSStefano Zampini } else { 202516909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 2026b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 202716909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 202816909a7fSStefano Zampini } 2029b097fa66SStefano Zampini } 203055c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 2031df187020SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 203255c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 2033c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec4_D);CHKERRQ(ierr); 2034efc2fbd9SStefano Zampini 20358ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2036b097fa66SStefano Zampini if (pcbddc->switch_static) { 2037b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 2038b097fa66SStefano Zampini } else { 2039b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 2040b097fa66SStefano Zampini } 20410c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20420c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2043b097fa66SStefano Zampini } else { 2044b097fa66SStefano Zampini if (pcbddc->switch_static) { 2045b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 2046b097fa66SStefano Zampini } else { 2047b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 2048b097fa66SStefano Zampini } 2049b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2050b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2051b097fa66SStefano Zampini } 205227b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 20531dd7afcfSStefano Zampini if (pcbddc->benign_apply_coarse_only) { 2054580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->benign_p0,pcbddc->benign_n);CHKERRQ(ierr); 20551dd7afcfSStefano Zampini } 2056015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 2057efc2fbd9SStefano Zampini } 20581f4df5f7SStefano Zampini 20591dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2060f913dca9SStefano Zampini pcbddc->work_change = r; 20611dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 20621dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 20631dd7afcfSStefano Zampini } 20640c7d97c5SJed Brown PetscFunctionReturn(0); 20650c7d97c5SJed Brown } 206650efa1b5SStefano Zampini 206750efa1b5SStefano Zampini /* 206850efa1b5SStefano Zampini PCApplyTranspose_BDDC - Applies the transpose of the BDDC operator to a vector. 206950efa1b5SStefano Zampini 207050efa1b5SStefano Zampini Input Parameters: 20710f202f7eSStefano Zampini + pc - the preconditioner context 20720f202f7eSStefano Zampini - r - input vector (global) 207350efa1b5SStefano Zampini 207450efa1b5SStefano Zampini Output Parameter: 207550efa1b5SStefano Zampini . z - output vector (global) 207650efa1b5SStefano Zampini 207750efa1b5SStefano Zampini Application Interface Routine: PCApplyTranspose() 207850efa1b5SStefano Zampini */ 207950efa1b5SStefano Zampini PetscErrorCode PCApplyTranspose_BDDC(PC pc,Vec r,Vec z) 208050efa1b5SStefano Zampini { 208150efa1b5SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 208250efa1b5SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 2083b3338236SStefano Zampini Mat lA = NULL; 2084b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 208550efa1b5SStefano Zampini PetscErrorCode ierr; 208650efa1b5SStefano Zampini const PetscScalar one = 1.0; 208750efa1b5SStefano Zampini const PetscScalar m_one = -1.0; 208850efa1b5SStefano Zampini const PetscScalar zero = 0.0; 208950efa1b5SStefano Zampini 209050efa1b5SStefano Zampini PetscFunctionBegin; 2091f3d41395Sstefano_zampini ierr = PetscCitationsRegister(citation,&cited);CHKERRQ(ierr); 2092b3338236SStefano Zampini if (pcbddc->switch_static) { 2093b3338236SStefano Zampini ierr = MatISGetLocalMat(pc->useAmat ? pc->mat : pc->pmat,&lA);CHKERRQ(ierr); 2094b3338236SStefano Zampini } 20951dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 20961dd7afcfSStefano Zampini Vec swap; 209727b6a85dSStefano Zampini 209827b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 20991dd7afcfSStefano Zampini swap = pcbddc->work_change; 21001dd7afcfSStefano Zampini pcbddc->work_change = r; 21011dd7afcfSStefano Zampini r = swap; 210227b6a85dSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 21038ae0ca82SStefano Zampini if (pcbddc->benign_apply_coarse_only && pcbddc->exact_dirichlet_trick_app && pcbddc->change_interior) { 210427b6a85dSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 21058860a134SJunchao Zhang ierr = VecLockReadPush(pcis->vec1_global);CHKERRQ(ierr); 21061dd7afcfSStefano Zampini } 210727b6a85dSStefano Zampini } 210827b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 2109537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 2110537c1cdfSStefano Zampini } 21118ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2112b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 211350efa1b5SStefano Zampini /* First Dirichlet solve */ 211450efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 211550efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 211650efa1b5SStefano Zampini /* 211750efa1b5SStefano Zampini Assembling right hand side for BDDC operator 2118b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 211950efa1b5SStefano Zampini - pcis->vec1_B the interface part of the global vector z 212050efa1b5SStefano Zampini */ 2121b097fa66SStefano Zampini if (n_D) { 212255c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 2123b097fa66SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 212455c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 2125c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 212650efa1b5SStefano Zampini ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 212716909a7fSStefano Zampini if (pcbddc->switch_static) { 212816909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 212916909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 213016909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 213116909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 2132b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 213316909a7fSStefano Zampini } else { 213416909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 2135b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 213616909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 213716909a7fSStefano Zampini } 213816909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 213916909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 214016909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 214116909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 214216909a7fSStefano Zampini } else { 2143b097fa66SStefano Zampini ierr = MatMultTranspose(pcis->A_IB,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 214416909a7fSStefano Zampini } 2145b097fa66SStefano Zampini } else { 2146b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 2147b097fa66SStefano Zampini } 214850efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 214950efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 215050efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 215150efa1b5SStefano Zampini } else { 215250efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 215350efa1b5SStefano Zampini } 215450efa1b5SStefano Zampini 215550efa1b5SStefano Zampini /* Apply interface preconditioner 215650efa1b5SStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 2157dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_TRUE);CHKERRQ(ierr); 215850efa1b5SStefano Zampini 215950efa1b5SStefano Zampini /* Apply transpose of partition of unity operator */ 216050efa1b5SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 216150efa1b5SStefano Zampini 216250efa1b5SStefano Zampini /* Second Dirichlet solve and assembling of output */ 216350efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 216450efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2165b097fa66SStefano Zampini if (n_B) { 216616909a7fSStefano Zampini if (pcbddc->switch_static) { 216716909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 216816909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 216916909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 217016909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 217116909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 2172b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 217316909a7fSStefano Zampini } else { 217416909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 2175b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 217616909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 217716909a7fSStefano Zampini } 217816909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 217916909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 218016909a7fSStefano Zampini } else { 218150efa1b5SStefano Zampini ierr = MatMultTranspose(pcis->A_BI,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 218216909a7fSStefano Zampini } 218316909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 218416909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 2185b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 218616909a7fSStefano Zampini } else { 218716909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 2188b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 218916909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 219016909a7fSStefano Zampini } 2191b097fa66SStefano Zampini } 219255c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 2193b0147a47SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 219455c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 2195c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec4_D);CHKERRQ(ierr); 21968ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2197b097fa66SStefano Zampini if (pcbddc->switch_static) { 2198b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 2199b097fa66SStefano Zampini } else { 2200b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 2201b097fa66SStefano Zampini } 220250efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 220350efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2204b097fa66SStefano Zampini } else { 2205b097fa66SStefano Zampini if (pcbddc->switch_static) { 2206b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 2207b097fa66SStefano Zampini } else { 2208b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 2209b097fa66SStefano Zampini } 2210b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2211b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2212b097fa66SStefano Zampini } 221327b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 2214537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 2215537c1cdfSStefano Zampini } 22161dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2217f913dca9SStefano Zampini pcbddc->work_change = r; 22181dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 22191dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 22201dd7afcfSStefano Zampini } 222150efa1b5SStefano Zampini PetscFunctionReturn(0); 222250efa1b5SStefano Zampini } 2223674ae819SStefano Zampini 22249326c5c6Sstefano_zampini PetscErrorCode PCReset_BDDC(PC pc) 2225da1bb401SStefano Zampini { 2226da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 22279326c5c6Sstefano_zampini PC_IS *pcis = (PC_IS*)pc->data; 22289326c5c6Sstefano_zampini KSP kspD,kspR,kspC; 2229da1bb401SStefano Zampini PetscErrorCode ierr; 2230da1bb401SStefano Zampini 2231da1bb401SStefano Zampini PetscFunctionBegin; 2232674ae819SStefano Zampini /* free BDDC custom data */ 2233674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 2234674ae819SStefano Zampini /* destroy objects related to topography */ 2235674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 223634a97f8cSStefano Zampini /* destroy objects for scaling operator */ 2237674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 2238674ae819SStefano Zampini /* free solvers stuff */ 2239674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 224062a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 224162a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 224262a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 22431dd7afcfSStefano Zampini /* free data created by PCIS */ 22441dd7afcfSStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 22459326c5c6Sstefano_zampini 22469326c5c6Sstefano_zampini /* restore defaults */ 22479326c5c6Sstefano_zampini kspD = pcbddc->ksp_D; 22489326c5c6Sstefano_zampini kspR = pcbddc->ksp_R; 22499326c5c6Sstefano_zampini kspC = pcbddc->coarse_ksp; 22509326c5c6Sstefano_zampini ierr = PetscMemzero(pc->data,sizeof(*pcbddc));CHKERRQ(ierr); 22519326c5c6Sstefano_zampini pcis->n_neigh = -1; 22529326c5c6Sstefano_zampini pcis->scaling_factor = 1.0; 22539326c5c6Sstefano_zampini pcis->reusesubmatrices = PETSC_TRUE; 22549326c5c6Sstefano_zampini pcbddc->use_local_adj = PETSC_TRUE; 22559326c5c6Sstefano_zampini pcbddc->use_vertices = PETSC_TRUE; 22569326c5c6Sstefano_zampini pcbddc->use_edges = PETSC_TRUE; 22579326c5c6Sstefano_zampini pcbddc->symmetric_primal = PETSC_TRUE; 22589326c5c6Sstefano_zampini pcbddc->vertex_size = 1; 22599326c5c6Sstefano_zampini pcbddc->recompute_topography = PETSC_TRUE; 22609326c5c6Sstefano_zampini pcbddc->coarse_size = -1; 22619326c5c6Sstefano_zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 22629326c5c6Sstefano_zampini pcbddc->coarsening_ratio = 8; 22639326c5c6Sstefano_zampini pcbddc->coarse_eqs_per_proc = 1; 22649326c5c6Sstefano_zampini pcbddc->benign_compute_correction = PETSC_TRUE; 22659326c5c6Sstefano_zampini pcbddc->nedfield = -1; 22669326c5c6Sstefano_zampini pcbddc->nedglobal = PETSC_TRUE; 22679326c5c6Sstefano_zampini pcbddc->graphmaxcount = PETSC_MAX_INT; 22689326c5c6Sstefano_zampini pcbddc->sub_schurs_layers = -1; 22699326c5c6Sstefano_zampini pcbddc->ksp_D = kspD; 22709326c5c6Sstefano_zampini pcbddc->ksp_R = kspR; 22719326c5c6Sstefano_zampini pcbddc->coarse_ksp = kspC; 22729326c5c6Sstefano_zampini PetscFunctionReturn(0); 22739326c5c6Sstefano_zampini } 22749326c5c6Sstefano_zampini 22759326c5c6Sstefano_zampini PetscErrorCode PCDestroy_BDDC(PC pc) 22769326c5c6Sstefano_zampini { 22779326c5c6Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 22789326c5c6Sstefano_zampini PetscErrorCode ierr; 22799326c5c6Sstefano_zampini 22809326c5c6Sstefano_zampini PetscFunctionBegin; 22819326c5c6Sstefano_zampini ierr = PCReset_BDDC(pc);CHKERRQ(ierr); 22829326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 22839326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 22849326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 2285a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",NULL);CHKERRQ(ierr); 2286a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",NULL);CHKERRQ(ierr); 2287906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",NULL);CHKERRQ(ierr); 2288674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 228930368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",NULL);CHKERRQ(ierr); 2290bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 22912b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr); 2292b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr); 22932b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr); 2294bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 229582ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2296bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 229782ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2298bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 229982ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2300bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 2301785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2302bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 230363602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",NULL);CHKERRQ(ierr); 2304bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 2305bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 2306bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 2307bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 2308a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",NULL);CHKERRQ(ierr); 2309ab8c8b98SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",NULL);CHKERRQ(ierr); 2310674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 2311da1bb401SStefano Zampini PetscFunctionReturn(0); 2312da1bb401SStefano Zampini } 23131e6b0712SBarry Smith 2314ab8c8b98SStefano Zampini static PetscErrorCode PCSetCoordinates_BDDC(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 2315ab8c8b98SStefano Zampini { 2316ab8c8b98SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2317ab8c8b98SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 2318ab8c8b98SStefano Zampini PetscErrorCode ierr; 2319ab8c8b98SStefano Zampini 2320ab8c8b98SStefano Zampini PetscFunctionBegin; 2321ab8c8b98SStefano Zampini ierr = PetscFree(mat_graph->coords);CHKERRQ(ierr); 2322ab8c8b98SStefano Zampini ierr = PetscMalloc1(nloc*dim,&mat_graph->coords);CHKERRQ(ierr); 2323580bdb30SBarry Smith ierr = PetscArraycpy(mat_graph->coords,coords,nloc*dim);CHKERRQ(ierr); 2324ab8c8b98SStefano Zampini mat_graph->cnloc = nloc; 2325ab8c8b98SStefano Zampini mat_graph->cdim = dim; 2326ab8c8b98SStefano Zampini mat_graph->cloc = PETSC_FALSE; 23274f819b78SStefano Zampini /* flg setup */ 23284f819b78SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 23294f819b78SStefano Zampini pcbddc->corner_selected = PETSC_FALSE; 2330ab8c8b98SStefano Zampini PetscFunctionReturn(0); 2331ab8c8b98SStefano Zampini } 2332ab8c8b98SStefano Zampini 2333a06fd7f2SStefano Zampini static PetscErrorCode PCPreSolveChangeRHS_BDDC(PC pc, PetscBool* change) 2334a06fd7f2SStefano Zampini { 2335a06fd7f2SStefano Zampini PetscFunctionBegin; 2336a06fd7f2SStefano Zampini *change = PETSC_TRUE; 2337a06fd7f2SStefano Zampini PetscFunctionReturn(0); 2338a06fd7f2SStefano Zampini } 2339a06fd7f2SStefano Zampini 23403425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 23413425bc38SStefano Zampini { 2342674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 2343266e20e9SStefano Zampini Vec work; 23443425bc38SStefano Zampini PC_IS* pcis; 23453425bc38SStefano Zampini PC_BDDC* pcbddc; 23463425bc38SStefano Zampini PetscErrorCode ierr; 23470c7d97c5SJed Brown 23483425bc38SStefano Zampini PetscFunctionBegin; 23493425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 23503425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 23513425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 23523425bc38SStefano Zampini 2353229984c5Sstefano_zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 2354229984c5Sstefano_zampini /* copy rhs since we may change it during PCPreSolve_BDDC */ 2355229984c5Sstefano_zampini if (!pcbddc->original_rhs) { 2356229984c5Sstefano_zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 2357229984c5Sstefano_zampini } 23586cc1294bSstefano_zampini if (mat_ctx->rhs_flip) { 23596cc1294bSstefano_zampini ierr = VecPointwiseMult(pcbddc->original_rhs,standard_rhs,mat_ctx->rhs_flip);CHKERRQ(ierr); 23606cc1294bSstefano_zampini } else { 2361229984c5Sstefano_zampini ierr = VecCopy(standard_rhs,pcbddc->original_rhs);CHKERRQ(ierr); 23626cc1294bSstefano_zampini } 2363af140850Sstefano_zampini if (mat_ctx->g2g_p) { 2364229984c5Sstefano_zampini /* interface pressure rhs */ 2365022d8d2bSstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,fetidp_flux_rhs,pcbddc->original_rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2366022d8d2bSstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,fetidp_flux_rhs,pcbddc->original_rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2367229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,standard_rhs,fetidp_flux_rhs,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2368229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,standard_rhs,fetidp_flux_rhs,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23696cc1294bSstefano_zampini if (!mat_ctx->rhs_flip) { 2370229984c5Sstefano_zampini ierr = VecScale(fetidp_flux_rhs,-1.);CHKERRQ(ierr); 2371229984c5Sstefano_zampini } 23726cc1294bSstefano_zampini } 2373c08af4c6SStefano Zampini /* 2374c08af4c6SStefano Zampini change of basis for physical rhs if needed 2375c08af4c6SStefano Zampini It also changes the rhs in case of dirichlet boundaries 2376c08af4c6SStefano Zampini */ 23773738a8e6SStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,pcbddc->original_rhs,NULL);CHKERRQ(ierr); 2378fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 23793738a8e6SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcbddc->original_rhs,pcbddc->work_change);CHKERRQ(ierr); 23803738a8e6SStefano Zampini work = pcbddc->work_change; 2381fc17d649SStefano Zampini } else { 23823738a8e6SStefano Zampini work = pcbddc->original_rhs; 2383fc17d649SStefano Zampini } 23843425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 2385266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2386266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2387fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 2388fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 2389266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2390266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2391674ae819SStefano Zampini /* Apply partition of unity */ 23923425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 2393266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 23948eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 23953425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 239655c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][0],mat_ctx->pc,0,0,0);CHKERRQ(ierr); 23973425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 239855c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][0],mat_ctx->pc,0,0,0);CHKERRQ(ierr); 2399c0decd05SBarry Smith /* Cannot propagate up error in KSPSolve() because there is no access to the PC */ 24003425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 24013425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 2402266e20e9SStefano Zampini ierr = VecSet(work,0.0);CHKERRQ(ierr); 2403266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2404266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2405266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 2406266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2407266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 24083425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 24093425bc38SStefano Zampini } 24103425bc38SStefano Zampini /* BDDC rhs */ 24113425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 24128eeda7d8SStefano Zampini if (pcbddc->switch_static) { 24133425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 24143425bc38SStefano Zampini } 24153425bc38SStefano Zampini /* apply BDDC */ 2416580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->benign_p0,pcbddc->benign_n);CHKERRQ(ierr); 2417dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2418580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->benign_p0,pcbddc->benign_n);CHKERRQ(ierr); 2419229984c5Sstefano_zampini 24203425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 24213425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 24223425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 24233425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2424229984c5Sstefano_zampini /* Add contribution to interface pressures */ 2425229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2426229984c5Sstefano_zampini ierr = MatMult(mat_ctx->B_BB,pcis->vec1_B,mat_ctx->vP);CHKERRQ(ierr); 2427229984c5Sstefano_zampini if (pcbddc->switch_static) { 2428229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->B_BI,pcis->vec1_D,mat_ctx->vP,mat_ctx->vP);CHKERRQ(ierr); 2429229984c5Sstefano_zampini } 2430229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->l2g_p,mat_ctx->vP,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2431229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->l2g_p,mat_ctx->vP,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2432229984c5Sstefano_zampini } 24333425bc38SStefano Zampini PetscFunctionReturn(0); 24343425bc38SStefano Zampini } 24351e6b0712SBarry Smith 24363425bc38SStefano Zampini /*@ 24370f202f7eSStefano Zampini PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETI-DP linear system using the physical right-hand side 24383425bc38SStefano Zampini 24393425bc38SStefano Zampini Collective 24403425bc38SStefano Zampini 24413425bc38SStefano Zampini Input Parameters: 24420f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix object obtained by a call to PCBDDCCreateFETIDPOperators 24430f202f7eSStefano Zampini - standard_rhs - the right-hand side of the original linear system 24443425bc38SStefano Zampini 24453425bc38SStefano Zampini Output Parameters: 24460f202f7eSStefano Zampini . fetidp_flux_rhs - the right-hand side for the FETI-DP linear system 24473425bc38SStefano Zampini 24483425bc38SStefano Zampini Level: developer 24493425bc38SStefano Zampini 24503425bc38SStefano Zampini Notes: 24513425bc38SStefano Zampini 24520f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetSolution 24533425bc38SStefano Zampini @*/ 24543425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 24553425bc38SStefano Zampini { 2456674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 24573425bc38SStefano Zampini PetscErrorCode ierr; 24583425bc38SStefano Zampini 24593425bc38SStefano Zampini PetscFunctionBegin; 2460266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2461266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_rhs,VEC_CLASSID,2); 2462266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_rhs,VEC_CLASSID,3); 24633425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2464163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 24653425bc38SStefano Zampini PetscFunctionReturn(0); 24663425bc38SStefano Zampini } 24671e6b0712SBarry Smith 24683425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 24693425bc38SStefano Zampini { 2470674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 24713425bc38SStefano Zampini PC_IS* pcis; 24723425bc38SStefano Zampini PC_BDDC* pcbddc; 24733425bc38SStefano Zampini PetscErrorCode ierr; 2474229984c5Sstefano_zampini Vec work; 24753425bc38SStefano Zampini 24763425bc38SStefano Zampini PetscFunctionBegin; 24773425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 24783425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 24793425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 24803425bc38SStefano Zampini 24813425bc38SStefano Zampini /* apply B_delta^T */ 2482af140850Sstefano_zampini ierr = VecSet(pcis->vec1_B,0.);CHKERRQ(ierr); 24833425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24843425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24853425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 2486229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2487229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->l2g_p,fetidp_flux_sol,mat_ctx->vP,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2488229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->l2g_p,fetidp_flux_sol,mat_ctx->vP,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2489229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->Bt_BB,mat_ctx->vP,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 2490229984c5Sstefano_zampini } 2491229984c5Sstefano_zampini 24923425bc38SStefano Zampini /* compute rhs for BDDC application */ 24933425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 24948eeda7d8SStefano Zampini if (pcbddc->switch_static) { 24953425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 2496229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2497229984c5Sstefano_zampini ierr = VecScale(mat_ctx->vP,-1.);CHKERRQ(ierr); 2498229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->Bt_BI,mat_ctx->vP,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); 24993425bc38SStefano Zampini } 2500229984c5Sstefano_zampini } 2501229984c5Sstefano_zampini 25023425bc38SStefano Zampini /* apply BDDC */ 2503580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->benign_p0,pcbddc->benign_n);CHKERRQ(ierr); 2504dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2505229984c5Sstefano_zampini 2506229984c5Sstefano_zampini /* put values into global vector */ 2507af140850Sstefano_zampini if (pcbddc->ChangeOfBasisMatrix) work = pcbddc->work_change; 2508af140850Sstefano_zampini else work = standard_sol; 2509229984c5Sstefano_zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2510229984c5Sstefano_zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 25118eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 25123425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 25133425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 251400f6b531SStefano Zampini ierr = VecAYPX(pcis->vec1_D,-1.0,mat_ctx->temp_solution_D);CHKERRQ(ierr); 251555c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][0],mat_ctx->pc,0,0,0);CHKERRQ(ierr); 251600f6b531SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); 251755c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][0],mat_ctx->pc,0,0,0);CHKERRQ(ierr); 2518c0decd05SBarry Smith /* Cannot propagate up error in KSPSolve() because there is no access to the PC */ 25193425bc38SStefano Zampini } 2520229984c5Sstefano_zampini 2521229984c5Sstefano_zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2522229984c5Sstefano_zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_D,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2523266e20e9SStefano Zampini /* add p0 solution to final solution */ 2524229984c5Sstefano_zampini ierr = PCBDDCBenignGetOrSetP0(mat_ctx->pc,work,PETSC_FALSE);CHKERRQ(ierr); 2525fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2526af140850Sstefano_zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,work,standard_sol);CHKERRQ(ierr); 2527fc17d649SStefano Zampini } 2528af140850Sstefano_zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 2529af140850Sstefano_zampini if (mat_ctx->g2g_p) { 2530229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,fetidp_flux_sol,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2531229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,fetidp_flux_sol,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2532229984c5Sstefano_zampini } 25333425bc38SStefano Zampini PetscFunctionReturn(0); 25343425bc38SStefano Zampini } 25351e6b0712SBarry Smith 25365a1e936bSStefano Zampini static PetscErrorCode PCView_BDDCIPC(PC pc, PetscViewer viewer) 25375a1e936bSStefano Zampini { 25385a1e936bSStefano Zampini PetscErrorCode ierr; 25395a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25405a1e936bSStefano Zampini PetscBool isascii; 25415a1e936bSStefano Zampini 25425a1e936bSStefano Zampini PetscFunctionBegin; 25433ec1f749SStefano Zampini ierr = PCShellGetContext(pc,&bddcipc_ctx);CHKERRQ(ierr); 25445a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 25455a1e936bSStefano Zampini if (isascii) { 25465a1e936bSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"BDDC interface preconditioner\n");CHKERRQ(ierr); 25475a1e936bSStefano Zampini } 25485a1e936bSStefano Zampini ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 25495a1e936bSStefano Zampini ierr = PCView(bddcipc_ctx->bddc,viewer);CHKERRQ(ierr); 25505a1e936bSStefano Zampini ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 25515a1e936bSStefano Zampini PetscFunctionReturn(0); 25525a1e936bSStefano Zampini } 25535a1e936bSStefano Zampini 25545a1e936bSStefano Zampini static PetscErrorCode PCSetUp_BDDCIPC(PC pc) 25555a1e936bSStefano Zampini { 25565a1e936bSStefano Zampini PetscErrorCode ierr; 25575a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25585a1e936bSStefano Zampini PetscBool isbddc; 25595a1e936bSStefano Zampini Vec vv; 25605a1e936bSStefano Zampini IS is; 25615a1e936bSStefano Zampini PC_IS *pcis; 25625a1e936bSStefano Zampini 25635a1e936bSStefano Zampini PetscFunctionBegin; 25643ec1f749SStefano Zampini ierr = PCShellGetContext(pc,&bddcipc_ctx);CHKERRQ(ierr); 25655a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)bddcipc_ctx->bddc,PCBDDC,&isbddc);CHKERRQ(ierr); 2566*98921bdaSJacob Faibussowitsch if (!isbddc) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid type %s. Must be of type bddc",((PetscObject)bddcipc_ctx->bddc)->type_name); 25675a1e936bSStefano Zampini ierr = PCSetUp(bddcipc_ctx->bddc);CHKERRQ(ierr); 25685a1e936bSStefano Zampini 25695a1e936bSStefano Zampini /* create interface scatter */ 25705a1e936bSStefano Zampini pcis = (PC_IS*)(bddcipc_ctx->bddc->data); 25715a1e936bSStefano Zampini ierr = VecScatterDestroy(&bddcipc_ctx->g2l);CHKERRQ(ierr); 25725a1e936bSStefano Zampini ierr = MatCreateVecs(pc->pmat,&vv,NULL);CHKERRQ(ierr); 25735a1e936bSStefano Zampini ierr = ISRenumber(pcis->is_B_global,NULL,NULL,&is);CHKERRQ(ierr); 25749448b7f1SJunchao Zhang ierr = VecScatterCreate(vv,is,pcis->vec1_B,NULL,&bddcipc_ctx->g2l);CHKERRQ(ierr); 25755a1e936bSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 25765a1e936bSStefano Zampini ierr = VecDestroy(&vv);CHKERRQ(ierr); 25775a1e936bSStefano Zampini PetscFunctionReturn(0); 25785a1e936bSStefano Zampini } 25795a1e936bSStefano Zampini 25805a1e936bSStefano Zampini static PetscErrorCode PCApply_BDDCIPC(PC pc, Vec r, Vec x) 25815a1e936bSStefano Zampini { 25825a1e936bSStefano Zampini PetscErrorCode ierr; 25835a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25845a1e936bSStefano Zampini PC_IS *pcis; 25855a1e936bSStefano Zampini VecScatter tmps; 25865a1e936bSStefano Zampini 25875a1e936bSStefano Zampini PetscFunctionBegin; 25883ec1f749SStefano Zampini ierr = PCShellGetContext(pc,&bddcipc_ctx);CHKERRQ(ierr); 25895a1e936bSStefano Zampini pcis = (PC_IS*)(bddcipc_ctx->bddc->data); 25905a1e936bSStefano Zampini tmps = pcis->global_to_B; 25915a1e936bSStefano Zampini pcis->global_to_B = bddcipc_ctx->g2l; 25925a1e936bSStefano Zampini ierr = PCBDDCScalingRestriction(bddcipc_ctx->bddc,r,pcis->vec1_B);CHKERRQ(ierr); 25935a1e936bSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(bddcipc_ctx->bddc,PETSC_FALSE);CHKERRQ(ierr); 25945a1e936bSStefano Zampini ierr = PCBDDCScalingExtension(bddcipc_ctx->bddc,pcis->vec1_B,x);CHKERRQ(ierr); 25955a1e936bSStefano Zampini pcis->global_to_B = tmps; 25965a1e936bSStefano Zampini PetscFunctionReturn(0); 25975a1e936bSStefano Zampini } 25985a1e936bSStefano Zampini 25995a1e936bSStefano Zampini static PetscErrorCode PCApplyTranspose_BDDCIPC(PC pc, Vec r, Vec x) 26005a1e936bSStefano Zampini { 26015a1e936bSStefano Zampini PetscErrorCode ierr; 26025a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 26035a1e936bSStefano Zampini PC_IS *pcis; 26045a1e936bSStefano Zampini VecScatter tmps; 26055a1e936bSStefano Zampini 26065a1e936bSStefano Zampini PetscFunctionBegin; 26073ec1f749SStefano Zampini ierr = PCShellGetContext(pc,&bddcipc_ctx);CHKERRQ(ierr); 26085a1e936bSStefano Zampini pcis = (PC_IS*)(bddcipc_ctx->bddc->data); 26095a1e936bSStefano Zampini tmps = pcis->global_to_B; 26105a1e936bSStefano Zampini pcis->global_to_B = bddcipc_ctx->g2l; 26115a1e936bSStefano Zampini ierr = PCBDDCScalingRestriction(bddcipc_ctx->bddc,r,pcis->vec1_B);CHKERRQ(ierr); 26125a1e936bSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(bddcipc_ctx->bddc,PETSC_TRUE);CHKERRQ(ierr); 26135a1e936bSStefano Zampini ierr = PCBDDCScalingExtension(bddcipc_ctx->bddc,pcis->vec1_B,x);CHKERRQ(ierr); 26145a1e936bSStefano Zampini pcis->global_to_B = tmps; 26155a1e936bSStefano Zampini PetscFunctionReturn(0); 26165a1e936bSStefano Zampini } 26175a1e936bSStefano Zampini 26185a1e936bSStefano Zampini static PetscErrorCode PCDestroy_BDDCIPC(PC pc) 26195a1e936bSStefano Zampini { 26205a1e936bSStefano Zampini PetscErrorCode ierr; 26215a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 26225a1e936bSStefano Zampini 26235a1e936bSStefano Zampini PetscFunctionBegin; 26243ec1f749SStefano Zampini ierr = PCShellGetContext(pc,&bddcipc_ctx);CHKERRQ(ierr); 26255a1e936bSStefano Zampini ierr = PCDestroy(&bddcipc_ctx->bddc);CHKERRQ(ierr); 26265a1e936bSStefano Zampini ierr = VecScatterDestroy(&bddcipc_ctx->g2l);CHKERRQ(ierr); 26275a1e936bSStefano Zampini ierr = PetscFree(bddcipc_ctx);CHKERRQ(ierr); 26285a1e936bSStefano Zampini PetscFunctionReturn(0); 26295a1e936bSStefano Zampini } 26305a1e936bSStefano Zampini 26313425bc38SStefano Zampini /*@ 26320f202f7eSStefano Zampini PCBDDCMatFETIDPGetSolution - Compute the physical solution using the solution of the FETI-DP linear system 26333425bc38SStefano Zampini 26343425bc38SStefano Zampini Collective 26353425bc38SStefano Zampini 26363425bc38SStefano Zampini Input Parameters: 26370f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix obtained by a call to PCBDDCCreateFETIDPOperators 26380f202f7eSStefano Zampini - fetidp_flux_sol - the solution of the FETI-DP linear system 26393425bc38SStefano Zampini 26403425bc38SStefano Zampini Output Parameters: 26410f202f7eSStefano Zampini . standard_sol - the solution defined on the physical domain 26423425bc38SStefano Zampini 26433425bc38SStefano Zampini Level: developer 26443425bc38SStefano Zampini 26453425bc38SStefano Zampini Notes: 26463425bc38SStefano Zampini 26470f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetRHS 26483425bc38SStefano Zampini @*/ 26493425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 26503425bc38SStefano Zampini { 2651674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 26523425bc38SStefano Zampini PetscErrorCode ierr; 26533425bc38SStefano Zampini 26543425bc38SStefano Zampini PetscFunctionBegin; 2655266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2656266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_sol,VEC_CLASSID,2); 2657266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_sol,VEC_CLASSID,3); 26583425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2659163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 26603425bc38SStefano Zampini PetscFunctionReturn(0); 26613425bc38SStefano Zampini } 26621e6b0712SBarry Smith 2663547c9a8eSstefano_zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, PetscBool fully_redundant, const char* prefix, Mat *fetidp_mat, PC *fetidp_pc) 26643425bc38SStefano Zampini { 2665674ae819SStefano Zampini 2666674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 26673425bc38SStefano Zampini Mat newmat; 2668674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 26693425bc38SStefano Zampini PC newpc; 2670ce94432eSBarry Smith MPI_Comm comm; 26713425bc38SStefano Zampini PetscErrorCode ierr; 26723425bc38SStefano Zampini 26733425bc38SStefano Zampini PetscFunctionBegin; 2674ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 267515579a77SStefano Zampini /* FETI-DP matrix */ 26763425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 26771720468bSStefano Zampini fetidpmat_ctx->fully_redundant = fully_redundant; 26783425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 2679a5bb87b3Sstefano_zampini ierr = MatCreateShell(comm,fetidpmat_ctx->n,fetidpmat_ctx->n,fetidpmat_ctx->N,fetidpmat_ctx->N,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 268015579a77SStefano Zampini ierr = PetscObjectSetName((PetscObject)newmat,!fetidpmat_ctx->l2g_lambda_only ? "F" : "G");CHKERRQ(ierr); 26813425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 2682edf7251bSStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT_TRANSPOSE,(void (*)(void))FETIDPMatMultTranspose);CHKERRQ(ierr); 26833425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 268415579a77SStefano Zampini /* propagate MatOptions */ 268515579a77SStefano Zampini { 268615579a77SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)fetidpmat_ctx->pc->data; 268715579a77SStefano Zampini PetscBool issym; 268815579a77SStefano Zampini 268915579a77SStefano Zampini ierr = MatGetOption(pc->mat,MAT_SYMMETRIC,&issym);CHKERRQ(ierr); 269015579a77SStefano Zampini if (issym || pcbddc->symmetric_primal) { 269115579a77SStefano Zampini ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 269215579a77SStefano Zampini } 269315579a77SStefano Zampini } 2694547c9a8eSstefano_zampini ierr = MatSetOptionsPrefix(newmat,prefix);CHKERRQ(ierr); 2695547c9a8eSstefano_zampini ierr = MatAppendOptionsPrefix(newmat,"fetidp_");CHKERRQ(ierr); 26963425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 269715579a77SStefano Zampini /* FETI-DP preconditioner */ 26983425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 26993425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 27003425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 2701e1214c54Sstefano_zampini ierr = PCSetOperators(newpc,newmat,newmat);CHKERRQ(ierr); 2702e1214c54Sstefano_zampini ierr = PCSetOptionsPrefix(newpc,prefix);CHKERRQ(ierr); 2703e1214c54Sstefano_zampini ierr = PCAppendOptionsPrefix(newpc,"fetidp_");CHKERRQ(ierr); 2704399ffe99SStefano Zampini ierr = PCSetErrorIfFailure(newpc,pc->erroriffailure);CHKERRQ(ierr); 270515579a77SStefano Zampini if (!fetidpmat_ctx->l2g_lambda_only) { /* standard FETI-DP */ 27063425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 270715579a77SStefano Zampini ierr = PCShellSetName(newpc,"FETI-DP multipliers");CHKERRQ(ierr); 27083425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 27093425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 2710edf7251bSStefano Zampini ierr = PCShellSetApplyTranspose(newpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 2711c45b8d2dSstefano_zampini ierr = PCShellSetView(newpc,FETIDPPCView);CHKERRQ(ierr); 27123425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 27135a1e936bSStefano Zampini } else { /* saddle-point FETI-DP */ 27145a1e936bSStefano Zampini Mat M; 27155a1e936bSStefano Zampini PetscInt psize; 27165a1e936bSStefano Zampini PetscBool fake = PETSC_FALSE, isfieldsplit; 2717e1214c54Sstefano_zampini 271815579a77SStefano Zampini ierr = ISViewFromOptions(fetidpmat_ctx->lagrange,NULL,"-lag_view");CHKERRQ(ierr); 271915579a77SStefano Zampini ierr = ISViewFromOptions(fetidpmat_ctx->pressure,NULL,"-press_view");CHKERRQ(ierr); 2720e1214c54Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_PPmat",(PetscObject*)&M);CHKERRQ(ierr); 2721e1214c54Sstefano_zampini ierr = PCSetType(newpc,PCFIELDSPLIT);CHKERRQ(ierr); 2722e1214c54Sstefano_zampini ierr = PCFieldSplitSetIS(newpc,"lag",fetidpmat_ctx->lagrange);CHKERRQ(ierr); 2723e1214c54Sstefano_zampini ierr = PCFieldSplitSetIS(newpc,"p",fetidpmat_ctx->pressure);CHKERRQ(ierr); 2724e1214c54Sstefano_zampini ierr = PCFieldSplitSetType(newpc,PC_COMPOSITE_SCHUR);CHKERRQ(ierr); 272540c75d76SStefano Zampini ierr = PCFieldSplitSetSchurFactType(newpc,PC_FIELDSPLIT_SCHUR_FACT_DIAG);CHKERRQ(ierr); 27265a1e936bSStefano Zampini ierr = ISGetSize(fetidpmat_ctx->pressure,&psize);CHKERRQ(ierr); 27275a1e936bSStefano Zampini if (psize != M->rmap->N) { 27285a1e936bSStefano Zampini Mat M2; 27295a1e936bSStefano Zampini PetscInt lpsize; 27305a1e936bSStefano Zampini 27315a1e936bSStefano Zampini fake = PETSC_TRUE; 27325a1e936bSStefano Zampini ierr = ISGetLocalSize(fetidpmat_ctx->pressure,&lpsize);CHKERRQ(ierr); 27335a1e936bSStefano Zampini ierr = MatCreate(comm,&M2);CHKERRQ(ierr); 27345a1e936bSStefano Zampini ierr = MatSetType(M2,MATAIJ);CHKERRQ(ierr); 27355a1e936bSStefano Zampini ierr = MatSetSizes(M2,lpsize,lpsize,psize,psize);CHKERRQ(ierr); 27365a1e936bSStefano Zampini ierr = MatSetUp(M2);CHKERRQ(ierr); 27375a1e936bSStefano Zampini ierr = MatAssemblyBegin(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27385a1e936bSStefano Zampini ierr = MatAssemblyEnd(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27395a1e936bSStefano Zampini ierr = PCFieldSplitSetSchurPre(newpc,PC_FIELDSPLIT_SCHUR_PRE_USER,M2);CHKERRQ(ierr); 27405a1e936bSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 27415a1e936bSStefano Zampini } else { 2742e1214c54Sstefano_zampini ierr = PCFieldSplitSetSchurPre(newpc,PC_FIELDSPLIT_SCHUR_PRE_USER,M);CHKERRQ(ierr); 27435a1e936bSStefano Zampini } 2744c096484dSStefano Zampini ierr = PCFieldSplitSetSchurScale(newpc,1.0);CHKERRQ(ierr); 274515579a77SStefano Zampini 274615579a77SStefano Zampini /* we need to setfromoptions and setup here to access the blocks */ 2747e1214c54Sstefano_zampini ierr = PCSetFromOptions(newpc);CHKERRQ(ierr); 2748e1214c54Sstefano_zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 2749e1214c54Sstefano_zampini 27505a1e936bSStefano Zampini /* user may have changed the type (e.g. -fetidp_pc_type none) */ 27515a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)newpc,PCFIELDSPLIT,&isfieldsplit);CHKERRQ(ierr); 27525a1e936bSStefano Zampini if (isfieldsplit) { 27535a1e936bSStefano Zampini KSP *ksps; 27545a1e936bSStefano Zampini PC ppc,lagpc; 27555a1e936bSStefano Zampini PetscInt nn; 2756064a4176SStefano Zampini PetscBool ismatis,matisok = PETSC_FALSE,check = PETSC_FALSE; 27575a1e936bSStefano Zampini 2758e1214c54Sstefano_zampini /* set the solver for the (0,0) block */ 27595a1e936bSStefano Zampini ierr = PCFieldSplitSchurGetSubKSP(newpc,&nn,&ksps);CHKERRQ(ierr); 27605a1e936bSStefano Zampini if (!nn) { /* not of type PC_COMPOSITE_SCHUR */ 276140c75d76SStefano Zampini ierr = PCFieldSplitGetSubKSP(newpc,&nn,&ksps);CHKERRQ(ierr); 27625a1e936bSStefano Zampini if (!fake) { /* pass pmat to the pressure solver */ 27635a1e936bSStefano Zampini Mat F; 27645a1e936bSStefano Zampini 27655a1e936bSStefano Zampini ierr = KSPGetOperators(ksps[1],&F,NULL);CHKERRQ(ierr); 27665a1e936bSStefano Zampini ierr = KSPSetOperators(ksps[1],F,M);CHKERRQ(ierr); 27675a1e936bSStefano Zampini } 27685a1e936bSStefano Zampini } else { 27695a1e936bSStefano Zampini PetscBool issym; 27705a1e936bSStefano Zampini Mat S; 27715a1e936bSStefano Zampini 27725a1e936bSStefano Zampini ierr = PCFieldSplitSchurGetS(newpc,&S);CHKERRQ(ierr); 27735a1e936bSStefano Zampini 27745a1e936bSStefano Zampini ierr = MatGetOption(newmat,MAT_SYMMETRIC,&issym);CHKERRQ(ierr); 27755a1e936bSStefano Zampini if (issym) { 27765a1e936bSStefano Zampini ierr = MatSetOption(S,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 27775a1e936bSStefano Zampini } 27785a1e936bSStefano Zampini } 27795a1e936bSStefano Zampini ierr = KSPGetPC(ksps[0],&lagpc);CHKERRQ(ierr); 2780e1214c54Sstefano_zampini ierr = PCSetType(lagpc,PCSHELL);CHKERRQ(ierr); 27815a1e936bSStefano Zampini ierr = PCShellSetName(lagpc,"FETI-DP multipliers");CHKERRQ(ierr); 2782e1214c54Sstefano_zampini ierr = PCShellSetContext(lagpc,fetidppc_ctx);CHKERRQ(ierr); 2783e1214c54Sstefano_zampini ierr = PCShellSetApply(lagpc,FETIDPPCApply);CHKERRQ(ierr); 2784e1214c54Sstefano_zampini ierr = PCShellSetApplyTranspose(lagpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 2785e1214c54Sstefano_zampini ierr = PCShellSetView(lagpc,FETIDPPCView);CHKERRQ(ierr); 2786e1214c54Sstefano_zampini ierr = PCShellSetDestroy(lagpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 27875a1e936bSStefano Zampini 27885a1e936bSStefano Zampini /* Olof's idea: interface Schur complement preconditioner for the mass matrix */ 27895a1e936bSStefano Zampini ierr = KSPGetPC(ksps[1],&ppc);CHKERRQ(ierr); 27905a1e936bSStefano Zampini if (fake) { 27915a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 2792ff11fd76SStefano Zampini PetscContainer c; 27935a1e936bSStefano Zampini 27945a1e936bSStefano Zampini matisok = PETSC_TRUE; 27955a1e936bSStefano Zampini 27965a1e936bSStefano Zampini /* create inner BDDC solver */ 27975a1e936bSStefano Zampini ierr = PetscNew(&bddcipc_ctx);CHKERRQ(ierr); 27985a1e936bSStefano Zampini ierr = PCCreate(comm,&bddcipc_ctx->bddc);CHKERRQ(ierr); 27995a1e936bSStefano Zampini ierr = PCSetType(bddcipc_ctx->bddc,PCBDDC);CHKERRQ(ierr); 28005a1e936bSStefano Zampini ierr = PCSetOperators(bddcipc_ctx->bddc,M,M);CHKERRQ(ierr); 2801ff11fd76SStefano Zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_pCSR",(PetscObject*)&c);CHKERRQ(ierr); 2802ff11fd76SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)M,MATIS,&ismatis);CHKERRQ(ierr); 2803ff11fd76SStefano Zampini if (c && ismatis) { 2804ff11fd76SStefano Zampini Mat lM; 2805ff11fd76SStefano Zampini PetscInt *csr,n; 2806ff11fd76SStefano Zampini 2807ff11fd76SStefano Zampini ierr = MatISGetLocalMat(M,&lM);CHKERRQ(ierr); 2808ff11fd76SStefano Zampini ierr = MatGetSize(lM,&n,NULL);CHKERRQ(ierr); 2809ff11fd76SStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&csr);CHKERRQ(ierr); 2810ff11fd76SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(bddcipc_ctx->bddc,n,csr,csr + (n + 1),PETSC_COPY_VALUES);CHKERRQ(ierr); 2811ff11fd76SStefano Zampini ierr = MatISRestoreLocalMat(M,&lM);CHKERRQ(ierr); 2812ff11fd76SStefano Zampini } 28135a1e936bSStefano Zampini ierr = PCSetOptionsPrefix(bddcipc_ctx->bddc,((PetscObject)ksps[1])->prefix);CHKERRQ(ierr); 28145a1e936bSStefano Zampini ierr = PCSetErrorIfFailure(bddcipc_ctx->bddc,pc->erroriffailure);CHKERRQ(ierr); 28155a1e936bSStefano Zampini ierr = PCSetFromOptions(bddcipc_ctx->bddc);CHKERRQ(ierr); 28165a1e936bSStefano Zampini 28175a1e936bSStefano Zampini /* wrap the interface application */ 28185a1e936bSStefano Zampini ierr = PCSetType(ppc,PCSHELL);CHKERRQ(ierr); 28195a1e936bSStefano Zampini ierr = PCShellSetName(ppc,"FETI-DP pressure");CHKERRQ(ierr); 28205a1e936bSStefano Zampini ierr = PCShellSetContext(ppc,bddcipc_ctx);CHKERRQ(ierr); 28215a1e936bSStefano Zampini ierr = PCShellSetSetUp(ppc,PCSetUp_BDDCIPC);CHKERRQ(ierr); 28225a1e936bSStefano Zampini ierr = PCShellSetApply(ppc,PCApply_BDDCIPC);CHKERRQ(ierr); 28235a1e936bSStefano Zampini ierr = PCShellSetApplyTranspose(ppc,PCApplyTranspose_BDDCIPC);CHKERRQ(ierr); 28245a1e936bSStefano Zampini ierr = PCShellSetView(ppc,PCView_BDDCIPC);CHKERRQ(ierr); 28255a1e936bSStefano Zampini ierr = PCShellSetDestroy(ppc,PCDestroy_BDDCIPC);CHKERRQ(ierr); 28265a1e936bSStefano Zampini } 28275a1e936bSStefano Zampini 28285a1e936bSStefano Zampini /* determine if we need to assemble M to construct a preconditioner */ 28295a1e936bSStefano Zampini if (!matisok) { 28305a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)M,MATIS,&ismatis);CHKERRQ(ierr); 28315a1e936bSStefano Zampini ierr = PetscObjectTypeCompareAny((PetscObject)ppc,&matisok,PCBDDC,PCJACOBI,PCNONE,PCMG,"");CHKERRQ(ierr); 28325a1e936bSStefano Zampini if (ismatis && !matisok) { 28335a1e936bSStefano Zampini ierr = MatConvert(M,MATAIJ,MAT_INPLACE_MATRIX,&M);CHKERRQ(ierr); 28345a1e936bSStefano Zampini } 28355a1e936bSStefano Zampini } 2836064a4176SStefano Zampini 2837064a4176SStefano Zampini /* run the subproblems to check convergence */ 2838064a4176SStefano Zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)newmat)->prefix,"-check_saddlepoint",&check,NULL);CHKERRQ(ierr); 2839064a4176SStefano Zampini if (check) { 2840064a4176SStefano Zampini PetscInt i; 2841064a4176SStefano Zampini 2842064a4176SStefano Zampini for (i=0;i<nn;i++) { 2843064a4176SStefano Zampini KSP kspC; 2844064a4176SStefano Zampini PC pc; 2845064a4176SStefano Zampini Mat F,pF; 2846064a4176SStefano Zampini Vec x,y; 2847064a4176SStefano Zampini PetscBool isschur,prec = PETSC_TRUE; 2848064a4176SStefano Zampini 2849064a4176SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)ksps[i]),&kspC);CHKERRQ(ierr); 2850064a4176SStefano Zampini ierr = KSPSetOptionsPrefix(kspC,((PetscObject)ksps[i])->prefix);CHKERRQ(ierr); 2851064a4176SStefano Zampini ierr = KSPAppendOptionsPrefix(kspC,"check_");CHKERRQ(ierr); 2852064a4176SStefano Zampini ierr = KSPGetOperators(ksps[i],&F,&pF);CHKERRQ(ierr); 2853064a4176SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)F,MATSCHURCOMPLEMENT,&isschur);CHKERRQ(ierr); 2854064a4176SStefano Zampini if (isschur) { 2855064a4176SStefano Zampini KSP kspS,kspS2; 2856064a4176SStefano Zampini Mat A00,pA00,A10,A01,A11; 2857064a4176SStefano Zampini char prefix[256]; 2858064a4176SStefano Zampini 2859064a4176SStefano Zampini ierr = MatSchurComplementGetKSP(F,&kspS);CHKERRQ(ierr); 2860064a4176SStefano Zampini ierr = MatSchurComplementGetSubMatrices(F,&A00,&pA00,&A01,&A10,&A11);CHKERRQ(ierr); 2861064a4176SStefano Zampini ierr = MatCreateSchurComplement(A00,pA00,A01,A10,A11,&F);CHKERRQ(ierr); 2862064a4176SStefano Zampini ierr = MatSchurComplementGetKSP(F,&kspS2);CHKERRQ(ierr); 2863064a4176SStefano Zampini ierr = PetscSNPrintf(prefix,sizeof(prefix),"%sschur_",((PetscObject)kspC)->prefix);CHKERRQ(ierr); 2864064a4176SStefano Zampini ierr = KSPSetOptionsPrefix(kspS2,prefix);CHKERRQ(ierr); 2865064a4176SStefano Zampini ierr = KSPGetPC(kspS2,&pc);CHKERRQ(ierr); 2866064a4176SStefano Zampini ierr = PCSetType(pc,PCKSP);CHKERRQ(ierr); 2867064a4176SStefano Zampini ierr = PCKSPSetKSP(pc,kspS);CHKERRQ(ierr); 2868064a4176SStefano Zampini ierr = KSPSetFromOptions(kspS2);CHKERRQ(ierr); 2869064a4176SStefano Zampini ierr = KSPGetPC(kspS2,&pc);CHKERRQ(ierr); 2870064a4176SStefano Zampini ierr = PCSetUseAmat(pc,PETSC_TRUE);CHKERRQ(ierr); 2871064a4176SStefano Zampini } else { 2872064a4176SStefano Zampini ierr = PetscObjectReference((PetscObject)F);CHKERRQ(ierr); 2873064a4176SStefano Zampini } 2874064a4176SStefano Zampini ierr = KSPSetFromOptions(kspC);CHKERRQ(ierr); 2875064a4176SStefano Zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)kspC)->prefix,"-preconditioned",&prec,NULL);CHKERRQ(ierr); 2876064a4176SStefano Zampini if (prec) { 2877064a4176SStefano Zampini ierr = KSPGetPC(ksps[i],&pc);CHKERRQ(ierr); 2878064a4176SStefano Zampini ierr = KSPSetPC(kspC,pc);CHKERRQ(ierr); 2879064a4176SStefano Zampini } 2880064a4176SStefano Zampini ierr = KSPSetOperators(kspC,F,pF);CHKERRQ(ierr); 2881064a4176SStefano Zampini ierr = MatCreateVecs(F,&x,&y);CHKERRQ(ierr); 2882064a4176SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 2883064a4176SStefano Zampini ierr = MatMult(F,x,y);CHKERRQ(ierr); 2884064a4176SStefano Zampini ierr = KSPSolve(kspC,y,x);CHKERRQ(ierr); 2885c0decd05SBarry Smith ierr = KSPCheckSolve(kspC,pc,x);CHKERRQ(ierr); 2886064a4176SStefano Zampini ierr = KSPDestroy(&kspC);CHKERRQ(ierr); 2887064a4176SStefano Zampini ierr = MatDestroy(&F);CHKERRQ(ierr); 2888064a4176SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2889064a4176SStefano Zampini ierr = VecDestroy(&y);CHKERRQ(ierr); 2890064a4176SStefano Zampini } 2891064a4176SStefano Zampini } 2892e1214c54Sstefano_zampini ierr = PetscFree(ksps);CHKERRQ(ierr); 2893e1214c54Sstefano_zampini } 28945a1e936bSStefano Zampini } 28953425bc38SStefano Zampini /* return pointers for objects created */ 28963425bc38SStefano Zampini *fetidp_mat = newmat; 28973425bc38SStefano Zampini *fetidp_pc = newpc; 28983425bc38SStefano Zampini PetscFunctionReturn(0); 28993425bc38SStefano Zampini } 29001e6b0712SBarry Smith 290194ef8ddeSSatish Balay /*@C 29020f202f7eSStefano Zampini PCBDDCCreateFETIDPOperators - Create FETI-DP operators 29033425bc38SStefano Zampini 29043425bc38SStefano Zampini Collective 29053425bc38SStefano Zampini 29063425bc38SStefano Zampini Input Parameters: 29071720468bSStefano Zampini + pc - the BDDC preconditioning context (setup should have been called before) 2908547c9a8eSstefano_zampini . fully_redundant - true for a fully redundant set of Lagrange multipliers 2909547c9a8eSstefano_zampini - prefix - optional options database prefix for the objects to be created (can be NULL) 291028509bceSStefano Zampini 291128509bceSStefano Zampini Output Parameters: 29120f202f7eSStefano Zampini + fetidp_mat - shell FETI-DP matrix object 29130f202f7eSStefano Zampini - fetidp_pc - shell Dirichlet preconditioner for FETI-DP matrix 291428509bceSStefano Zampini 29153425bc38SStefano Zampini Level: developer 29163425bc38SStefano Zampini 29173425bc38SStefano Zampini Notes: 29180f202f7eSStefano Zampini Currently the only operations provided for FETI-DP matrix are MatMult and MatMultTranspose 29193425bc38SStefano Zampini 29200f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCMatFETIDPGetRHS, PCBDDCMatFETIDPGetSolution 29213425bc38SStefano Zampini @*/ 2922547c9a8eSstefano_zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, PetscBool fully_redundant, const char *prefix, Mat *fetidp_mat, PC *fetidp_pc) 29233425bc38SStefano Zampini { 29243425bc38SStefano Zampini PetscErrorCode ierr; 29253425bc38SStefano Zampini 29263425bc38SStefano Zampini PetscFunctionBegin; 29273425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 29283425bc38SStefano Zampini if (pc->setupcalled) { 2929547c9a8eSstefano_zampini ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,PetscBool,const char*,Mat*,PC*),(pc,fully_redundant,prefix,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 29306080607fSStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"You must call PCSetup_BDDC() first"); 29313425bc38SStefano Zampini PetscFunctionReturn(0); 29323425bc38SStefano Zampini } 29330c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2934da1bb401SStefano Zampini /*MC 2935da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 29360c7d97c5SJed Brown 2937be4a8d98Sprj- An implementation of the BDDC preconditioner based on the bibliography found below. 293828509bceSStefano Zampini 293928509bceSStefano Zampini The matrix to be preconditioned (Pmat) must be of type MATIS. 294028509bceSStefano Zampini 29410f202f7eSStefano Zampini Currently works with MATIS matrices with local matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers. 294228509bceSStefano Zampini 294328509bceSStefano Zampini It also works with unsymmetric and indefinite problems. 294428509bceSStefano Zampini 2945b6fdb6dfSStefano 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. 2946b6fdb6dfSStefano Zampini 2947c7017625SStefano 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). 294828509bceSStefano Zampini 29490f202f7eSStefano 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() 295030368db7SStefano Zampini Additional information on dofs can be provided by using PCBDDCSetDofsSplitting(), PCBDDCSetDirichletBoundaries(), PCBDDCSetNeumannBoundaries(), and PCBDDCSetPrimalVerticesIS() and their local counterparts. 295128509bceSStefano Zampini 29520f202f7eSStefano Zampini Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace(). Non-singular modes are retained via SVD. 295328509bceSStefano Zampini 29540f202f7eSStefano 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. 29550f202f7eSStefano Zampini User defined change of basis can be passed to PCBDDC by using PCBDDCSetChangeOfBasisMat() 295628509bceSStefano Zampini 29570f202f7eSStefano Zampini The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using a MatPartitioning object. 295828509bceSStefano Zampini 2959df4d28bfSStefano 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. 296028509bceSStefano Zampini 29610f202f7eSStefano 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. 29620f202f7eSStefano Zampini 2963d314f959SVaclav Hapla Options Database Keys (some of them, run with -help for a complete list): 29640f202f7eSStefano Zampini 2965a2b725a8SWilliam Gropp + -pc_bddc_use_vertices <true> - use or not vertices in primal space 29660f202f7eSStefano Zampini . -pc_bddc_use_edges <true> - use or not edges in primal space 29670f202f7eSStefano Zampini . -pc_bddc_use_faces <false> - use or not faces in primal space 29680f202f7eSStefano Zampini . -pc_bddc_symmetric <true> - symmetric computation of primal basis functions. Specify false for unsymmetric problems 29690f202f7eSStefano Zampini . -pc_bddc_use_change_of_basis <false> - use change of basis approach (on edges only) 29700f202f7eSStefano Zampini . -pc_bddc_use_change_on_faces <false> - use change of basis approach on faces if change of basis has been requested 29710f202f7eSStefano Zampini . -pc_bddc_switch_static <false> - switches from M_2 (default) to M_3 operator (see reference article [1]) 297228509bceSStefano Zampini . -pc_bddc_levels <0> - maximum number of levels for multilevel 29730f202f7eSStefano 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) 29745459c157SBarry 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) 29750f202f7eSStefano Zampini . -pc_bddc_use_deluxe_scaling <false> - use deluxe scaling 297671f2caa7Sprj- . -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) 2977bd2a564bSStefano 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) 297828509bceSStefano Zampini - -pc_bddc_check_level <0> - set verbosity level of debugging output 297928509bceSStefano Zampini 298028509bceSStefano Zampini Options for Dirichlet, Neumann or coarse solver can be set with 298128509bceSStefano Zampini .vb 298228509bceSStefano Zampini -pc_bddc_dirichlet_ 298328509bceSStefano Zampini -pc_bddc_neumann_ 298428509bceSStefano Zampini -pc_bddc_coarse_ 298528509bceSStefano Zampini .ve 2986f9ff08acSPierre Jolivet e.g. -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg. PCBDDC uses by default KSPPREONLY and PCLU. 298728509bceSStefano Zampini 29880f202f7eSStefano Zampini When using a multilevel approach, solvers' options at the N-th level (N > 1) can be specified as 298928509bceSStefano Zampini .vb 2990312be037SStefano Zampini -pc_bddc_dirichlet_lN_ 2991312be037SStefano Zampini -pc_bddc_neumann_lN_ 2992312be037SStefano Zampini -pc_bddc_coarse_lN_ 299328509bceSStefano Zampini .ve 29940f202f7eSStefano Zampini Note that level number ranges from the finest (0) to the coarsest (N). 29950f202f7eSStefano 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. 29960f202f7eSStefano Zampini .vb 29970f202f7eSStefano Zampini -pc_bddc_coarse_pc_bddc_adaptive_threshold 5 -pc_bddc_coarse_l1_pc_bddc_redistribute 3 29980f202f7eSStefano Zampini .ve 29990f202f7eSStefano 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 3000da1bb401SStefano Zampini 3001be4a8d98Sprj- References: 3002be4a8d98Sprj- + [1] - C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149--168, March 2007 3003be4a8d98Sprj- . [2] - 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 3004be4a8d98Sprj- . [3] - J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", Computing Volume 83, Issue 2--3, pages 55--85, November 2008 3005be4a8d98Sprj- - [4] - C. Pechstein and C. R. Dohrmann. "Modern domain decomposition methods BDDC, deluxe scaling, and an algebraic approach", Seminar talk, Linz, December 2013, http://people.ricam.oeaw.ac.at/c.pechstein/pechstein-bddc2013.pdf 3006be4a8d98Sprj- 3007da1bb401SStefano Zampini Level: intermediate 3008da1bb401SStefano Zampini 3009e94cfbe0SPatrick Sanan Developer Notes: 3010da1bb401SStefano Zampini 3011da1bb401SStefano Zampini Contributed by Stefano Zampini 3012da1bb401SStefano Zampini 3013da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 3014da1bb401SStefano Zampini M*/ 3015b2573a8aSBarry Smith 30168cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 3017da1bb401SStefano Zampini { 3018da1bb401SStefano Zampini PetscErrorCode ierr; 3019da1bb401SStefano Zampini PC_BDDC *pcbddc; 3020da1bb401SStefano Zampini 3021da1bb401SStefano Zampini PetscFunctionBegin; 3022b00a9115SJed Brown ierr = PetscNewLog(pc,&pcbddc);CHKERRQ(ierr); 30233ec1f749SStefano Zampini pc->data = pcbddc; 3024da1bb401SStefano Zampini 3025da1bb401SStefano Zampini /* create PCIS data structure */ 3026da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 3027da1bb401SStefano Zampini 30289326c5c6Sstefano_zampini /* create local graph structure */ 30299326c5c6Sstefano_zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 30309326c5c6Sstefano_zampini 30319326c5c6Sstefano_zampini /* BDDC nonzero defaults */ 30326d9e27e4SStefano Zampini pcbddc->use_nnsp = PETSC_TRUE; 303308a5cf49SStefano Zampini pcbddc->use_local_adj = PETSC_TRUE; 303447d04d0dSStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 303547d04d0dSStefano Zampini pcbddc->use_edges = PETSC_TRUE; 30363301b35fSStefano Zampini pcbddc->symmetric_primal = PETSC_TRUE; 303714f95afaSStefano Zampini pcbddc->vertex_size = 1; 3038c703fcc7SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 303968457ee5SStefano Zampini pcbddc->coarse_size = -1; 304085c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 304147d04d0dSStefano Zampini pcbddc->coarsening_ratio = 8; 304257de7509SStefano Zampini pcbddc->coarse_eqs_per_proc = 1; 304327b6a85dSStefano Zampini pcbddc->benign_compute_correction = PETSC_TRUE; 30441e0482f5SStefano Zampini pcbddc->nedfield = -1; 30451e0482f5SStefano Zampini pcbddc->nedglobal = PETSC_TRUE; 3046be12c134Sstefano_zampini pcbddc->graphmaxcount = PETSC_MAX_INT; 3047b96c3477SStefano Zampini pcbddc->sub_schurs_layers = -1; 3048bd2a564bSStefano Zampini pcbddc->adaptive_threshold[0] = 0.0; 3049bd2a564bSStefano Zampini pcbddc->adaptive_threshold[1] = 0.0; 3050b7eb3628SStefano Zampini 3051da1bb401SStefano Zampini /* function pointers */ 3052da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 305393bd9ae7SStefano Zampini pc->ops->applytranspose = PCApplyTranspose_BDDC; 3054da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 3055da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 3056da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 30576b78500eSPatrick Sanan pc->ops->view = PCView_BDDC; 30580a545947SLisandro Dalcin pc->ops->applyrichardson = NULL; 30590a545947SLisandro Dalcin pc->ops->applysymmetricleft = NULL; 30600a545947SLisandro Dalcin pc->ops->applysymmetricright = NULL; 3061534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 3062534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 30639326c5c6Sstefano_zampini pc->ops->reset = PCReset_BDDC; 3064da1bb401SStefano Zampini 3065da1bb401SStefano Zampini /* composing function */ 3066a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",PCBDDCSetDiscreteGradient_BDDC);CHKERRQ(ierr); 3067a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",PCBDDCSetDivergenceMat_BDDC);CHKERRQ(ierr); 3068906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",PCBDDCSetChangeOfBasisMat_BDDC);CHKERRQ(ierr); 3069674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 307030368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",PCBDDCSetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 30713100ebe3SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetPrimalVerticesLocalIS_C",PCBDDCGetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 30723100ebe3SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetPrimalVerticesIS_C",PCBDDCGetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 3073bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 30742b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr); 3075b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr); 30762b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr); 3077bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 307882ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 3079bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 308082ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 3081bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 308282ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 3083bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 308482ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 3085bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 308663602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",PCBDDCSetDofsSplittingLocal_BDDC);CHKERRQ(ierr); 3087bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 3088bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 3089bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 3090bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 3091a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",PCPreSolveChangeRHS_BDDC);CHKERRQ(ierr); 3092ab8c8b98SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_BDDC);CHKERRQ(ierr); 3093da1bb401SStefano Zampini PetscFunctionReturn(0); 3094da1bb401SStefano Zampini } 309543371fb9SStefano Zampini 309643371fb9SStefano Zampini /*@C 309743371fb9SStefano Zampini PCBDDCInitializePackage - This function initializes everything in the PCBDDC package. It is called 30988a690491SBarry Smith from PCInitializePackage(). 309943371fb9SStefano Zampini 310043371fb9SStefano Zampini Level: developer 310143371fb9SStefano Zampini 310243371fb9SStefano Zampini .seealso: PetscInitialize() 310343371fb9SStefano Zampini @*/ 310443371fb9SStefano Zampini PetscErrorCode PCBDDCInitializePackage(void) 310543371fb9SStefano Zampini { 310643371fb9SStefano Zampini PetscErrorCode ierr; 310743371fb9SStefano Zampini int i; 310843371fb9SStefano Zampini 310943371fb9SStefano Zampini PetscFunctionBegin; 311043371fb9SStefano Zampini if (PCBDDCPackageInitialized) PetscFunctionReturn(0); 311143371fb9SStefano Zampini PCBDDCPackageInitialized = PETSC_TRUE; 311243371fb9SStefano Zampini ierr = PetscRegisterFinalize(PCBDDCFinalizePackage);CHKERRQ(ierr); 311343371fb9SStefano Zampini 311443371fb9SStefano Zampini /* general events */ 311543371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCTopo",PC_CLASSID,&PC_BDDC_Topology[0]);CHKERRQ(ierr); 311643371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCLKSP",PC_CLASSID,&PC_BDDC_LocalSolvers[0]);CHKERRQ(ierr); 311743371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCLWor",PC_CLASSID,&PC_BDDC_LocalWork[0]);CHKERRQ(ierr); 311843371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCorr",PC_CLASSID,&PC_BDDC_CorrectionSetUp[0]);CHKERRQ(ierr); 31198ead10e4SStefano Zampini ierr = PetscLogEventRegister("PCBDDCASet",PC_CLASSID,&PC_BDDC_ApproxSetUp[0]);CHKERRQ(ierr); 31208ead10e4SStefano Zampini ierr = PetscLogEventRegister("PCBDDCAApp",PC_CLASSID,&PC_BDDC_ApproxApply[0]);CHKERRQ(ierr); 312143371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCSet",PC_CLASSID,&PC_BDDC_CoarseSetUp[0]);CHKERRQ(ierr); 312243371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCKSP",PC_CLASSID,&PC_BDDC_CoarseSolver[0]);CHKERRQ(ierr); 312343371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCAdap",PC_CLASSID,&PC_BDDC_AdaptiveSetUp[0]);CHKERRQ(ierr); 312443371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCScal",PC_CLASSID,&PC_BDDC_Scaling[0]);CHKERRQ(ierr); 312543371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCSchr",PC_CLASSID,&PC_BDDC_Schurs[0]);CHKERRQ(ierr); 312655c176c0SStefano Zampini ierr = PetscLogEventRegister("PCBDDCDirS",PC_CLASSID,&PC_BDDC_Solves[0][0]);CHKERRQ(ierr); 312755c176c0SStefano Zampini ierr = PetscLogEventRegister("PCBDDCNeuS",PC_CLASSID,&PC_BDDC_Solves[0][1]);CHKERRQ(ierr); 312855c176c0SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCoaS",PC_CLASSID,&PC_BDDC_Solves[0][2]);CHKERRQ(ierr); 312943371fb9SStefano Zampini for (i=1;i<PETSC_PCBDDC_MAXLEVELS;i++) { 313043371fb9SStefano Zampini char ename[32]; 313143371fb9SStefano Zampini 313243371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCTopo l%02d",i);CHKERRQ(ierr); 313343371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Topology[i]);CHKERRQ(ierr); 313443371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCLKSP l%02d",i);CHKERRQ(ierr); 313543371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_LocalSolvers[i]);CHKERRQ(ierr); 313643371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCLWor l%02d",i);CHKERRQ(ierr); 313743371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_LocalWork[i]);CHKERRQ(ierr); 313843371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCorr l%02d",i);CHKERRQ(ierr); 313943371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CorrectionSetUp[i]);CHKERRQ(ierr); 31408ead10e4SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCASet l%02d",i);CHKERRQ(ierr); 31418ead10e4SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_ApproxSetUp[i]);CHKERRQ(ierr); 31428ead10e4SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCAApp l%02d",i);CHKERRQ(ierr); 31438ead10e4SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_ApproxApply[i]);CHKERRQ(ierr); 314443371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCSet l%02d",i);CHKERRQ(ierr); 314543371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CoarseSetUp[i]);CHKERRQ(ierr); 314643371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCKSP l%02d",i);CHKERRQ(ierr); 314743371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CoarseSolver[i]);CHKERRQ(ierr); 314843371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCAdap l%02d",i);CHKERRQ(ierr); 314943371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_AdaptiveSetUp[i]);CHKERRQ(ierr); 315043371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCScal l%02d",i);CHKERRQ(ierr); 315143371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Scaling[i]);CHKERRQ(ierr); 315243371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCSchr l%02d",i);CHKERRQ(ierr); 315343371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Schurs[i]);CHKERRQ(ierr); 315455c176c0SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCDirS l%02d",i);CHKERRQ(ierr); 315555c176c0SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Solves[i][0]);CHKERRQ(ierr); 315655c176c0SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCNeuS l%02d",i);CHKERRQ(ierr); 315755c176c0SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Solves[i][1]);CHKERRQ(ierr); 315855c176c0SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCoaS l%02d",i);CHKERRQ(ierr); 315955c176c0SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Solves[i][2]);CHKERRQ(ierr); 316043371fb9SStefano Zampini } 316143371fb9SStefano Zampini PetscFunctionReturn(0); 316243371fb9SStefano Zampini } 316343371fb9SStefano Zampini 316443371fb9SStefano Zampini /*@C 316543371fb9SStefano Zampini PCBDDCFinalizePackage - This function frees everything from the PCBDDC package. It is 316643371fb9SStefano Zampini called from PetscFinalize() automatically. 316743371fb9SStefano Zampini 316843371fb9SStefano Zampini Level: developer 316943371fb9SStefano Zampini 317043371fb9SStefano Zampini .seealso: PetscFinalize() 317143371fb9SStefano Zampini @*/ 317243371fb9SStefano Zampini PetscErrorCode PCBDDCFinalizePackage(void) 317343371fb9SStefano Zampini { 317443371fb9SStefano Zampini PetscFunctionBegin; 317543371fb9SStefano Zampini PCBDDCPackageInitialized = PETSC_FALSE; 317643371fb9SStefano Zampini PetscFunctionReturn(0); 317743371fb9SStefano Zampini } 3178