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 26f3d41395Sstefano_zampini static PetscBool cited = PETSC_FALSE; 27f3d41395Sstefano_zampini static const char citation[] = 28f3d41395Sstefano_zampini "@article{ZampiniPCBDDC,\n" 29f3d41395Sstefano_zampini "author = {Stefano Zampini},\n" 30f3d41395Sstefano_zampini "title = {{PCBDDC}: A Class of Robust Dual-Primal Methods in {PETS}c},\n" 31f3d41395Sstefano_zampini "journal = {SIAM Journal on Scientific Computing},\n" 32f3d41395Sstefano_zampini "volume = {38},\n" 33f3d41395Sstefano_zampini "number = {5},\n" 34f3d41395Sstefano_zampini "pages = {S282-S306},\n" 35f3d41395Sstefano_zampini "year = {2016},\n" 36f3d41395Sstefano_zampini "doi = {10.1137/15M1025785},\n" 37f3d41395Sstefano_zampini "URL = {http://dx.doi.org/10.1137/15M1025785},\n" 38f3d41395Sstefano_zampini "eprint = {http://dx.doi.org/10.1137/15M1025785}\n" 39f3d41395Sstefano_zampini "}\n"; 40f3d41395Sstefano_zampini 410369aaf7SStefano Zampini /* temporarily declare it */ 420369aaf7SStefano Zampini PetscErrorCode PCApply_BDDC(PC,Vec,Vec); 430369aaf7SStefano Zampini 444416b707SBarry Smith PetscErrorCode PCSetFromOptions_BDDC(PetscOptionItems *PetscOptionsObject,PC pc) 450c7d97c5SJed Brown { 460c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 47bd2a564bSStefano Zampini PetscInt nt; 480c7d97c5SJed Brown PetscErrorCode ierr; 490c7d97c5SJed Brown 500c7d97c5SJed Brown PetscFunctionBegin; 51e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"BDDC options");CHKERRQ(ierr); 528eeda7d8SStefano Zampini /* Verbose debugging */ 53a13144ffSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_check_level","Verbose output for PCBDDC (intended for debug)","none",pcbddc->dbg_flag,&pcbddc->dbg_flag,NULL);CHKERRQ(ierr); 54a13144ffSStefano Zampini /* Approximate solvers */ 55c7017625SStefano 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); 56c7017625SStefano 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); 57c7017625SStefano 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); 58c7017625SStefano 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); 596b78500eSPatrick Sanan /* Primal space customization */ 6008a5cf49SStefano 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); 61be12c134Sstefano_zampini ierr = PetscOptionsInt("-pc_bddc_graph_maxcount","Maximum number of shared subdomains for a connected component","none",pcbddc->graphmaxcount,&pcbddc->graphmaxcount,NULL);CHKERRQ(ierr); 621c7a958bSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_corner_selection","Activates face-based corner selection","none",pcbddc->corner_selection,&pcbddc->corner_selection,NULL);CHKERRQ(ierr); 638eeda7d8SStefano 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); 648eeda7d8SStefano 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); 658eeda7d8SStefano 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); 6614f95afaSStefano 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); 676661aa1dSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_true_nnsp","Use near null space attached to the matrix without modifications","none",pcbddc->use_nnsp_true,&pcbddc->use_nnsp_true,NULL);CHKERRQ(ierr); 6814f95afaSStefano 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); 698eeda7d8SStefano Zampini /* Change of basis */ 70b9b85e73SStefano 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); 71b9b85e73SStefano 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); 72674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 73674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 74674ae819SStefano Zampini } 758eeda7d8SStefano Zampini /* Switch between M_2 (default) and M_3 preconditioners (as defined by C. Dohrmann in the ref. article) */ 768eeda7d8SStefano 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); 7757de7509SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_coarse_eqs_per_proc","Number of equations per process for coarse problem redistribution (significant only at the coarsest level)","none",pcbddc->coarse_eqs_per_proc,&pcbddc->coarse_eqs_per_proc,NULL);CHKERRQ(ierr); 780298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr); 792b510759SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr); 80323d395dSStefano 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); 81674ae819SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_deluxe_scaling","Use deluxe scaling for BDDC","none",pcbddc->use_deluxe_scaling,&pcbddc->use_deluxe_scaling,NULL);CHKERRQ(ierr); 82b96c3477SStefano 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); 83b96c3477SStefano 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); 84b96c3477SStefano 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); 85683d3df6SStefano 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); 86bf3a8328SStefano 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); 87839e9adbSstefano_zampini ierr = PetscOptionsBool("-pc_bddc_deluxe_singlemat","Collapse deluxe operators","none",pcbddc->deluxe_singlemat,&pcbddc->deluxe_singlemat,NULL);CHKERRQ(ierr); 88bf3a8328SStefano 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); 89bd2a564bSStefano Zampini nt = 2; 90bd2a564bSStefano Zampini ierr = PetscOptionsRealArray("-pc_bddc_adaptive_threshold","Thresholds to be used for adaptive selection of constraints","none",pcbddc->adaptive_threshold,&nt,NULL);CHKERRQ(ierr); 91bd2a564bSStefano Zampini if (nt == 1) pcbddc->adaptive_threshold[1] = pcbddc->adaptive_threshold[0]; 9208122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmin","Minimum number of constraints per connected components","none",pcbddc->adaptive_nmin,&pcbddc->adaptive_nmin,NULL);CHKERRQ(ierr); 9308122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmax","Maximum number of constraints per connected components","none",pcbddc->adaptive_nmax,&pcbddc->adaptive_nmax,NULL);CHKERRQ(ierr); 943301b35fSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_symmetric","Symmetric computation of primal basis functions","none",pcbddc->symmetric_primal,&pcbddc->symmetric_primal,NULL);CHKERRQ(ierr); 95b0c7d250SStefano 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); 96b3afcdbeSStefano 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); 97e9627c49SStefano 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); 9827b6a85dSStefano 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); 99a198735bSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nonetflux","Automatic computation of no-net-flux quadrature weights","none",pcbddc->compute_nonetflux,&pcbddc->compute_nonetflux,NULL);CHKERRQ(ierr); 1004f1b2e48SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_detect_disconnected","Detects disconnected subdomains","none",pcbddc->detect_disconnected,&pcbddc->detect_disconnected,NULL);CHKERRQ(ierr); 1018361f951SStefano 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); 10270c64980SStefano 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); 1030c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 1040c7d97c5SJed Brown PetscFunctionReturn(0); 1050c7d97c5SJed Brown } 1066b78500eSPatrick Sanan 1076b78500eSPatrick Sanan static PetscErrorCode PCView_BDDC(PC pc,PetscViewer viewer) 1086b78500eSPatrick Sanan { 1096b78500eSPatrick Sanan PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 110e9627c49SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1116b78500eSPatrick Sanan PetscErrorCode ierr; 11271783a16SStefano Zampini PetscBool isascii; 113e9627c49SStefano Zampini PetscSubcomm subcomm; 114e9627c49SStefano Zampini PetscViewer subviewer; 1156b78500eSPatrick Sanan 1166b78500eSPatrick Sanan PetscFunctionBegin; 1176b78500eSPatrick Sanan ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1186b78500eSPatrick Sanan /* ASCII viewer */ 1196b78500eSPatrick Sanan if (isascii) { 1204b2aedd3SStefano Zampini PetscMPIInt color,rank,size; 121fbad9177SStefano Zampini PetscInt64 loc[7],gsum[6],gmax[6],gmin[6],totbenign; 122e9627c49SStefano Zampini PetscScalar interface_size; 123e9627c49SStefano Zampini PetscReal ratio1=0.,ratio2=0.; 124e9627c49SStefano Zampini Vec counter; 1256b78500eSPatrick Sanan 126b74ba07aSstefano_zampini if (!pc->setupcalled) { 127b74ba07aSstefano_zampini ierr = PetscViewerASCIIPrintf(viewer," Partial information available: preconditioner has not been setup yet\n");CHKERRQ(ierr); 128b74ba07aSstefano_zampini } 129efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use verbose output: %D\n",pcbddc->dbg_flag);CHKERRQ(ierr); 1306f0c0a6aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use user-defined CSR: %d\n",!!pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 1316f0c0a6aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use local mat graph: %d\n",pcbddc->use_local_adj && !pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 132e9627c49SStefano Zampini if (pcbddc->mat_graph->twodim) { 133efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Connectivity graph topological dimension: 2\n");CHKERRQ(ierr); 134e9627c49SStefano Zampini } else { 135efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Connectivity graph topological dimension: 3\n");CHKERRQ(ierr); 136e9627c49SStefano Zampini } 137aefa1729SStefano Zampini if (pcbddc->graphmaxcount != PETSC_MAX_INT) { 138efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Graph max count: %D\n",pcbddc->graphmaxcount);CHKERRQ(ierr); 139aefa1729SStefano Zampini } 14050e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use vertices: %d (vertex size %D)\n",pcbddc->use_vertices,pcbddc->vertex_size);CHKERRQ(ierr); 141efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use edges: %d\n",pcbddc->use_edges);CHKERRQ(ierr); 142efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use faces: %d\n",pcbddc->use_faces);CHKERRQ(ierr); 143efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use true near null space: %d\n",pcbddc->use_nnsp_true);CHKERRQ(ierr); 144efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use QR for single constraints on cc: %d\n",pcbddc->use_qr_single);CHKERRQ(ierr); 145efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use change of basis on local edge nodes: %d\n",pcbddc->use_change_of_basis);CHKERRQ(ierr); 146efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use change of basis on local face nodes: %d\n",pcbddc->use_change_on_faces);CHKERRQ(ierr); 147efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," User defined change of basis matrix: %d\n",!!pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 148efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Has change of basis matrix: %d\n",!!pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 149efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eliminate dirichlet boundary dofs: %d\n",pcbddc->eliminate_dirdofs);CHKERRQ(ierr); 150efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Switch on static condensation ops around the interface preconditioner: %d\n",pcbddc->switch_static);CHKERRQ(ierr); 151efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use exact dirichlet trick: %d\n",pcbddc->use_exact_dirichlet_trick);CHKERRQ(ierr); 15250e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Multilevel max levels: %D\n",pcbddc->max_levels);CHKERRQ(ierr); 15350e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Multilevel coarsening ratio: %D\n",pcbddc->coarsening_ratio);CHKERRQ(ierr); 154efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use estimated eigs for coarse problem: %d\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 155efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe scaling: %d\n",pcbddc->use_deluxe_scaling);CHKERRQ(ierr); 156efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe zerorows: %d\n",pcbddc->deluxe_zerorows);CHKERRQ(ierr); 157efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe singlemat: %d\n",pcbddc->deluxe_singlemat);CHKERRQ(ierr); 158efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Rebuild interface graph for Schur principal minors: %d\n",pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 15950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Number of dofs' layers for the computation of principal minors: %D\n",pcbddc->sub_schurs_layers);CHKERRQ(ierr); 160efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use user CSR graph to compute successive layers: %d\n",pcbddc->sub_schurs_use_useradj);CHKERRQ(ierr); 161bd2a564bSStefano Zampini if (pcbddc->adaptive_threshold[1] != pcbddc->adaptive_threshold[0]) { 162bd2a564bSStefano 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); 163bd2a564bSStefano Zampini } else { 164bd2a564bSStefano 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); 165bd2a564bSStefano Zampini } 16650e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Min constraints / connected component: %D\n",pcbddc->adaptive_nmin);CHKERRQ(ierr); 16750e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Max constraints / connected component: %D\n",pcbddc->adaptive_nmax);CHKERRQ(ierr); 168efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Invert exact Schur complement for adaptive selection: %d\n",pcbddc->sub_schurs_exact_schur);CHKERRQ(ierr); 169efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Symmetric computation of primal basis functions: %d\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 17050e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Num. Procs. to map coarse adjacency list: %D\n",pcbddc->coarse_adj_red);CHKERRQ(ierr); 17150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Coarse eqs per proc (significant at the coarsest level): %D\n",pcbddc->coarse_eqs_per_proc);CHKERRQ(ierr); 1728361f951SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Detect disconnected: %d (filter %d)\n",pcbddc->detect_disconnected,pcbddc->detect_disconnected_filter);CHKERRQ(ierr); 173efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Benign subspace trick: %d (change explicit %d)\n",pcbddc->benign_saddle_point,pcbddc->benign_change_explicit);CHKERRQ(ierr); 174efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Benign subspace trick is active: %d\n",pcbddc->benign_have_null);CHKERRQ(ierr); 175efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Algebraic computation of no-net-flux %d\n",pcbddc->compute_nonetflux);CHKERRQ(ierr); 176b74ba07aSstefano_zampini if (!pc->setupcalled) PetscFunctionReturn(0); 1776b78500eSPatrick Sanan 178fbad9177SStefano Zampini /* compute interface size */ 179e9627c49SStefano Zampini ierr = VecSet(pcis->vec1_B,1.0);CHKERRQ(ierr); 180e9627c49SStefano Zampini ierr = MatCreateVecs(pc->pmat,&counter,0);CHKERRQ(ierr); 181e9627c49SStefano Zampini ierr = VecSet(counter,0.0);CHKERRQ(ierr); 182e9627c49SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 183e9627c49SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 184e9627c49SStefano Zampini ierr = VecSum(counter,&interface_size);CHKERRQ(ierr); 185e9627c49SStefano Zampini ierr = VecDestroy(&counter);CHKERRQ(ierr); 186fbad9177SStefano Zampini 187fbad9177SStefano Zampini /* compute some statistics on the domain decomposition */ 188e9627c49SStefano Zampini gsum[0] = 1; 189fbad9177SStefano Zampini gsum[1] = gsum[2] = gsum[3] = gsum[4] = gsum[5] = 0; 190e9627c49SStefano Zampini loc[0] = !!pcis->n; 191e9627c49SStefano Zampini loc[1] = pcis->n - pcis->n_B; 192e9627c49SStefano Zampini loc[2] = pcis->n_B; 193e9627c49SStefano Zampini loc[3] = pcbddc->local_primal_size; 194345ecf6cSStefano Zampini loc[4] = pcis->n; 195fbad9177SStefano Zampini loc[5] = pcbddc->n_local_subs > 0 ? pcbddc->n_local_subs : (pcis->n ? 1 : 0); 196fbad9177SStefano Zampini loc[6] = pcbddc->benign_n; 197fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gsum,6,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 198fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = -1; 199fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gmax,6,MPIU_INT64,MPI_MAX,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 200fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = PETSC_MAX_INT; 201fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gmin,6,MPIU_INT64,MPI_MIN,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 202fbad9177SStefano Zampini ierr = MPI_Reduce(&loc[6],&totbenign,1,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 203e9627c49SStefano Zampini if (pcbddc->coarse_size) { 204e9627c49SStefano Zampini ratio1 = pc->pmat->rmap->N/(1.*pcbddc->coarse_size); 205e9627c49SStefano Zampini ratio2 = PetscRealPart(interface_size)/pcbddc->coarse_size; 206e9627c49SStefano Zampini } 207efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ********************************** STATISTICS AT LEVEL %d **********************************\n",pcbddc->current_level);CHKERRQ(ierr); 20850e0721cSStefano 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); 20950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Coarsening ratios: all/coarse %D interface/coarse %D\n",(PetscInt)ratio1,(PetscInt)ratio2);CHKERRQ(ierr); 21050e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Active processes : %D\n",(PetscInt)gsum[0]);CHKERRQ(ierr); 21150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Total subdomains : %D\n",(PetscInt)gsum[5]);CHKERRQ(ierr); 212345ecf6cSStefano Zampini if (pcbddc->benign_have_null) { 21350e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Benign subs : %D\n",(PetscInt)totbenign);CHKERRQ(ierr); 214345ecf6cSStefano Zampini } 21550e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Dofs type :\tMIN\tMAX\tMEAN\n");CHKERRQ(ierr); 21650e0721cSStefano 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); 21750e0721cSStefano 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); 21850e0721cSStefano 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); 21950e0721cSStefano 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); 22050e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Local subs :\t%D\t%D\n" ,(PetscInt)gmin[5],(PetscInt)gmax[5]);CHKERRQ(ierr); 22150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," ********************************** COARSE PROBLEM DETAILS *********************************\n");CHKERRQ(ierr); 22227b6a85dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 223e9627c49SStefano Zampini 224fbad9177SStefano Zampini /* the coarse problem can be handled by a different communicator */ 225e9627c49SStefano Zampini if (pcbddc->coarse_ksp) color = 1; 226e9627c49SStefano Zampini else color = 0; 227e9627c49SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 2284b2aedd3SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 229e9627c49SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)pc),&subcomm);CHKERRQ(ierr); 2304b2aedd3SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,PetscMin(size,2));CHKERRQ(ierr); 231e9627c49SStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 232e9627c49SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 233e9627c49SStefano Zampini if (color == 1) { 234e9627c49SStefano Zampini ierr = KSPView(pcbddc->coarse_ksp,subviewer);CHKERRQ(ierr); 235e9627c49SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 236e9627c49SStefano Zampini } 237e9627c49SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 238e9627c49SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 239e9627c49SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 240e9627c49SStefano Zampini } 2416b78500eSPatrick Sanan PetscFunctionReturn(0); 2426b78500eSPatrick Sanan } 243a13144ffSStefano Zampini 2441e0482f5SStefano Zampini static PetscErrorCode PCBDDCSetDiscreteGradient_BDDC(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 245a13144ffSStefano Zampini { 246a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 247a13144ffSStefano Zampini PetscErrorCode ierr; 248a13144ffSStefano Zampini 249a13144ffSStefano Zampini PetscFunctionBegin; 250a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr); 251a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 252a13144ffSStefano Zampini pcbddc->discretegradient = G; 253a13144ffSStefano Zampini pcbddc->nedorder = order > 0 ? order : -order; 254495a2a07SStefano Zampini pcbddc->nedfield = field; 2551e0482f5SStefano Zampini pcbddc->nedglobal = global; 2561e0482f5SStefano Zampini pcbddc->conforming = conforming; 257a13144ffSStefano Zampini PetscFunctionReturn(0); 258a13144ffSStefano Zampini } 259a13144ffSStefano Zampini 260a13144ffSStefano Zampini /*@ 261a13144ffSStefano Zampini PCBDDCSetDiscreteGradient - Sets the discrete gradient 262a13144ffSStefano Zampini 263a13144ffSStefano Zampini Collective on PC 264a13144ffSStefano Zampini 265a13144ffSStefano Zampini Input Parameters: 266a13144ffSStefano Zampini + pc - the preconditioning context 267a13144ffSStefano Zampini . G - the discrete gradient matrix (should be in AIJ format) 268a13144ffSStefano Zampini . order - the order of the Nedelec space (1 for the lowest order) 269495a2a07SStefano Zampini . field - the field id of the Nedelec dofs (not used if the fields have not been specified) 2701e0482f5SStefano Zampini . global - the type of global ordering for the rows of G 271a13144ffSStefano Zampini - conforming - whether the mesh is conforming or not 272a13144ffSStefano Zampini 273a13144ffSStefano Zampini Level: advanced 274a13144ffSStefano Zampini 27595452b02SPatrick Sanan Notes: 27695452b02SPatrick Sanan The discrete gradient matrix G is used to analyze the subdomain edges, and it should not contain any zero entry. 277495a2a07SStefano Zampini For variable order spaces, the order should be set to zero. 2781e0482f5SStefano Zampini If global is true, the rows of G should be given in global ordering for the whole dofs; 2791e0482f5SStefano Zampini if false, the ordering should be global for the Nedelec field. 2801e0482f5SStefano 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 2811e0482f5SStefano Zampini and geid the one for the Nedelec field. 282a13144ffSStefano Zampini 283495a2a07SStefano Zampini .seealso: PCBDDC,PCBDDCSetDofsSplitting(),PCBDDCSetDofsSplittingLocal() 284a13144ffSStefano Zampini @*/ 2851e0482f5SStefano Zampini PetscErrorCode PCBDDCSetDiscreteGradient(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 286a13144ffSStefano Zampini { 287a13144ffSStefano Zampini PetscErrorCode ierr; 288a13144ffSStefano Zampini 289a13144ffSStefano Zampini PetscFunctionBegin; 290a13144ffSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 291a13144ffSStefano Zampini PetscValidHeaderSpecific(G,MAT_CLASSID,2); 292a13144ffSStefano Zampini PetscValidLogicalCollectiveInt(pc,order,3); 2931e0482f5SStefano Zampini PetscValidLogicalCollectiveInt(pc,field,4); 2941e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,global,5); 2951e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,conforming,6); 2961e0482f5SStefano Zampini PetscCheckSameComm(pc,1,G,2); 2971e0482f5SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDiscreteGradient_C",(PC,Mat,PetscInt,PetscInt,PetscBool,PetscBool),(pc,G,order,field,global,conforming));CHKERRQ(ierr); 298a13144ffSStefano Zampini PetscFunctionReturn(0); 299a13144ffSStefano Zampini } 300a13144ffSStefano Zampini 3018ae0ca82SStefano Zampini static PetscErrorCode PCBDDCSetDivergenceMat_BDDC(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 302a198735bSStefano Zampini { 303a198735bSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 304a198735bSStefano Zampini PetscErrorCode ierr; 3056b78500eSPatrick Sanan 306a198735bSStefano Zampini PetscFunctionBegin; 307a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)divudotp);CHKERRQ(ierr); 308a198735bSStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 309a198735bSStefano Zampini pcbddc->divudotp = divudotp; 3108ae0ca82SStefano Zampini pcbddc->divudotp_trans = trans; 311a198735bSStefano Zampini pcbddc->compute_nonetflux = PETSC_TRUE; 312a198735bSStefano Zampini if (vl2l) { 313a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2l);CHKERRQ(ierr); 314fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 315a198735bSStefano Zampini pcbddc->divudotp_vl2l = vl2l; 316a198735bSStefano Zampini } 317a198735bSStefano Zampini PetscFunctionReturn(0); 318a198735bSStefano Zampini } 3193d996552SStefano Zampini 320a198735bSStefano Zampini /*@ 321a198735bSStefano Zampini PCBDDCSetDivergenceMat - Sets the linear operator representing \int_\Omega \div {\bf u} \cdot p dx 322a198735bSStefano Zampini 323a198735bSStefano Zampini Collective on PC 324a198735bSStefano Zampini 325a198735bSStefano Zampini Input Parameters: 326a198735bSStefano Zampini + pc - the preconditioning context 327a198735bSStefano Zampini . divudotp - the matrix (must be of type MATIS) 3288ae0ca82SStefano Zampini . trans - if trans if false (resp. true), then pressures are in the test (trial) space and velocities are in the trial (test) space. 32905a3bf82SStefano 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 330a198735bSStefano Zampini 331a198735bSStefano Zampini Level: advanced 332a198735bSStefano Zampini 33395452b02SPatrick Sanan Notes: 33495452b02SPatrick Sanan This auxiliary matrix is used to compute quadrature weights representing the net-flux across subdomain boundaries 33505a3bf82SStefano Zampini If vl2l is NULL, the local ordering for velocities in divudotp should match that of the preconditioning matrix 336a198735bSStefano Zampini 337a198735bSStefano Zampini .seealso: PCBDDC 338a198735bSStefano Zampini @*/ 3398ae0ca82SStefano Zampini PetscErrorCode PCBDDCSetDivergenceMat(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 340a198735bSStefano Zampini { 341a198735bSStefano Zampini PetscBool ismatis; 342a198735bSStefano Zampini PetscErrorCode ierr; 343a198735bSStefano Zampini 344a198735bSStefano Zampini PetscFunctionBegin; 345a198735bSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 346a198735bSStefano Zampini PetscValidHeaderSpecific(divudotp,MAT_CLASSID,2); 347a198735bSStefano Zampini PetscCheckSameComm(pc,1,divudotp,2); 3488ae0ca82SStefano Zampini PetscValidLogicalCollectiveBool(pc,trans,3); 3498ae0ca82SStefano Zampini if (vl2l) PetscValidHeaderSpecific(divudotp,IS_CLASSID,4); 350a198735bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)divudotp,MATIS,&ismatis);CHKERRQ(ierr); 351a198735bSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Divergence matrix needs to be of type MATIS"); 3528ae0ca82SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDivergenceMat_C",(PC,Mat,PetscBool,IS),(pc,divudotp,trans,vl2l));CHKERRQ(ierr); 353a198735bSStefano Zampini PetscFunctionReturn(0); 354a198735bSStefano Zampini } 3552d505d7fSStefano Zampini 3561dd7afcfSStefano Zampini static PetscErrorCode PCBDDCSetChangeOfBasisMat_BDDC(PC pc, Mat change, PetscBool interior) 357b9b85e73SStefano Zampini { 358b9b85e73SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 359b9b85e73SStefano Zampini PetscErrorCode ierr; 360b9b85e73SStefano Zampini 361b9b85e73SStefano Zampini PetscFunctionBegin; 362b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)change);CHKERRQ(ierr); 36356282151SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 364b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = change; 3651dd7afcfSStefano Zampini pcbddc->change_interior = interior; 366b9b85e73SStefano Zampini PetscFunctionReturn(0); 367b9b85e73SStefano Zampini } 368b9b85e73SStefano Zampini /*@ 369906d46d4SStefano Zampini PCBDDCSetChangeOfBasisMat - Set user defined change of basis for dofs 370b9b85e73SStefano Zampini 371b9b85e73SStefano Zampini Collective on PC 372b9b85e73SStefano Zampini 373b9b85e73SStefano Zampini Input Parameters: 374b9b85e73SStefano Zampini + pc - the preconditioning context 3751dd7afcfSStefano Zampini . change - the change of basis matrix 3761dd7afcfSStefano Zampini - interior - whether or not the change of basis modifies interior dofs 377b9b85e73SStefano Zampini 378b9b85e73SStefano Zampini Level: intermediate 379b9b85e73SStefano Zampini 380b9b85e73SStefano Zampini Notes: 381b9b85e73SStefano Zampini 382b9b85e73SStefano Zampini .seealso: PCBDDC 383b9b85e73SStefano Zampini @*/ 3841dd7afcfSStefano Zampini PetscErrorCode PCBDDCSetChangeOfBasisMat(PC pc, Mat change, PetscBool interior) 385b9b85e73SStefano Zampini { 386b9b85e73SStefano Zampini PetscErrorCode ierr; 387b9b85e73SStefano Zampini 388b9b85e73SStefano Zampini PetscFunctionBegin; 389b9b85e73SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 390b9b85e73SStefano Zampini PetscValidHeaderSpecific(change,MAT_CLASSID,2); 391906d46d4SStefano Zampini PetscCheckSameComm(pc,1,change,2); 392906d46d4SStefano Zampini if (pc->mat) { 393906d46d4SStefano Zampini PetscInt rows_c,cols_c,rows,cols; 394906d46d4SStefano Zampini ierr = MatGetSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 395906d46d4SStefano Zampini ierr = MatGetSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 396e0fe2d75SToby Isaac if (rows_c != rows) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of rows for change of basis matrix! %D != %D",rows_c,rows); 397e0fe2d75SToby Isaac if (cols_c != cols) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of columns for change of basis matrix! %D != %D",cols_c,cols); 398906d46d4SStefano Zampini ierr = MatGetLocalSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 399906d46d4SStefano Zampini ierr = MatGetLocalSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 400e0fe2d75SToby Isaac if (rows_c != rows) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of local rows for change of basis matrix! %D != %D",rows_c,rows); 401e0fe2d75SToby Isaac if (cols_c != cols) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of local columns for change of basis matrix! %D != %D",cols_c,cols); 402906d46d4SStefano Zampini } 4031dd7afcfSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetChangeOfBasisMat_C",(PC,Mat,PetscBool),(pc,change,interior));CHKERRQ(ierr); 404b9b85e73SStefano Zampini PetscFunctionReturn(0); 405b9b85e73SStefano Zampini } 4062d505d7fSStefano Zampini 40730368db7SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesIS_BDDC(PC pc, IS PrimalVertices) 40830368db7SStefano Zampini { 40930368db7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 41056282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 41130368db7SStefano Zampini PetscErrorCode ierr; 41230368db7SStefano Zampini 41330368db7SStefano Zampini PetscFunctionBegin; 41456282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 41556282151SStefano Zampini if (pcbddc->user_primal_vertices) { 41656282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices,&isequal);CHKERRQ(ierr); 41756282151SStefano Zampini } 41830368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 41930368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 42030368db7SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 42156282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 42230368db7SStefano Zampini PetscFunctionReturn(0); 42330368db7SStefano Zampini } 424ab8c8b98SStefano Zampini 42530368db7SStefano Zampini /*@ 42630368db7SStefano Zampini PCBDDCSetPrimalVerticesIS - Set additional user defined primal vertices in PCBDDC 42730368db7SStefano Zampini 42830368db7SStefano Zampini Collective 42930368db7SStefano Zampini 43030368db7SStefano Zampini Input Parameters: 43130368db7SStefano Zampini + pc - the preconditioning context 43230368db7SStefano Zampini - PrimalVertices - index set of primal vertices in global numbering (can be empty) 43330368db7SStefano Zampini 43430368db7SStefano Zampini Level: intermediate 43530368db7SStefano Zampini 43630368db7SStefano Zampini Notes: 43730368db7SStefano Zampini Any process can list any global node 43830368db7SStefano Zampini 43930368db7SStefano Zampini .seealso: PCBDDC 44030368db7SStefano Zampini @*/ 44130368db7SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesIS(PC pc, IS PrimalVertices) 44230368db7SStefano Zampini { 44330368db7SStefano Zampini PetscErrorCode ierr; 44430368db7SStefano Zampini 44530368db7SStefano Zampini PetscFunctionBegin; 44630368db7SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 44730368db7SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 44830368db7SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 44930368db7SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 45030368db7SStefano Zampini PetscFunctionReturn(0); 45130368db7SStefano Zampini } 4522d505d7fSStefano Zampini 453674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 454674ae819SStefano Zampini { 455674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 45656282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 457674ae819SStefano Zampini PetscErrorCode ierr; 4581e6b0712SBarry Smith 459674ae819SStefano Zampini PetscFunctionBegin; 46056282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 46156282151SStefano Zampini if (pcbddc->user_primal_vertices_local) { 46256282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices_local,&isequal);CHKERRQ(ierr); 46356282151SStefano Zampini } 464674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 46530368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 46630368db7SStefano Zampini pcbddc->user_primal_vertices_local = PrimalVertices; 46756282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 468674ae819SStefano Zampini PetscFunctionReturn(0); 469674ae819SStefano Zampini } 470674ae819SStefano Zampini /*@ 47128509bceSStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC 472674ae819SStefano Zampini 47317eb1463SStefano Zampini Collective 474674ae819SStefano Zampini 475674ae819SStefano Zampini Input Parameters: 476674ae819SStefano Zampini + pc - the preconditioning context 47717eb1463SStefano Zampini - PrimalVertices - index set of primal vertices in local numbering (can be empty) 478674ae819SStefano Zampini 479674ae819SStefano Zampini Level: intermediate 480674ae819SStefano Zampini 481674ae819SStefano Zampini Notes: 482674ae819SStefano Zampini 483674ae819SStefano Zampini .seealso: PCBDDC 484674ae819SStefano Zampini @*/ 485674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 486674ae819SStefano Zampini { 487674ae819SStefano Zampini PetscErrorCode ierr; 488674ae819SStefano Zampini 489674ae819SStefano Zampini PetscFunctionBegin; 490674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 491674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 49217eb1463SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 493674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 494674ae819SStefano Zampini PetscFunctionReturn(0); 495674ae819SStefano Zampini } 4962d505d7fSStefano Zampini 4974fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 4984fad6a16SStefano Zampini { 4994fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5004fad6a16SStefano Zampini 5014fad6a16SStefano Zampini PetscFunctionBegin; 5024fad6a16SStefano Zampini pcbddc->coarsening_ratio = k; 5034fad6a16SStefano Zampini PetscFunctionReturn(0); 5044fad6a16SStefano Zampini } 5051e6b0712SBarry Smith 5064fad6a16SStefano Zampini /*@ 50728509bceSStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel 5084fad6a16SStefano Zampini 5094fad6a16SStefano Zampini Logically collective on PC 5104fad6a16SStefano Zampini 5114fad6a16SStefano Zampini Input Parameters: 5124fad6a16SStefano Zampini + pc - the preconditioning context 51328509bceSStefano Zampini - k - coarsening ratio (H/h at the coarser level) 5144fad6a16SStefano Zampini 5150f202f7eSStefano Zampini Options Database Keys: 5160f202f7eSStefano Zampini . -pc_bddc_coarsening_ratio 5174fad6a16SStefano Zampini 5184fad6a16SStefano Zampini Level: intermediate 5194fad6a16SStefano Zampini 5204fad6a16SStefano Zampini Notes: 5210f202f7eSStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level 5224fad6a16SStefano Zampini 5230f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetLevels() 5244fad6a16SStefano Zampini @*/ 5254fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 5264fad6a16SStefano Zampini { 5274fad6a16SStefano Zampini PetscErrorCode ierr; 5284fad6a16SStefano Zampini 5294fad6a16SStefano Zampini PetscFunctionBegin; 5304fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5312b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,k,2); 5324fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 5334fad6a16SStefano Zampini PetscFunctionReturn(0); 5344fad6a16SStefano Zampini } 5352b510759SStefano Zampini 536b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */ 537b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg) 538b8ffe317SStefano Zampini { 539b8ffe317SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 540b8ffe317SStefano Zampini 541b8ffe317SStefano Zampini PetscFunctionBegin; 54285c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = flg; 543b8ffe317SStefano Zampini PetscFunctionReturn(0); 544b8ffe317SStefano Zampini } 545b8ffe317SStefano Zampini 546b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg) 5472b510759SStefano Zampini { 5482b510759SStefano Zampini PetscErrorCode ierr; 5492b510759SStefano Zampini 5502b510759SStefano Zampini PetscFunctionBegin; 5512b510759SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 552b8ffe317SStefano Zampini PetscValidLogicalCollectiveBool(pc,flg,2); 553b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr); 5542b510759SStefano Zampini PetscFunctionReturn(0); 5552b510759SStefano Zampini } 5561e6b0712SBarry Smith 5572b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level) 5584fad6a16SStefano Zampini { 5594fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5604fad6a16SStefano Zampini 5614fad6a16SStefano Zampini PetscFunctionBegin; 5622b510759SStefano Zampini pcbddc->current_level = level; 5634fad6a16SStefano Zampini PetscFunctionReturn(0); 5644fad6a16SStefano Zampini } 5651e6b0712SBarry Smith 566b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 567b8ffe317SStefano Zampini { 568b8ffe317SStefano Zampini PetscErrorCode ierr; 569b8ffe317SStefano Zampini 570b8ffe317SStefano Zampini PetscFunctionBegin; 571b8ffe317SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 572b8ffe317SStefano Zampini PetscValidLogicalCollectiveInt(pc,level,2); 573b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr); 574b8ffe317SStefano Zampini PetscFunctionReturn(0); 575b8ffe317SStefano Zampini } 576b8ffe317SStefano Zampini 5772b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels) 5782b510759SStefano Zampini { 5792b510759SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5802b510759SStefano Zampini 5812b510759SStefano Zampini PetscFunctionBegin; 5822b510759SStefano Zampini pcbddc->max_levels = levels; 5832b510759SStefano Zampini PetscFunctionReturn(0); 5842b510759SStefano Zampini } 5852b510759SStefano Zampini 5864fad6a16SStefano Zampini /*@ 587*37ebbdf7SStefano Zampini PCBDDCSetLevels - Sets the maximum number of additional levels allowed for multilevel BDDC 5884fad6a16SStefano Zampini 5894fad6a16SStefano Zampini Logically collective on PC 5904fad6a16SStefano Zampini 5914fad6a16SStefano Zampini Input Parameters: 5924fad6a16SStefano Zampini + pc - the preconditioning context 593*37ebbdf7SStefano Zampini - levels - the maximum number of levels 5944fad6a16SStefano Zampini 5950f202f7eSStefano Zampini Options Database Keys: 5960f202f7eSStefano Zampini . -pc_bddc_levels 5974fad6a16SStefano Zampini 5984fad6a16SStefano Zampini Level: intermediate 5994fad6a16SStefano Zampini 6004fad6a16SStefano Zampini Notes: 601*37ebbdf7SStefano Zampini The default value is 0, that gives the classical two-levels BDDC 6024fad6a16SStefano Zampini 6030f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetCoarseningRatio() 6044fad6a16SStefano Zampini @*/ 6052b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels) 6064fad6a16SStefano Zampini { 6074fad6a16SStefano Zampini PetscErrorCode ierr; 6084fad6a16SStefano Zampini 6094fad6a16SStefano Zampini PetscFunctionBegin; 6104fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6112b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,levels,2); 612*37ebbdf7SStefano Zampini if (levels > PETSC_PCBDDC_MAXLEVELS-1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Maximum number of additional levels for BDDC is %d\n",PETSC_PCBDDC_MAXLEVELS-1); 6132b510759SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr); 6144fad6a16SStefano Zampini PetscFunctionReturn(0); 6154fad6a16SStefano Zampini } 6161e6b0712SBarry Smith 6173b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 6183b03a366Sstefano_zampini { 6193b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 62056282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 6213b03a366Sstefano_zampini PetscErrorCode ierr; 6223b03a366Sstefano_zampini 6233b03a366Sstefano_zampini PetscFunctionBegin; 62456282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 62556282151SStefano Zampini if (pcbddc->DirichletBoundaries) { 62656282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundaries,&isequal);CHKERRQ(ierr); 62756282151SStefano Zampini } 628785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 629785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 6303b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 63136e030ebSStefano Zampini pcbddc->DirichletBoundaries = DirichletBoundaries; 63256282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 6333b03a366Sstefano_zampini PetscFunctionReturn(0); 6343b03a366Sstefano_zampini } 6351e6b0712SBarry Smith 6363b03a366Sstefano_zampini /*@ 63728509bceSStefano Zampini PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem. 6383b03a366Sstefano_zampini 639785d1243SStefano Zampini Collective 6403b03a366Sstefano_zampini 6413b03a366Sstefano_zampini Input Parameters: 6423b03a366Sstefano_zampini + pc - the preconditioning context 643785d1243SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries 6443b03a366Sstefano_zampini 6453b03a366Sstefano_zampini Level: intermediate 6463b03a366Sstefano_zampini 6470f202f7eSStefano Zampini Notes: 6480f202f7eSStefano Zampini Provide the information if you used MatZeroRows/Columns routines. Any process can list any global node 6493b03a366Sstefano_zampini 6500f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundariesLocal(), MatZeroRows(), MatZeroRowsColumns() 6513b03a366Sstefano_zampini @*/ 6523b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 6533b03a366Sstefano_zampini { 6543b03a366Sstefano_zampini PetscErrorCode ierr; 6553b03a366Sstefano_zampini 6563b03a366Sstefano_zampini PetscFunctionBegin; 6573b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 658674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 659785d1243SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 6603b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 6613b03a366Sstefano_zampini PetscFunctionReturn(0); 6623b03a366Sstefano_zampini } 6631e6b0712SBarry Smith 66482ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries) 6653b03a366Sstefano_zampini { 6663b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 66756282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 6683b03a366Sstefano_zampini PetscErrorCode ierr; 6693b03a366Sstefano_zampini 6703b03a366Sstefano_zampini PetscFunctionBegin; 67156282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 67256282151SStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 67356282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundariesLocal,&isequal);CHKERRQ(ierr); 67456282151SStefano Zampini } 675785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 676785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 6773b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 678785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = DirichletBoundaries; 67956282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 6803b03a366Sstefano_zampini PetscFunctionReturn(0); 6813b03a366Sstefano_zampini } 6823b03a366Sstefano_zampini 6833b03a366Sstefano_zampini /*@ 68482ba6b80SStefano Zampini PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering. 6853b03a366Sstefano_zampini 686785d1243SStefano Zampini Collective 6873b03a366Sstefano_zampini 6883b03a366Sstefano_zampini Input Parameters: 6893b03a366Sstefano_zampini + pc - the preconditioning context 69082ba6b80SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering) 6913b03a366Sstefano_zampini 6923b03a366Sstefano_zampini Level: intermediate 6933b03a366Sstefano_zampini 6943b03a366Sstefano_zampini Notes: 6953b03a366Sstefano_zampini 6960f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundaries(), MatZeroRows(), MatZeroRowsColumns() 6973b03a366Sstefano_zampini @*/ 69882ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries) 6993b03a366Sstefano_zampini { 7003b03a366Sstefano_zampini PetscErrorCode ierr; 7013b03a366Sstefano_zampini 7023b03a366Sstefano_zampini PetscFunctionBegin; 7033b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 7043b03a366Sstefano_zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 70582ba6b80SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 70682ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 7073b03a366Sstefano_zampini PetscFunctionReturn(0); 7083b03a366Sstefano_zampini } 7093b03a366Sstefano_zampini 71053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 7110c7d97c5SJed Brown { 7120c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 71356282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 71453cdbc3dSStefano Zampini PetscErrorCode ierr; 7150c7d97c5SJed Brown 7160c7d97c5SJed Brown PetscFunctionBegin; 71756282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 71856282151SStefano Zampini if (pcbddc->NeumannBoundaries) { 71956282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundaries,&isequal);CHKERRQ(ierr); 72056282151SStefano Zampini } 721785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 722785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 72353cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 72436e030ebSStefano Zampini pcbddc->NeumannBoundaries = NeumannBoundaries; 72556282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7260c7d97c5SJed Brown PetscFunctionReturn(0); 7270c7d97c5SJed Brown } 7281e6b0712SBarry Smith 72957527edcSJed Brown /*@ 73028509bceSStefano Zampini PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem. 73157527edcSJed Brown 732785d1243SStefano Zampini Collective 73357527edcSJed Brown 73457527edcSJed Brown Input Parameters: 73557527edcSJed Brown + pc - the preconditioning context 736785d1243SStefano Zampini - NeumannBoundaries - parallel IS defining the Neumann boundaries 73757527edcSJed Brown 73857527edcSJed Brown Level: intermediate 73957527edcSJed Brown 7400f202f7eSStefano Zampini Notes: 7410f202f7eSStefano Zampini Any process can list any global node 74257527edcSJed Brown 7430f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundariesLocal() 74457527edcSJed Brown @*/ 74553cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 7460c7d97c5SJed Brown { 7470c7d97c5SJed Brown PetscErrorCode ierr; 7480c7d97c5SJed Brown 7490c7d97c5SJed Brown PetscFunctionBegin; 7500c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 751674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 752785d1243SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 75353cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 75453cdbc3dSStefano Zampini PetscFunctionReturn(0); 75553cdbc3dSStefano Zampini } 7561e6b0712SBarry Smith 75782ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries) 7580c7d97c5SJed Brown { 7590c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 76056282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 7610c7d97c5SJed Brown PetscErrorCode ierr; 7620c7d97c5SJed Brown 7630c7d97c5SJed Brown PetscFunctionBegin; 76456282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 76556282151SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 76656282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundariesLocal,&isequal);CHKERRQ(ierr); 76756282151SStefano Zampini } 768785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 769785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 7700c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 771785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = NeumannBoundaries; 77256282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7730c7d97c5SJed Brown PetscFunctionReturn(0); 7740c7d97c5SJed Brown } 7750c7d97c5SJed Brown 7760c7d97c5SJed Brown /*@ 77782ba6b80SStefano Zampini PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering. 7780c7d97c5SJed Brown 779785d1243SStefano Zampini Collective 7800c7d97c5SJed Brown 7810c7d97c5SJed Brown Input Parameters: 7820c7d97c5SJed Brown + pc - the preconditioning context 78382ba6b80SStefano Zampini - NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering) 7840c7d97c5SJed Brown 7850c7d97c5SJed Brown Level: intermediate 7860c7d97c5SJed Brown 7870c7d97c5SJed Brown Notes: 7880c7d97c5SJed Brown 7890f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundaries() 7900c7d97c5SJed Brown @*/ 79182ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries) 7920c7d97c5SJed Brown { 7930c7d97c5SJed Brown PetscErrorCode ierr; 7940c7d97c5SJed Brown 7950c7d97c5SJed Brown PetscFunctionBegin; 7960c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 7970c7d97c5SJed Brown PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 79882ba6b80SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 79982ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 80053cdbc3dSStefano Zampini PetscFunctionReturn(0); 80153cdbc3dSStefano Zampini } 80253cdbc3dSStefano Zampini 803da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 804da1bb401SStefano Zampini { 805da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 806da1bb401SStefano Zampini 807da1bb401SStefano Zampini PetscFunctionBegin; 808da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 809da1bb401SStefano Zampini PetscFunctionReturn(0); 810da1bb401SStefano Zampini } 8111e6b0712SBarry Smith 812da1bb401SStefano Zampini /*@ 813785d1243SStefano Zampini PCBDDCGetDirichletBoundaries - Get parallel IS for Dirichlet boundaries 814da1bb401SStefano Zampini 815785d1243SStefano Zampini Collective 816785d1243SStefano Zampini 817785d1243SStefano Zampini Input Parameters: 818785d1243SStefano Zampini . pc - the preconditioning context 819785d1243SStefano Zampini 820785d1243SStefano Zampini Output Parameters: 821785d1243SStefano Zampini . DirichletBoundaries - index set defining the Dirichlet boundaries 822785d1243SStefano Zampini 823785d1243SStefano Zampini Level: intermediate 824785d1243SStefano Zampini 8250f202f7eSStefano Zampini Notes: 8260f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetDirichletBoundaries 827785d1243SStefano Zampini 828785d1243SStefano Zampini .seealso: PCBDDC 829785d1243SStefano Zampini @*/ 830785d1243SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 831785d1243SStefano Zampini { 832785d1243SStefano Zampini PetscErrorCode ierr; 833785d1243SStefano Zampini 834785d1243SStefano Zampini PetscFunctionBegin; 835785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 836785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 837785d1243SStefano Zampini PetscFunctionReturn(0); 838785d1243SStefano Zampini } 839785d1243SStefano Zampini 840785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries) 841785d1243SStefano Zampini { 842785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 843785d1243SStefano Zampini 844785d1243SStefano Zampini PetscFunctionBegin; 845785d1243SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundariesLocal; 846785d1243SStefano Zampini PetscFunctionReturn(0); 847785d1243SStefano Zampini } 848785d1243SStefano Zampini 849da1bb401SStefano Zampini /*@ 85082ba6b80SStefano Zampini PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering) 851da1bb401SStefano Zampini 852785d1243SStefano Zampini Collective 853da1bb401SStefano Zampini 854da1bb401SStefano Zampini Input Parameters: 85528509bceSStefano Zampini . pc - the preconditioning context 856da1bb401SStefano Zampini 857da1bb401SStefano Zampini Output Parameters: 85828509bceSStefano Zampini . DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 859da1bb401SStefano Zampini 860da1bb401SStefano Zampini Level: intermediate 861da1bb401SStefano Zampini 862da1bb401SStefano Zampini Notes: 8630f202f7eSStefano 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). 8640f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 865da1bb401SStefano Zampini 866da1bb401SStefano Zampini .seealso: PCBDDC 867da1bb401SStefano Zampini @*/ 86882ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries) 869da1bb401SStefano Zampini { 870da1bb401SStefano Zampini PetscErrorCode ierr; 871da1bb401SStefano Zampini 872da1bb401SStefano Zampini PetscFunctionBegin; 873da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 87482ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 875da1bb401SStefano Zampini PetscFunctionReturn(0); 876da1bb401SStefano Zampini } 8771e6b0712SBarry Smith 87853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 87953cdbc3dSStefano Zampini { 88053cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 88153cdbc3dSStefano Zampini 88253cdbc3dSStefano Zampini PetscFunctionBegin; 88353cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 88453cdbc3dSStefano Zampini PetscFunctionReturn(0); 88553cdbc3dSStefano Zampini } 8861e6b0712SBarry Smith 88753cdbc3dSStefano Zampini /*@ 888785d1243SStefano Zampini PCBDDCGetNeumannBoundaries - Get parallel IS for Neumann boundaries 88953cdbc3dSStefano Zampini 890785d1243SStefano Zampini Collective 891785d1243SStefano Zampini 892785d1243SStefano Zampini Input Parameters: 893785d1243SStefano Zampini . pc - the preconditioning context 894785d1243SStefano Zampini 895785d1243SStefano Zampini Output Parameters: 896785d1243SStefano Zampini . NeumannBoundaries - index set defining the Neumann boundaries 897785d1243SStefano Zampini 898785d1243SStefano Zampini Level: intermediate 899785d1243SStefano Zampini 9000f202f7eSStefano Zampini Notes: 9010f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetNeumannBoundaries 902785d1243SStefano Zampini 903785d1243SStefano Zampini .seealso: PCBDDC 904785d1243SStefano Zampini @*/ 905785d1243SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 906785d1243SStefano Zampini { 907785d1243SStefano Zampini PetscErrorCode ierr; 908785d1243SStefano Zampini 909785d1243SStefano Zampini PetscFunctionBegin; 910785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 911785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 912785d1243SStefano Zampini PetscFunctionReturn(0); 913785d1243SStefano Zampini } 914785d1243SStefano Zampini 915785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries) 916785d1243SStefano Zampini { 917785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 918785d1243SStefano Zampini 919785d1243SStefano Zampini PetscFunctionBegin; 920785d1243SStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundariesLocal; 921785d1243SStefano Zampini PetscFunctionReturn(0); 922785d1243SStefano Zampini } 923785d1243SStefano Zampini 92453cdbc3dSStefano Zampini /*@ 92582ba6b80SStefano Zampini PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering) 92653cdbc3dSStefano Zampini 927785d1243SStefano Zampini Collective 92853cdbc3dSStefano Zampini 92953cdbc3dSStefano Zampini Input Parameters: 93028509bceSStefano Zampini . pc - the preconditioning context 93153cdbc3dSStefano Zampini 93253cdbc3dSStefano Zampini Output Parameters: 93328509bceSStefano Zampini . NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 93453cdbc3dSStefano Zampini 93553cdbc3dSStefano Zampini Level: intermediate 93653cdbc3dSStefano Zampini 93753cdbc3dSStefano Zampini Notes: 9380f202f7eSStefano 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). 9390f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 94053cdbc3dSStefano Zampini 94153cdbc3dSStefano Zampini .seealso: PCBDDC 94253cdbc3dSStefano Zampini @*/ 94382ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries) 94453cdbc3dSStefano Zampini { 94553cdbc3dSStefano Zampini PetscErrorCode ierr; 94653cdbc3dSStefano Zampini 94753cdbc3dSStefano Zampini PetscFunctionBegin; 94853cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 94982ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 9500c7d97c5SJed Brown PetscFunctionReturn(0); 9510c7d97c5SJed Brown } 9521e6b0712SBarry Smith 9531a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 95436e030ebSStefano Zampini { 95536e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 956da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 95756282151SStefano Zampini PetscBool same_data = PETSC_FALSE; 958da1bb401SStefano Zampini PetscErrorCode ierr; 95936e030ebSStefano Zampini 96036e030ebSStefano Zampini PetscFunctionBegin; 9618687889aSStefano Zampini if (!nvtxs) { 96204194a47SStefano Zampini if (copymode == PETSC_OWN_POINTER) { 96304194a47SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 96404194a47SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 96504194a47SStefano Zampini } 9668687889aSStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 9678687889aSStefano Zampini PetscFunctionReturn(0); 9688687889aSStefano Zampini } 96966da6bd7Sstefano_zampini if (mat_graph->nvtxs == nvtxs && mat_graph->freecsr) { /* we own the data */ 97056282151SStefano Zampini if (mat_graph->xadj == xadj && mat_graph->adjncy == adjncy) same_data = PETSC_TRUE; 97156282151SStefano Zampini if (!same_data && mat_graph->xadj[nvtxs] == xadj[nvtxs]) { 9722d505d7fSStefano Zampini ierr = PetscMemcmp(xadj,mat_graph->xadj,(nvtxs+1)*sizeof(PetscInt),&same_data);CHKERRQ(ierr); 9732d505d7fSStefano Zampini if (same_data) { 9742d505d7fSStefano Zampini ierr = PetscMemcmp(adjncy,mat_graph->adjncy,xadj[nvtxs]*sizeof(PetscInt),&same_data);CHKERRQ(ierr); 9752d505d7fSStefano Zampini } 97656282151SStefano Zampini } 97756282151SStefano Zampini } 97856282151SStefano Zampini if (!same_data) { 979674ae819SStefano Zampini /* free old CSR */ 980674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 981674ae819SStefano Zampini /* get CSR into graph structure */ 982da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 983854ce69bSBarry Smith ierr = PetscMalloc1(nvtxs+1,&mat_graph->xadj);CHKERRQ(ierr); 984785e854fSJed Brown ierr = PetscMalloc1(xadj[nvtxs],&mat_graph->adjncy);CHKERRQ(ierr); 985674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 986674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 987a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 988da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 9891a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 9901a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 991a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 992a1dbd327SStefano Zampini } else if (copymode == PETSC_USE_POINTER) { 993a1dbd327SStefano Zampini mat_graph->xadj = (PetscInt*)xadj; 994a1dbd327SStefano Zampini mat_graph->adjncy = (PetscInt*)adjncy; 995a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_FALSE; 996e0fe2d75SToby Isaac } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %D",copymode); 997575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 99856282151SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 99956282151SStefano Zampini } 100036e030ebSStefano Zampini PetscFunctionReturn(0); 100136e030ebSStefano Zampini } 10021e6b0712SBarry Smith 100336e030ebSStefano Zampini /*@ 100454fffbccSStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local degrees of freedom. 100536e030ebSStefano Zampini 100636e030ebSStefano Zampini Not collective 100736e030ebSStefano Zampini 100836e030ebSStefano Zampini Input Parameters: 100954fffbccSStefano Zampini + pc - the preconditioning context. 101054fffbccSStefano Zampini . nvtxs - number of local vertices of the graph (i.e., the number of local dofs). 101154fffbccSStefano Zampini . xadj, adjncy - the connectivity of the dofs in CSR format. 101254fffbccSStefano Zampini - copymode - supported modes are PETSC_COPY_VALUES, PETSC_USE_POINTER or PETSC_OWN_POINTER. 101336e030ebSStefano Zampini 101436e030ebSStefano Zampini Level: intermediate 101536e030ebSStefano Zampini 101695452b02SPatrick Sanan Notes: 101795452b02SPatrick Sanan A dof is considered connected with all local dofs if xadj[dof+1]-xadj[dof] == 1 and adjncy[xadj[dof]] is negative. 101836e030ebSStefano Zampini 101928509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode 102036e030ebSStefano Zampini @*/ 10211a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 102236e030ebSStefano Zampini { 1023575ad6abSStefano Zampini void (*f)(void) = 0; 102436e030ebSStefano Zampini PetscErrorCode ierr; 102536e030ebSStefano Zampini 102636e030ebSStefano Zampini PetscFunctionBegin; 102736e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 10288687889aSStefano Zampini if (nvtxs) { 1029674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 10301633d1f0SStefano Zampini if (xadj[nvtxs]) PetscValidIntPointer(adjncy,4); 10318687889aSStefano Zampini } 10321a83f524SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 1033575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 1034575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 1035575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 1036575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 1037575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 1038da1bb401SStefano Zampini } 103936e030ebSStefano Zampini PetscFunctionReturn(0); 104036e030ebSStefano Zampini } 10411e6b0712SBarry Smith 104263602bcaSStefano Zampini static PetscErrorCode PCBDDCSetDofsSplittingLocal_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 104363602bcaSStefano Zampini { 104463602bcaSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 104563602bcaSStefano Zampini PetscInt i; 104656282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 104763602bcaSStefano Zampini PetscErrorCode ierr; 104863602bcaSStefano Zampini 104963602bcaSStefano Zampini PetscFunctionBegin; 105056282151SStefano Zampini if (pcbddc->n_ISForDofsLocal == n_is) { 105156282151SStefano Zampini for (i=0;i<n_is;i++) { 105256282151SStefano Zampini PetscBool isequalt; 105356282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofsLocal[i],&isequalt);CHKERRQ(ierr); 105456282151SStefano Zampini if (!isequalt) break; 105556282151SStefano Zampini } 105656282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 105756282151SStefano Zampini } 105856282151SStefano Zampini for (i=0;i<n_is;i++) { 105956282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 106056282151SStefano Zampini } 106163602bcaSStefano Zampini /* Destroy ISes if they were already set */ 106263602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 106363602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 106463602bcaSStefano Zampini } 106563602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 106663602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 106763602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 106863602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 106963602bcaSStefano Zampini } 107063602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 107163602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 107263602bcaSStefano Zampini /* allocate space then set */ 1073d02579f5SStefano Zampini if (n_is) { 1074d02579f5SStefano Zampini ierr = PetscMalloc1(n_is,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1075d02579f5SStefano Zampini } 107663602bcaSStefano Zampini for (i=0;i<n_is;i++) { 107763602bcaSStefano Zampini pcbddc->ISForDofsLocal[i] = ISForDofs[i]; 107863602bcaSStefano Zampini } 107963602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = n_is; 108063602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 108156282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 108263602bcaSStefano Zampini PetscFunctionReturn(0); 108363602bcaSStefano Zampini } 108463602bcaSStefano Zampini 108563602bcaSStefano Zampini /*@ 108663602bcaSStefano Zampini PCBDDCSetDofsSplittingLocal - Set index sets defining fields of the local subdomain matrix 108763602bcaSStefano Zampini 108863602bcaSStefano Zampini Collective 108963602bcaSStefano Zampini 109063602bcaSStefano Zampini Input Parameters: 109163602bcaSStefano Zampini + pc - the preconditioning context 10920f202f7eSStefano Zampini . n_is - number of index sets defining the fields 10930f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in local ordering 109463602bcaSStefano Zampini 109563602bcaSStefano Zampini Level: intermediate 109663602bcaSStefano Zampini 10970f202f7eSStefano Zampini Notes: 10980f202f7eSStefano Zampini n_is should be the same among processes. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 109963602bcaSStefano Zampini 110063602bcaSStefano Zampini .seealso: PCBDDC 110163602bcaSStefano Zampini @*/ 110263602bcaSStefano Zampini PetscErrorCode PCBDDCSetDofsSplittingLocal(PC pc,PetscInt n_is, IS ISForDofs[]) 110363602bcaSStefano Zampini { 110463602bcaSStefano Zampini PetscInt i; 110563602bcaSStefano Zampini PetscErrorCode ierr; 110663602bcaSStefano Zampini 110763602bcaSStefano Zampini PetscFunctionBegin; 110863602bcaSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 110963602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 111063602bcaSStefano Zampini for (i=0;i<n_is;i++) { 111163602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 111263602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 111363602bcaSStefano Zampini } 1114e71e7a71SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplittingLocal_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 111563602bcaSStefano Zampini PetscFunctionReturn(0); 111663602bcaSStefano Zampini } 111763602bcaSStefano Zampini 11189c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 11199c0446d6SStefano Zampini { 11209c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 11219c0446d6SStefano Zampini PetscInt i; 112256282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 11239c0446d6SStefano Zampini PetscErrorCode ierr; 11249c0446d6SStefano Zampini 11259c0446d6SStefano Zampini PetscFunctionBegin; 112656282151SStefano Zampini if (pcbddc->n_ISForDofs == n_is) { 112756282151SStefano Zampini for (i=0;i<n_is;i++) { 112856282151SStefano Zampini PetscBool isequalt; 112956282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofs[i],&isequalt);CHKERRQ(ierr); 113056282151SStefano Zampini if (!isequalt) break; 113156282151SStefano Zampini } 113256282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 113356282151SStefano Zampini } 113456282151SStefano Zampini for (i=0;i<n_is;i++) { 113556282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 113656282151SStefano Zampini } 1137da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 11389c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 11399c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 11409c0446d6SStefano Zampini } 1141d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 114263602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 114363602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 114463602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 114563602bcaSStefano Zampini } 114663602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 114763602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 1148da1bb401SStefano Zampini /* allocate space then set */ 1149d02579f5SStefano Zampini if (n_is) { 1150785e854fSJed Brown ierr = PetscMalloc1(n_is,&pcbddc->ISForDofs);CHKERRQ(ierr); 1151d02579f5SStefano Zampini } 11529c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 1153da1bb401SStefano Zampini pcbddc->ISForDofs[i] = ISForDofs[i]; 11549c0446d6SStefano Zampini } 11559c0446d6SStefano Zampini pcbddc->n_ISForDofs = n_is; 115663602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 115756282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 11589c0446d6SStefano Zampini PetscFunctionReturn(0); 11599c0446d6SStefano Zampini } 11601e6b0712SBarry Smith 11619c0446d6SStefano Zampini /*@ 116263602bcaSStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of the global matrix 11639c0446d6SStefano Zampini 116463602bcaSStefano Zampini Collective 11659c0446d6SStefano Zampini 11669c0446d6SStefano Zampini Input Parameters: 11679c0446d6SStefano Zampini + pc - the preconditioning context 11680f202f7eSStefano Zampini . n_is - number of index sets defining the fields 11690f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in global ordering 11709c0446d6SStefano Zampini 11719c0446d6SStefano Zampini Level: intermediate 11729c0446d6SStefano Zampini 11730f202f7eSStefano Zampini Notes: 11740f202f7eSStefano Zampini Any process can list any global node. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 11759c0446d6SStefano Zampini 11769c0446d6SStefano Zampini .seealso: PCBDDC 11779c0446d6SStefano Zampini @*/ 11789c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 11799c0446d6SStefano Zampini { 11802b510759SStefano Zampini PetscInt i; 11819c0446d6SStefano Zampini PetscErrorCode ierr; 11829c0446d6SStefano Zampini 11839c0446d6SStefano Zampini PetscFunctionBegin; 11849c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 118563602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 11862b510759SStefano Zampini for (i=0;i<n_is;i++) { 118763602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 1188a011d5a7Sstefano_zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 11892b510759SStefano Zampini } 11909c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 11919c0446d6SStefano Zampini PetscFunctionReturn(0); 11929c0446d6SStefano Zampini } 1193906d46d4SStefano Zampini 1194534831adSStefano Zampini /* 1195534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 1196534831adSStefano Zampini guess if a transformation of basis approach has been selected. 11979c0446d6SStefano Zampini 1198534831adSStefano Zampini Input Parameter: 1199534831adSStefano Zampini + pc - the preconditioner contex 1200534831adSStefano Zampini 1201534831adSStefano Zampini Application Interface Routine: PCPreSolve() 1202534831adSStefano Zampini 1203534831adSStefano Zampini Notes: 1204534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 1205534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1206534831adSStefano Zampini */ 1207534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1208534831adSStefano Zampini { 1209534831adSStefano Zampini PetscErrorCode ierr; 1210534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1211534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 12123972b0daSStefano Zampini Vec used_vec; 121327b6a85dSStefano Zampini PetscBool save_rhs = PETSC_TRUE, benign_correction_computed; 1214534831adSStefano Zampini 1215534831adSStefano Zampini PetscFunctionBegin; 12161f4df5f7SStefano Zampini /* if we are working with CG, one dirichlet solve can be avoided during Krylov iterations */ 121785c4d303SStefano Zampini if (ksp) { 12181f4df5f7SStefano Zampini PetscBool iscg, isgroppcg, ispipecg, ispipecgrr; 121985c4d303SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr); 122027b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPGROPPCG,&isgroppcg);CHKERRQ(ierr); 122127b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECG,&ispipecg);CHKERRQ(ierr); 1222f94e96cbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECGRR,&ispipecgrr);CHKERRQ(ierr); 12231f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static || (!iscg && !isgroppcg && !ispipecg && !ispipecgrr)) { 122485c4d303SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 122585c4d303SStefano Zampini } 122685c4d303SStefano Zampini } 1227fc17d649SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static) { 1228fc17d649SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 1229fc17d649SStefano Zampini } 12301f4df5f7SStefano Zampini 123185c4d303SStefano Zampini /* Creates parallel work vectors used in presolve */ 123262a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 123362a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 123462a6ff1dSStefano Zampini } 123562a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 123662a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 123762a6ff1dSStefano Zampini } 12388d00608fSStefano Zampini 123927b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_FALSE; 12403972b0daSStefano Zampini if (x) { 12413972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 12423972b0daSStefano Zampini used_vec = x; 12438d00608fSStefano Zampini } else { /* it can only happen when calling PCBDDCMatFETIDPGetRHS */ 12443972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 12453972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 12463972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 124727b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 1248266e20e9SStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 1249266e20e9SStefano Zampini save_rhs = PETSC_FALSE; 1250266e20e9SStefano Zampini pcbddc->eliminate_dirdofs = PETSC_TRUE; 12513972b0daSStefano Zampini } 12528efcfb23SStefano Zampini 12538efcfb23SStefano Zampini /* hack into ksp data structure since PCPreSolve comes earlier than setting to zero the guess in src/ksp/ksp/interface/itfunc.c */ 12543972b0daSStefano Zampini if (ksp) { 1255a0cb1b98SStefano Zampini /* store the flag for the initial guess since it will be restored back during PCPostSolve_BDDC */ 12568efcfb23SStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 12578efcfb23SStefano Zampini if (!pcbddc->ksp_guess_nonzero) { 12583972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 12593972b0daSStefano Zampini } 12603972b0daSStefano Zampini } 12613308cffdSStefano Zampini 12628d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 12633972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 126470c64980SStefano Zampini if (rhs && pcbddc->eliminate_dirdofs) { 12653975b054SStefano Zampini IS dirIS = NULL; 12663975b054SStefano Zampini 1267a07ea27aSStefano Zampini /* DirichletBoundariesLocal may not be consistent among neighbours; gets a dirichlet dofs IS from graph (may be cached) */ 12683975b054SStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 12693975b054SStefano Zampini if (dirIS) { 1270906d46d4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1271785d1243SStefano Zampini PetscInt dirsize,i,*is_indices; 12722b095fd8SStefano Zampini PetscScalar *array_x; 12732b095fd8SStefano Zampini const PetscScalar *array_diagonal; 1274785d1243SStefano Zampini 12753972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 12763972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 1277e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1278e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1279e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1280e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 128182ba6b80SStefano Zampini ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr); 12823972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 12832b095fd8SStefano Zampini ierr = VecGetArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 12843972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 12852fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 12863972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 12872b095fd8SStefano Zampini ierr = VecRestoreArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 12883972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 1289e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1290e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 12918d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 12921b968477SStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 12938efcfb23SStefano Zampini } 1294a07ea27aSStefano Zampini } 1295b76ba322SStefano Zampini 12968efcfb23SStefano Zampini /* remove the computed solution or the initial guess from the rhs */ 12978d00608fSStefano Zampini if (pcbddc->rhs_change || (ksp && pcbddc->ksp_guess_nonzero) ) { 129827b6a85dSStefano Zampini /* save the original rhs */ 129927b6a85dSStefano Zampini if (save_rhs) { 130027b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 130127b6a85dSStefano Zampini save_rhs = PETSC_FALSE; 13028d00608fSStefano Zampini } 13038d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 13043972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 130527b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,used_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 13063972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 13078efcfb23SStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 130827b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 13097acc28cbSStefano Zampini if (ksp) { 13107acc28cbSStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_FALSE);CHKERRQ(ierr); 13117acc28cbSStefano Zampini } 13123308cffdSStefano Zampini } 13138efcfb23SStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 1314b76ba322SStefano Zampini 1315fc17d649SStefano Zampini /* compute initial vector in benign space if needed 131627b6a85dSStefano Zampini and remove non-benign solution from the rhs */ 131727b6a85dSStefano Zampini benign_correction_computed = PETSC_FALSE; 1318c69e9cc1SStefano Zampini if (rhs && pcbddc->benign_compute_correction && (pcbddc->benign_have_null || pcbddc->benign_apply_coarse_only)) { 13191f4df5f7SStefano Zampini /* compute u^*_h using ideas similar to those in Xuemin Tu's PhD thesis (see Section 4.8.1) 13201f4df5f7SStefano Zampini Recursively apply BDDC in the multilevel case */ 13210369aaf7SStefano Zampini if (!pcbddc->benign_vec) { 13220369aaf7SStefano Zampini ierr = VecDuplicate(rhs,&pcbddc->benign_vec);CHKERRQ(ierr); 13230369aaf7SStefano Zampini } 1324c69e9cc1SStefano Zampini /* keep applying coarse solver unless we no longer have benign subdomains */ 1325c69e9cc1SStefano Zampini pcbddc->benign_apply_coarse_only = pcbddc->benign_have_null ? PETSC_TRUE : PETSC_FALSE; 132627b6a85dSStefano Zampini if (!pcbddc->benign_skip_correction) { 13271dd7afcfSStefano Zampini ierr = PCApply_BDDC(pc,rhs,pcbddc->benign_vec);CHKERRQ(ierr); 13283bca92a6SStefano Zampini benign_correction_computed = PETSC_TRUE; 13291f4df5f7SStefano Zampini if (pcbddc->temp_solution_used) { 13301f4df5f7SStefano Zampini ierr = VecAXPY(pcbddc->temp_solution,1.0,pcbddc->benign_vec);CHKERRQ(ierr); 13311f4df5f7SStefano Zampini } 13321f4df5f7SStefano Zampini ierr = VecScale(pcbddc->benign_vec,-1.0);CHKERRQ(ierr); 133327b6a85dSStefano Zampini /* store the original rhs if not done earlier */ 133427b6a85dSStefano Zampini if (save_rhs) { 133527b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 133692e3dcfbSStefano Zampini } 133727b6a85dSStefano Zampini if (pcbddc->rhs_change) { 13380369aaf7SStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,rhs,rhs);CHKERRQ(ierr); 133927b6a85dSStefano Zampini } else { 134027b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 134127b6a85dSStefano Zampini } 13420369aaf7SStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 134327b6a85dSStefano Zampini } 134427b6a85dSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_FALSE; 13450369aaf7SStefano Zampini } 13462d4c4fecSStefano Zampini 13472d4c4fecSStefano Zampini /* dbg output */ 1348a198735bSStefano Zampini if (pcbddc->dbg_flag && benign_correction_computed) { 13491f4df5f7SStefano Zampini Vec v; 1350c69e9cc1SStefano Zampini 13511f4df5f7SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&v);CHKERRQ(ierr); 1352c69e9cc1SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 13531f4df5f7SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,v);CHKERRQ(ierr); 1354c69e9cc1SStefano Zampini } else { 1355c69e9cc1SStefano Zampini ierr = VecCopy(rhs,v);CHKERRQ(ierr); 1356c69e9cc1SStefano Zampini } 13571f4df5f7SStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,v,PETSC_TRUE);CHKERRQ(ierr); 1358e0fe2d75SToby Isaac ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"LEVEL %D: is the correction benign?\n",pcbddc->current_level);CHKERRQ(ierr); 1359c69e9cc1SStefano Zampini ierr = PetscScalarView(pcbddc->benign_n,pcbddc->benign_p0,pcbddc->dbg_viewer);CHKERRQ(ierr); 1360c69e9cc1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 13611f4df5f7SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 13621f4df5f7SStefano Zampini } 13630369aaf7SStefano Zampini 13640369aaf7SStefano Zampini /* set initial guess if using PCG */ 13658ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 13660369aaf7SStefano Zampini if (x && pcbddc->use_exact_dirichlet_trick) { 13670369aaf7SStefano Zampini ierr = VecSet(x,0.0);CHKERRQ(ierr); 13681dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 136927b6a85dSStefano Zampini if (benign_correction_computed) { /* we have already saved the changed rhs */ 13701dd7afcfSStefano Zampini ierr = VecLockPop(pcis->vec1_global);CHKERRQ(ierr); 13711dd7afcfSStefano Zampini } else { 13721dd7afcfSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,pcis->vec1_global);CHKERRQ(ierr); 13731dd7afcfSStefano Zampini } 13741dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13751dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13761dd7afcfSStefano Zampini } else { 13770369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13780369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13791dd7afcfSStefano Zampini } 13800369aaf7SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 13811dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 13821dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.);CHKERRQ(ierr); 13831dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13841dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13851dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x);CHKERRQ(ierr); 13861dd7afcfSStefano Zampini } else { 13870369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13880369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13891dd7afcfSStefano Zampini } 13900369aaf7SStefano Zampini if (ksp) { 13910369aaf7SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 13920369aaf7SStefano Zampini } 13938ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_TRUE; 1394266e20e9SStefano Zampini } else if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior && benign_correction_computed && pcbddc->use_exact_dirichlet_trick) { 1395266e20e9SStefano Zampini ierr = VecLockPop(pcis->vec1_global);CHKERRQ(ierr); 13960369aaf7SStefano Zampini } 1397534831adSStefano Zampini PetscFunctionReturn(0); 1398534831adSStefano Zampini } 1399906d46d4SStefano Zampini 1400534831adSStefano Zampini /* 1401534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 1402534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 1403534831adSStefano Zampini 1404534831adSStefano Zampini Input Parameter: 1405534831adSStefano Zampini + pc - the preconditioner contex 1406534831adSStefano Zampini 1407534831adSStefano Zampini Application Interface Routine: PCPostSolve() 1408534831adSStefano Zampini 1409534831adSStefano Zampini Notes: 1410534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 1411534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1412534831adSStefano Zampini */ 1413534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1414534831adSStefano Zampini { 1415534831adSStefano Zampini PetscErrorCode ierr; 1416534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1417534831adSStefano Zampini 1418534831adSStefano Zampini PetscFunctionBegin; 14193972b0daSStefano Zampini /* add solution removed in presolve */ 14206bcfc461SStefano Zampini if (x && pcbddc->rhs_change) { 142127b6a85dSStefano Zampini if (pcbddc->temp_solution_used) { 14223425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 1423af140850Sstefano_zampini } else if (pcbddc->benign_compute_correction && pcbddc->benign_vec) { 142427b6a85dSStefano Zampini ierr = VecAXPY(x,-1.0,pcbddc->benign_vec);CHKERRQ(ierr); 14253425bc38SStefano Zampini } 1426af140850Sstefano_zampini /* restore to original state (not for FETI-DP) */ 1427af140850Sstefano_zampini if (ksp) pcbddc->temp_solution_used = PETSC_FALSE; 142827b6a85dSStefano Zampini } 142927b6a85dSStefano Zampini 1430266e20e9SStefano Zampini /* restore rhs to its original state (not needed for FETI-DP) */ 14318d00608fSStefano Zampini if (rhs && pcbddc->rhs_change) { 143227b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 14338d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 1434af140850Sstefano_zampini } 14358efcfb23SStefano Zampini /* restore ksp guess state */ 14368efcfb23SStefano Zampini if (ksp) { 14378efcfb23SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 14388ae0ca82SStefano Zampini /* reset flag for exact dirichlet trick */ 14398ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 1440af140850Sstefano_zampini } 1441534831adSStefano Zampini PetscFunctionReturn(0); 1442534831adSStefano Zampini } 1443af140850Sstefano_zampini 14440c7d97c5SJed Brown /* 14450c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 14460c7d97c5SJed Brown by setting data structures and options. 14470c7d97c5SJed Brown 14480c7d97c5SJed Brown Input Parameter: 144953cdbc3dSStefano Zampini + pc - the preconditioner context 14500c7d97c5SJed Brown 14510c7d97c5SJed Brown Application Interface Routine: PCSetUp() 14520c7d97c5SJed Brown 14530c7d97c5SJed Brown Notes: 14540c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 14550c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 14560c7d97c5SJed Brown */ 145753cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 14580c7d97c5SJed Brown { 14590c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1460c703fcc7SStefano Zampini PCBDDCSubSchurs sub_schurs; 14615e8657edSStefano Zampini Mat_IS* matis; 146208122e43SStefano Zampini MatNullSpace nearnullspace; 146335509ce9Sstefano_zampini Mat lA; 146435509ce9Sstefano_zampini IS lP,zerodiag = NULL; 146591e8d312SStefano Zampini PetscInt nrows,ncols; 146686bfa4cfSStefano Zampini PetscMPIInt size; 1467c703fcc7SStefano Zampini PetscBool computesubschurs; 14688de1fae6SStefano Zampini PetscBool computeconstraintsmatrix; 14695e8657edSStefano Zampini PetscBool new_nearnullspace_provided,ismatis; 1470c703fcc7SStefano Zampini PetscErrorCode ierr; 14710c7d97c5SJed Brown 14720c7d97c5SJed Brown PetscFunctionBegin; 14735e8657edSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATIS,&ismatis);CHKERRQ(ierr); 14746c4ed002SBarry Smith if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner requires matrix of type MATIS"); 147591e8d312SStefano Zampini ierr = MatGetSize(pc->pmat,&nrows,&ncols);CHKERRQ(ierr); 14766c4ed002SBarry Smith if (nrows != ncols) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PCBDDC preconditioner requires a square preconditioning matrix"); 147786bfa4cfSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 147886bfa4cfSStefano Zampini 14795e8657edSStefano Zampini matis = (Mat_IS*)pc->pmat->data; 1480f4ddd8eeSStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other future nonoverlapping preconditioners */ 14813b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 148271582508SStefano Zampini Also, BDDC builds its own KSP for the Dirichlet problem */ 1483a485753aSstefano_zampini if (!pc->setupcalled || pc->flag == DIFFERENT_NONZERO_PATTERN) pcbddc->recompute_topography = PETSC_TRUE; 1484c83e1ba7SStefano Zampini if (pcbddc->recompute_topography) { 1485c83e1ba7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 1486c83e1ba7SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1487c83e1ba7SStefano Zampini } else { 14888de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_FALSE; 1489c83e1ba7SStefano Zampini } 1490b087196eSStefano Zampini 1491b087196eSStefano Zampini /* check parameters' compatibility */ 1492b7ab4a40SStefano Zampini if (!pcbddc->use_deluxe_scaling) pcbddc->deluxe_zerorows = PETSC_FALSE; 1493bd2a564bSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_threshold[0] != 0.0 || pcbddc->adaptive_threshold[1] != 0.0); 149486bfa4cfSStefano Zampini pcbddc->use_deluxe_scaling = (PetscBool)(pcbddc->use_deluxe_scaling && size > 1); 149586bfa4cfSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_selection && size > 1); 1496bf3a8328SStefano Zampini pcbddc->adaptive_userdefined = (PetscBool)(pcbddc->adaptive_selection && pcbddc->adaptive_userdefined); 1497862806e4SStefano Zampini if (pcbddc->adaptive_selection) pcbddc->use_faces = PETSC_TRUE; 1498862806e4SStefano Zampini 14995a95e1ceSStefano Zampini computesubschurs = (PetscBool)(pcbddc->adaptive_selection || pcbddc->use_deluxe_scaling); 150016909a7fSStefano Zampini if (pcbddc->switch_static) { 150116909a7fSStefano Zampini PetscBool ismatis; 1502d9869140SStefano Zampini 150316909a7fSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->mat,MATIS,&ismatis);CHKERRQ(ierr); 150416909a7fSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"When the static switch is one, the iteration matrix should be of type MATIS"); 150516909a7fSStefano Zampini } 150616909a7fSStefano Zampini 150771582508SStefano Zampini /* activate all connected components if the netflux has been requested */ 1508bb05f991SStefano Zampini if (pcbddc->compute_nonetflux) { 1509bb05f991SStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 1510bb05f991SStefano Zampini pcbddc->use_edges = PETSC_TRUE; 1511bb05f991SStefano Zampini pcbddc->use_faces = PETSC_TRUE; 1512bb05f991SStefano Zampini } 1513bb05f991SStefano Zampini 1514f4ddd8eeSStefano Zampini /* Get stdout for dbg */ 151570cf5478SStefano Zampini if (pcbddc->dbg_flag) { 151670cf5478SStefano Zampini if (!pcbddc->dbg_viewer) { 151758a03d70SStefano Zampini pcbddc->dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pc)); 1518f4ddd8eeSStefano Zampini } 1519d9869140SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 152058a03d70SStefano Zampini ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1521f4ddd8eeSStefano Zampini } 1522f4ddd8eeSStefano Zampini 1523c703fcc7SStefano Zampini /* process topology information */ 152471582508SStefano Zampini if (pcbddc->recompute_topography) { 152571582508SStefano Zampini ierr = PCBDDCComputeLocalTopologyInfo(pc);CHKERRQ(ierr); 1526c703fcc7SStefano Zampini if (pcbddc->discretegradient) { 1527a13144ffSStefano Zampini ierr = PCBDDCNedelecSupport(pc);CHKERRQ(ierr); 1528a13144ffSStefano Zampini } 1529c703fcc7SStefano Zampini } 1530a13144ffSStefano Zampini 1531c703fcc7SStefano Zampini /* change basis if requested by the user */ 15325e8657edSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 15335e8657edSStefano Zampini /* use_change_of_basis flag is used to automatically compute a change of basis from constraints */ 15345e8657edSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 15355e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 15365e8657edSStefano Zampini } else { 1537b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 15385e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 15395e8657edSStefano Zampini pcbddc->local_mat = matis->A; 1540d16cbb6bSStefano Zampini } 1541d16cbb6bSStefano Zampini 15424f1b2e48SStefano Zampini /* 1543c703fcc7SStefano Zampini Compute change of basis on local pressures (aka zerodiag dofs) with the benign trick 15444f1b2e48SStefano Zampini This should come earlier then PCISSetUp for extracting the correct subdomain matrices 15454f1b2e48SStefano Zampini */ 15461dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 1547d16cbb6bSStefano Zampini if (pcbddc->benign_saddle_point) { 15489f47a83aSStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 15499f47a83aSStefano Zampini 155005b28244SStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->use_change_of_basis || !computesubschurs) pcbddc->benign_change_explicit = PETSC_TRUE; 1551669cc0f4SStefano Zampini /* detect local saddle point and change the basis in pcbddc->local_mat (TODO: reuse case) */ 1552339f8db1SStefano Zampini ierr = PCBDDCBenignDetectSaddlePoint(pc,&zerodiag);CHKERRQ(ierr); 1553a3df083aSStefano Zampini /* pop B0 mat from local mat */ 1554c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 15551dd7afcfSStefano Zampini /* give pcis a hint to not reuse submatrices during PCISCreate */ 15561dd7afcfSStefano Zampini if (pc->flag == SAME_NONZERO_PATTERN && pcis->reusesubmatrices == PETSC_TRUE) { 15571dd7afcfSStefano Zampini if (pcbddc->benign_n && (pcbddc->benign_change_explicit || pcbddc->dbg_flag)) { 15581dd7afcfSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 15591dd7afcfSStefano Zampini } else { 1560a3df083aSStefano Zampini pcis->reusesubmatrices = PETSC_TRUE; 15611dd7afcfSStefano Zampini } 1562a3df083aSStefano Zampini } else { 15639f47a83aSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 1564674ae819SStefano Zampini } 1565a3df083aSStefano Zampini } 156627b6a85dSStefano Zampini 15678037d520SStefano Zampini /* propagate relevant information */ 156806a4e24aSStefano Zampini if (matis->A->symmetric_set) { 156906a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 157006a4e24aSStefano Zampini } 157106a4e24aSStefano Zampini if (matis->A->spd_set) { 157206a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SPD,matis->A->spd);CHKERRQ(ierr); 157306a4e24aSStefano Zampini } 1574e496cd5dSStefano Zampini 15755e8657edSStefano Zampini /* Set up all the "iterative substructuring" common block without computing solvers */ 15765e8657edSStefano Zampini { 15775e8657edSStefano Zampini Mat temp_mat; 15785e8657edSStefano Zampini 15795e8657edSStefano Zampini temp_mat = matis->A; 15805e8657edSStefano Zampini matis->A = pcbddc->local_mat; 1581d9869140SStefano Zampini ierr = PCISSetUp(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 15825e8657edSStefano Zampini pcbddc->local_mat = matis->A; 15835e8657edSStefano Zampini matis->A = temp_mat; 15845e8657edSStefano Zampini } 1585684f6988SStefano Zampini 158681d14e9dSStefano Zampini /* Analyze interface */ 158764ac59b8SStefano Zampini if (!pcbddc->graphanalyzed) { 1588674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 15898de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1590345ecf6cSStefano Zampini if (pcbddc->adaptive_selection && !pcbddc->use_deluxe_scaling && !pcbddc->mat_graph->twodim) { 15914247aa23Sstefano_zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot compute the adaptive primal space for a problem with 3D edges without deluxe scaling"); 1592345ecf6cSStefano Zampini } 1593a198735bSStefano Zampini if (pcbddc->compute_nonetflux) { 1594669cc0f4SStefano Zampini MatNullSpace nnfnnsp; 1595669cc0f4SStefano Zampini 159621ef3d20SStefano Zampini if (!pcbddc->divudotp) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Missing divudotp operator"); 15978ae0ca82SStefano Zampini ierr = PCBDDCComputeNoNetFlux(pc->pmat,pcbddc->divudotp,pcbddc->divudotp_trans,pcbddc->divudotp_vl2l,pcbddc->mat_graph,&nnfnnsp);CHKERRQ(ierr); 159871582508SStefano Zampini /* TODO what if a nearnullspace is already attached? */ 15998037d520SStefano Zampini if (nnfnnsp) { 1600669cc0f4SStefano Zampini ierr = MatSetNearNullSpace(pc->pmat,nnfnnsp);CHKERRQ(ierr); 1601669cc0f4SStefano Zampini ierr = MatNullSpaceDestroy(&nnfnnsp);CHKERRQ(ierr); 1602669cc0f4SStefano Zampini } 1603674ae819SStefano Zampini } 16048037d520SStefano Zampini } 1605fb8d54d4SStefano Zampini 16065408967cSStefano Zampini /* check existence of a divergence free extension, i.e. 16075408967cSStefano Zampini b(v_I,p_0) = 0 for all v_I (raise error if not). 16085408967cSStefano Zampini Also, check that PCBDDCBenignGetOrSetP0 works */ 1609ff1f7e73Sstefano_zampini if (pcbddc->benign_saddle_point && pcbddc->dbg_flag > 1) { 16105408967cSStefano Zampini ierr = PCBDDCBenignCheck(pc,zerodiag);CHKERRQ(ierr); 161109f581a4SStefano Zampini } 16124f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 161306f24817SStefano Zampini 1614b96c3477SStefano Zampini /* Setup local dirichlet solver ksp_D and sub_schurs solvers */ 1615c703fcc7SStefano Zampini if (computesubschurs && pcbddc->recompute_topography) { 161608122e43SStefano Zampini ierr = PCBDDCInitSubSchurs(pc);CHKERRQ(ierr); 1617b1b3d7a2SStefano Zampini } 16189d54b7f4SStefano Zampini /* SetUp Scaling operator (scaling matrices could be needed in SubSchursSetUp)*/ 16199d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) { 16209d54b7f4SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 16219d54b7f4SStefano Zampini } 1622c703fcc7SStefano Zampini 1623c703fcc7SStefano Zampini /* finish setup solvers and do adaptive selection of constraints */ 1624b334f244SStefano Zampini sub_schurs = pcbddc->sub_schurs; 1625b334f244SStefano Zampini if (sub_schurs && sub_schurs->schur_explicit) { 16262070dbb6SStefano Zampini if (computesubschurs) { 162708122e43SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 16282070dbb6SStefano Zampini } 1629d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 1630d5574798SStefano Zampini } else { 1631d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 16322070dbb6SStefano Zampini if (computesubschurs) { 1633d5574798SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 1634d5574798SStefano Zampini } 16352070dbb6SStefano Zampini } 163608122e43SStefano Zampini if (pcbddc->adaptive_selection) { 163708122e43SStefano Zampini ierr = PCBDDCAdaptiveSelection(pc);CHKERRQ(ierr); 16388de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1639b7eb3628SStefano Zampini } 1640684f6988SStefano Zampini 1641f4ddd8eeSStefano Zampini /* infer if NullSpace object attached to Mat via MatSetNearNullSpace has changed */ 1642fb8d54d4SStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1643f4ddd8eeSStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullspace);CHKERRQ(ierr); 1644f4ddd8eeSStefano Zampini if (pcbddc->onearnullspace) { /* already used nearnullspace */ 1645f4ddd8eeSStefano Zampini if (!nearnullspace) { /* near null space attached to mat has been destroyed */ 1646f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1647f4ddd8eeSStefano Zampini } else { 1648f4ddd8eeSStefano Zampini /* determine if the two nullspaces are different (should be lightweight) */ 1649f4ddd8eeSStefano Zampini if (nearnullspace != pcbddc->onearnullspace) { 1650f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1651165b64e2SStefano Zampini } else { /* maybe the user has changed the content of the nearnullspace so check vectors ObjectStateId */ 1652f4ddd8eeSStefano Zampini PetscInt i; 1653165b64e2SStefano Zampini const Vec *nearnullvecs; 1654165b64e2SStefano Zampini PetscObjectState state; 1655165b64e2SStefano Zampini PetscInt nnsp_size; 1656165b64e2SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullspace,NULL,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1657f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1658f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&state);CHKERRQ(ierr); 1659165b64e2SStefano Zampini if (pcbddc->onearnullvecs_state[i] != state) { 1660f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1661f4ddd8eeSStefano Zampini break; 1662f4ddd8eeSStefano Zampini } 1663f4ddd8eeSStefano Zampini } 1664f4ddd8eeSStefano Zampini } 1665f4ddd8eeSStefano Zampini } 1666f4ddd8eeSStefano Zampini } else { 1667f4ddd8eeSStefano Zampini if (!nearnullspace) { /* both nearnullspaces are null */ 1668f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1669f4ddd8eeSStefano Zampini } else { /* nearnullspace attached later */ 1670f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1671f4ddd8eeSStefano Zampini } 1672f4ddd8eeSStefano Zampini } 1673f4ddd8eeSStefano Zampini 1674f4ddd8eeSStefano Zampini /* Setup constraints and related work vectors */ 1675727cdba6SStefano Zampini /* reset primal space flags */ 1676f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 1677727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 16788de1fae6SStefano Zampini if (computeconstraintsmatrix || new_nearnullspace_provided) { 1679727cdba6SStefano Zampini /* It also sets the primal space flags */ 1680674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 16819543d0ffSStefano Zampini } 1682e7b262bdSStefano Zampini /* Allocate needed local vectors (which depends on quantities defined during ConstraintsSetUp) */ 1683f4ddd8eeSStefano Zampini ierr = PCBDDCSetUpLocalWorkVectors(pc);CHKERRQ(ierr); 16845e8657edSStefano Zampini 16855e8657edSStefano Zampini if (pcbddc->use_change_of_basis) { 16865e8657edSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 16875e8657edSStefano Zampini 16885e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 16894f1b2e48SStefano Zampini if (pcbddc->benign_change) { 16901dd7afcfSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 1691c263805aSStefano Zampini /* pop B0 from pcbddc->local_mat */ 1692c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 1693c263805aSStefano Zampini } 16945e8657edSStefano Zampini /* get submatrices */ 16955e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 16965e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 16975e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 16987dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 16997dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 17007dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 17013975b054SStefano Zampini /* set flag in pcis to not reuse submatrices during PCISCreate */ 17023975b054SStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 17039c6a02ceSStefano Zampini } else if (!pcbddc->user_ChangeOfBasisMatrix && !pcbddc->benign_change) { 1704b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 17055e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 17065e8657edSStefano Zampini pcbddc->local_mat = matis->A; 17075e8657edSStefano Zampini } 170835509ce9Sstefano_zampini 170935509ce9Sstefano_zampini /* interface pressure block row for B_C */ 171035509ce9Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lP" ,(PetscObject*)&lP);CHKERRQ(ierr); 171135509ce9Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject*)&lA);CHKERRQ(ierr); 171235509ce9Sstefano_zampini if (lA && lP) { 171335509ce9Sstefano_zampini PC_IS* pcis = (PC_IS*)pc->data; 171435509ce9Sstefano_zampini Mat B_BI,B_BB,Bt_BI,Bt_BB; 171535509ce9Sstefano_zampini PetscBool issym; 171635509ce9Sstefano_zampini ierr = MatIsSymmetric(lA,PETSC_SMALL,&issym);CHKERRQ(ierr); 17176cc1294bSstefano_zampini if (issym) { 17187dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_I_local,MAT_INITIAL_MATRIX,&B_BI);CHKERRQ(ierr); 17197dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_B_local,MAT_INITIAL_MATRIX,&B_BB);CHKERRQ(ierr); 172035509ce9Sstefano_zampini ierr = MatCreateTranspose(B_BI,&Bt_BI);CHKERRQ(ierr); 172135509ce9Sstefano_zampini ierr = MatCreateTranspose(B_BB,&Bt_BB);CHKERRQ(ierr); 172235509ce9Sstefano_zampini } else { 17237dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_I_local,MAT_INITIAL_MATRIX,&B_BI);CHKERRQ(ierr); 17247dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_B_local,MAT_INITIAL_MATRIX,&B_BB);CHKERRQ(ierr); 17257dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,pcis->is_I_local,lP,MAT_INITIAL_MATRIX,&Bt_BI);CHKERRQ(ierr); 17267dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,pcis->is_B_local,lP,MAT_INITIAL_MATRIX,&Bt_BB);CHKERRQ(ierr); 172735509ce9Sstefano_zampini } 172835509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_B_BI",(PetscObject)B_BI);CHKERRQ(ierr); 172935509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_B_BB",(PetscObject)B_BB);CHKERRQ(ierr); 173035509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_Bt_BI",(PetscObject)Bt_BI);CHKERRQ(ierr); 173135509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_Bt_BB",(PetscObject)Bt_BB);CHKERRQ(ierr); 173235509ce9Sstefano_zampini ierr = MatDestroy(&B_BI);CHKERRQ(ierr); 173335509ce9Sstefano_zampini ierr = MatDestroy(&B_BB);CHKERRQ(ierr); 173435509ce9Sstefano_zampini ierr = MatDestroy(&Bt_BI);CHKERRQ(ierr); 173535509ce9Sstefano_zampini ierr = MatDestroy(&Bt_BB);CHKERRQ(ierr); 173635509ce9Sstefano_zampini } 173735509ce9Sstefano_zampini 1738b96c3477SStefano Zampini /* SetUp coarse and local Neumann solvers */ 173999cc7994SStefano Zampini ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr); 1740b96c3477SStefano Zampini /* SetUp Scaling operator */ 17419d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1742674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 17430c7d97c5SJed Brown } 1744c703fcc7SStefano Zampini 17451dd7afcfSStefano Zampini /* mark topography as done */ 174656282151SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 17470369aaf7SStefano Zampini 17481dd7afcfSStefano Zampini /* wrap pcis->A_IB and pcis->A_BI if we did not change explicitly the variables on the pressures */ 17491dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_FALSE);CHKERRQ(ierr); 17501dd7afcfSStefano Zampini 175158a03d70SStefano Zampini if (pcbddc->dbg_flag) { 175258a03d70SStefano Zampini ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1753d9869140SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 17542b510759SStefano Zampini } 17550c7d97c5SJed Brown PetscFunctionReturn(0); 17560c7d97c5SJed Brown } 17570c7d97c5SJed Brown 17580c7d97c5SJed Brown /* 175950efa1b5SStefano Zampini PCApply_BDDC - Applies the BDDC operator to a vector. 17600c7d97c5SJed Brown 17610c7d97c5SJed Brown Input Parameters: 17620f202f7eSStefano Zampini + pc - the preconditioner context 17630f202f7eSStefano Zampini - r - input vector (global) 17640c7d97c5SJed Brown 17650c7d97c5SJed Brown Output Parameter: 17660c7d97c5SJed Brown . z - output vector (global) 17670c7d97c5SJed Brown 17680c7d97c5SJed Brown Application Interface Routine: PCApply() 17690c7d97c5SJed Brown */ 177053cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 17710c7d97c5SJed Brown { 17720c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 17730c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1774b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 17750c7d97c5SJed Brown PetscErrorCode ierr; 17763b03a366Sstefano_zampini const PetscScalar one = 1.0; 17773b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 17782617d88aSStefano Zampini const PetscScalar zero = 0.0; 17790c7d97c5SJed Brown 17800c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 17810c7d97c5SJed Brown NN interface preconditioner changed to BDDC 1782b097fa66SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static == PETSC_TRUE) */ 17830c7d97c5SJed Brown 17840c7d97c5SJed Brown PetscFunctionBegin; 1785f3d41395Sstefano_zampini ierr = PetscCitationsRegister(citation,&cited);CHKERRQ(ierr); 17861dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 17871dd7afcfSStefano Zampini Vec swap; 178827b6a85dSStefano Zampini 178927b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 17901dd7afcfSStefano Zampini swap = pcbddc->work_change; 17911dd7afcfSStefano Zampini pcbddc->work_change = r; 17921dd7afcfSStefano Zampini r = swap; 17931dd7afcfSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 17949cc2a9b1Sstefano_zampini if (pcbddc->benign_apply_coarse_only && pcbddc->use_exact_dirichlet_trick && pcbddc->change_interior) { 17951dd7afcfSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 17961dd7afcfSStefano Zampini ierr = VecLockPush(pcis->vec1_global);CHKERRQ(ierr); 17971dd7afcfSStefano Zampini } 17981dd7afcfSStefano Zampini } 179927b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 1800015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1801efc2fbd9SStefano Zampini } 18028ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 1803b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 18040c7d97c5SJed Brown /* First Dirichlet solve */ 18050c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18060c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18070c7d97c5SJed Brown /* 18080c7d97c5SJed Brown Assembling right hand side for BDDC operator 1809b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 1810674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 18110c7d97c5SJed Brown */ 1812b097fa66SStefano Zampini if (n_D) { 1813b097fa66SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 18140c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 181516909a7fSStefano Zampini if (pcbddc->switch_static) { 181616909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 181716909a7fSStefano Zampini 181816909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 181916909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 182016909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 182116909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 182216909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 182316909a7fSStefano Zampini } else { 182416909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 182516909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 182616909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 182716909a7fSStefano Zampini } 182816909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 182916909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 183016909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 183116909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 183216909a7fSStefano Zampini } else { 1833b097fa66SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 183416909a7fSStefano Zampini } 1835b097fa66SStefano Zampini } else { 1836b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1837b097fa66SStefano Zampini } 18380c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 18390c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1840674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 1841b76ba322SStefano Zampini } else { 18424fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 1843674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 1844b76ba322SStefano Zampini } 18454fee134fSStefano Zampini } 1846b76ba322SStefano Zampini 18472617d88aSStefano Zampini /* Apply interface preconditioner 18482617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1849dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 18502617d88aSStefano Zampini 1851674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 1852674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 18530c7d97c5SJed Brown 18543b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 18550c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18560c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1857b097fa66SStefano Zampini if (n_B) { 185816909a7fSStefano Zampini if (pcbddc->switch_static) { 185916909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 186016909a7fSStefano Zampini 186116909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 186216909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 186316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 186416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 186516909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 186616909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 186716909a7fSStefano Zampini } else { 186816909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 186916909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 187016909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 187116909a7fSStefano Zampini } 187216909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 187316909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 187416909a7fSStefano Zampini } else { 18750c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 187616909a7fSStefano Zampini } 187716909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 187816909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 187916909a7fSStefano Zampini 188016909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 188116909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 188216909a7fSStefano Zampini } else { 188316909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 188416909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 188516909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 188616909a7fSStefano Zampini } 1887b097fa66SStefano Zampini } 1888df187020SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 1889efc2fbd9SStefano Zampini 18908ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 1891b097fa66SStefano Zampini if (pcbddc->switch_static) { 1892b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 1893b097fa66SStefano Zampini } else { 1894b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 1895b097fa66SStefano Zampini } 18960c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 18970c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1898b097fa66SStefano Zampini } else { 1899b097fa66SStefano Zampini if (pcbddc->switch_static) { 1900b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 1901b097fa66SStefano Zampini } else { 1902b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 1903b097fa66SStefano Zampini } 1904b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1905b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1906b097fa66SStefano Zampini } 190727b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 19081dd7afcfSStefano Zampini if (pcbddc->benign_apply_coarse_only) { 19091dd7afcfSStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 19101dd7afcfSStefano Zampini } 1911015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 1912efc2fbd9SStefano Zampini } 19131f4df5f7SStefano Zampini 19141dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1915f913dca9SStefano Zampini pcbddc->work_change = r; 19161dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 19171dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 19181dd7afcfSStefano Zampini } 19190c7d97c5SJed Brown PetscFunctionReturn(0); 19200c7d97c5SJed Brown } 192150efa1b5SStefano Zampini 192250efa1b5SStefano Zampini /* 192350efa1b5SStefano Zampini PCApplyTranspose_BDDC - Applies the transpose of the BDDC operator to a vector. 192450efa1b5SStefano Zampini 192550efa1b5SStefano Zampini Input Parameters: 19260f202f7eSStefano Zampini + pc - the preconditioner context 19270f202f7eSStefano Zampini - r - input vector (global) 192850efa1b5SStefano Zampini 192950efa1b5SStefano Zampini Output Parameter: 193050efa1b5SStefano Zampini . z - output vector (global) 193150efa1b5SStefano Zampini 193250efa1b5SStefano Zampini Application Interface Routine: PCApplyTranspose() 193350efa1b5SStefano Zampini */ 193450efa1b5SStefano Zampini PetscErrorCode PCApplyTranspose_BDDC(PC pc,Vec r,Vec z) 193550efa1b5SStefano Zampini { 193650efa1b5SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 193750efa1b5SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1938b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 193950efa1b5SStefano Zampini PetscErrorCode ierr; 194050efa1b5SStefano Zampini const PetscScalar one = 1.0; 194150efa1b5SStefano Zampini const PetscScalar m_one = -1.0; 194250efa1b5SStefano Zampini const PetscScalar zero = 0.0; 194350efa1b5SStefano Zampini 194450efa1b5SStefano Zampini PetscFunctionBegin; 1945f3d41395Sstefano_zampini ierr = PetscCitationsRegister(citation,&cited);CHKERRQ(ierr); 19461dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 19471dd7afcfSStefano Zampini Vec swap; 194827b6a85dSStefano Zampini 194927b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 19501dd7afcfSStefano Zampini swap = pcbddc->work_change; 19511dd7afcfSStefano Zampini pcbddc->work_change = r; 19521dd7afcfSStefano Zampini r = swap; 195327b6a85dSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 19548ae0ca82SStefano Zampini if (pcbddc->benign_apply_coarse_only && pcbddc->exact_dirichlet_trick_app && pcbddc->change_interior) { 195527b6a85dSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 195627b6a85dSStefano Zampini ierr = VecLockPush(pcis->vec1_global);CHKERRQ(ierr); 19571dd7afcfSStefano Zampini } 195827b6a85dSStefano Zampini } 195927b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 1960537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1961537c1cdfSStefano Zampini } 19628ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 1963b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 196450efa1b5SStefano Zampini /* First Dirichlet solve */ 196550efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 196650efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 196750efa1b5SStefano Zampini /* 196850efa1b5SStefano Zampini Assembling right hand side for BDDC operator 1969b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 197050efa1b5SStefano Zampini - pcis->vec1_B the interface part of the global vector z 197150efa1b5SStefano Zampini */ 1972b097fa66SStefano Zampini if (n_D) { 1973b097fa66SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 197450efa1b5SStefano Zampini ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 197516909a7fSStefano Zampini if (pcbddc->switch_static) { 197616909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 197716909a7fSStefano Zampini 197816909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 197916909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 198016909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 198116909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 198216909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 198316909a7fSStefano Zampini } else { 198416909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 198516909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 198616909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 198716909a7fSStefano Zampini } 198816909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 198916909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 199016909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 199116909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 199216909a7fSStefano Zampini } else { 1993b097fa66SStefano Zampini ierr = MatMultTranspose(pcis->A_IB,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 199416909a7fSStefano Zampini } 1995b097fa66SStefano Zampini } else { 1996b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1997b097fa66SStefano Zampini } 199850efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 199950efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 200050efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 200150efa1b5SStefano Zampini } else { 200250efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 200350efa1b5SStefano Zampini } 200450efa1b5SStefano Zampini 200550efa1b5SStefano Zampini /* Apply interface preconditioner 200650efa1b5SStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 2007dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_TRUE);CHKERRQ(ierr); 200850efa1b5SStefano Zampini 200950efa1b5SStefano Zampini /* Apply transpose of partition of unity operator */ 201050efa1b5SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 201150efa1b5SStefano Zampini 201250efa1b5SStefano Zampini /* Second Dirichlet solve and assembling of output */ 201350efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 201450efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2015b097fa66SStefano Zampini if (n_B) { 201616909a7fSStefano Zampini if (pcbddc->switch_static) { 201716909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 201816909a7fSStefano Zampini 201916909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 202016909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 202116909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 202216909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 202316909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 202416909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 202516909a7fSStefano Zampini } else { 202616909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 202716909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 202816909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 202916909a7fSStefano Zampini } 203016909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 203116909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 203216909a7fSStefano Zampini } else { 203350efa1b5SStefano Zampini ierr = MatMultTranspose(pcis->A_BI,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 203416909a7fSStefano Zampini } 203516909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 203616909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 203716909a7fSStefano Zampini 203816909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 203916909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 204016909a7fSStefano Zampini } else { 204116909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 204216909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 204316909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 204416909a7fSStefano Zampini } 2045b097fa66SStefano Zampini } 2046b0147a47SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 20478ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2048b097fa66SStefano Zampini if (pcbddc->switch_static) { 2049b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 2050b097fa66SStefano Zampini } else { 2051b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 2052b097fa66SStefano Zampini } 205350efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 205450efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2055b097fa66SStefano Zampini } else { 2056b097fa66SStefano Zampini if (pcbddc->switch_static) { 2057b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 2058b097fa66SStefano Zampini } else { 2059b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 2060b097fa66SStefano Zampini } 2061b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2062b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2063b097fa66SStefano Zampini } 206427b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 2065537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 2066537c1cdfSStefano Zampini } 20671dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2068f913dca9SStefano Zampini pcbddc->work_change = r; 20691dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 20701dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 20711dd7afcfSStefano Zampini } 207250efa1b5SStefano Zampini PetscFunctionReturn(0); 207350efa1b5SStefano Zampini } 2074674ae819SStefano Zampini 20759326c5c6Sstefano_zampini PetscErrorCode PCReset_BDDC(PC pc) 2076da1bb401SStefano Zampini { 2077da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 20789326c5c6Sstefano_zampini PC_IS *pcis = (PC_IS*)pc->data; 20799326c5c6Sstefano_zampini KSP kspD,kspR,kspC; 2080da1bb401SStefano Zampini PetscErrorCode ierr; 2081da1bb401SStefano Zampini 2082da1bb401SStefano Zampini PetscFunctionBegin; 2083674ae819SStefano Zampini /* free BDDC custom data */ 2084674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 2085674ae819SStefano Zampini /* destroy objects related to topography */ 2086674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 208734a97f8cSStefano Zampini /* destroy objects for scaling operator */ 2088674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 2089674ae819SStefano Zampini /* free solvers stuff */ 2090674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 209162a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 209262a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 209362a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 20941dd7afcfSStefano Zampini /* free data created by PCIS */ 20951dd7afcfSStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 20969326c5c6Sstefano_zampini 20979326c5c6Sstefano_zampini /* restore defaults */ 20989326c5c6Sstefano_zampini kspD = pcbddc->ksp_D; 20999326c5c6Sstefano_zampini kspR = pcbddc->ksp_R; 21009326c5c6Sstefano_zampini kspC = pcbddc->coarse_ksp; 21019326c5c6Sstefano_zampini ierr = PetscMemzero(pc->data,sizeof(*pcbddc));CHKERRQ(ierr); 21029326c5c6Sstefano_zampini pcis->n_neigh = -1; 21039326c5c6Sstefano_zampini pcis->scaling_factor = 1.0; 21049326c5c6Sstefano_zampini pcis->reusesubmatrices = PETSC_TRUE; 21059326c5c6Sstefano_zampini pcbddc->use_local_adj = PETSC_TRUE; 21069326c5c6Sstefano_zampini pcbddc->use_vertices = PETSC_TRUE; 21079326c5c6Sstefano_zampini pcbddc->use_edges = PETSC_TRUE; 21089326c5c6Sstefano_zampini pcbddc->symmetric_primal = PETSC_TRUE; 21099326c5c6Sstefano_zampini pcbddc->vertex_size = 1; 21109326c5c6Sstefano_zampini pcbddc->recompute_topography = PETSC_TRUE; 21119326c5c6Sstefano_zampini pcbddc->coarse_size = -1; 21129326c5c6Sstefano_zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 21139326c5c6Sstefano_zampini pcbddc->coarsening_ratio = 8; 21149326c5c6Sstefano_zampini pcbddc->coarse_eqs_per_proc = 1; 21159326c5c6Sstefano_zampini pcbddc->benign_compute_correction = PETSC_TRUE; 21169326c5c6Sstefano_zampini pcbddc->nedfield = -1; 21179326c5c6Sstefano_zampini pcbddc->nedglobal = PETSC_TRUE; 21189326c5c6Sstefano_zampini pcbddc->graphmaxcount = PETSC_MAX_INT; 21199326c5c6Sstefano_zampini pcbddc->sub_schurs_layers = -1; 21209326c5c6Sstefano_zampini pcbddc->ksp_D = kspD; 21219326c5c6Sstefano_zampini pcbddc->ksp_R = kspR; 21229326c5c6Sstefano_zampini pcbddc->coarse_ksp = kspC; 21239326c5c6Sstefano_zampini PetscFunctionReturn(0); 21249326c5c6Sstefano_zampini } 21259326c5c6Sstefano_zampini 21269326c5c6Sstefano_zampini PetscErrorCode PCDestroy_BDDC(PC pc) 21279326c5c6Sstefano_zampini { 21289326c5c6Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 21299326c5c6Sstefano_zampini PetscErrorCode ierr; 21309326c5c6Sstefano_zampini 21319326c5c6Sstefano_zampini PetscFunctionBegin; 21329326c5c6Sstefano_zampini ierr = PCReset_BDDC(pc);CHKERRQ(ierr); 21339326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 21349326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 21359326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 2136a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",NULL);CHKERRQ(ierr); 2137a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",NULL);CHKERRQ(ierr); 2138906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",NULL);CHKERRQ(ierr); 2139674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 214030368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",NULL);CHKERRQ(ierr); 2141bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 21422b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr); 2143b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr); 21442b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr); 2145bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 214682ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2147bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 214882ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2149bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 215082ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2151bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 2152785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2153bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 215463602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",NULL);CHKERRQ(ierr); 2155bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 2156bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 2157bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 2158bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 2159a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",NULL);CHKERRQ(ierr); 2160ab8c8b98SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",NULL);CHKERRQ(ierr); 2161674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 2162da1bb401SStefano Zampini PetscFunctionReturn(0); 2163da1bb401SStefano Zampini } 21641e6b0712SBarry Smith 2165ab8c8b98SStefano Zampini static PetscErrorCode PCSetCoordinates_BDDC(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 2166ab8c8b98SStefano Zampini { 2167ab8c8b98SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2168ab8c8b98SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 2169ab8c8b98SStefano Zampini PetscErrorCode ierr; 2170ab8c8b98SStefano Zampini 2171ab8c8b98SStefano Zampini PetscFunctionBegin; 2172ab8c8b98SStefano Zampini ierr = PetscFree(mat_graph->coords);CHKERRQ(ierr); 2173ab8c8b98SStefano Zampini ierr = PetscMalloc1(nloc*dim,&mat_graph->coords);CHKERRQ(ierr); 2174ab8c8b98SStefano Zampini ierr = PetscMemcpy(mat_graph->coords,coords,nloc*dim*sizeof(PetscReal));CHKERRQ(ierr); 2175ab8c8b98SStefano Zampini mat_graph->cnloc = nloc; 2176ab8c8b98SStefano Zampini mat_graph->cdim = dim; 2177ab8c8b98SStefano Zampini mat_graph->cloc = PETSC_FALSE; 2178ab8c8b98SStefano Zampini PetscFunctionReturn(0); 2179ab8c8b98SStefano Zampini } 2180ab8c8b98SStefano Zampini 2181a06fd7f2SStefano Zampini static PetscErrorCode PCPreSolveChangeRHS_BDDC(PC pc, PetscBool* change) 2182a06fd7f2SStefano Zampini { 2183a06fd7f2SStefano Zampini PetscFunctionBegin; 2184a06fd7f2SStefano Zampini *change = PETSC_TRUE; 2185a06fd7f2SStefano Zampini PetscFunctionReturn(0); 2186a06fd7f2SStefano Zampini } 2187a06fd7f2SStefano Zampini 21883425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 21893425bc38SStefano Zampini { 2190674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 2191266e20e9SStefano Zampini Vec work; 21923425bc38SStefano Zampini PC_IS* pcis; 21933425bc38SStefano Zampini PC_BDDC* pcbddc; 21943425bc38SStefano Zampini PetscErrorCode ierr; 21950c7d97c5SJed Brown 21963425bc38SStefano Zampini PetscFunctionBegin; 21973425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 21983425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 21993425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 22003425bc38SStefano Zampini 2201229984c5Sstefano_zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 2202229984c5Sstefano_zampini /* copy rhs since we may change it during PCPreSolve_BDDC */ 2203229984c5Sstefano_zampini if (!pcbddc->original_rhs) { 2204229984c5Sstefano_zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 2205229984c5Sstefano_zampini } 22066cc1294bSstefano_zampini if (mat_ctx->rhs_flip) { 22076cc1294bSstefano_zampini ierr = VecPointwiseMult(pcbddc->original_rhs,standard_rhs,mat_ctx->rhs_flip);CHKERRQ(ierr); 22086cc1294bSstefano_zampini } else { 2209229984c5Sstefano_zampini ierr = VecCopy(standard_rhs,pcbddc->original_rhs);CHKERRQ(ierr); 22106cc1294bSstefano_zampini } 2211af140850Sstefano_zampini if (mat_ctx->g2g_p) { 2212229984c5Sstefano_zampini /* interface pressure rhs */ 2213022d8d2bSstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,fetidp_flux_rhs,pcbddc->original_rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2214022d8d2bSstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,fetidp_flux_rhs,pcbddc->original_rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2215229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,standard_rhs,fetidp_flux_rhs,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2216229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,standard_rhs,fetidp_flux_rhs,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22176cc1294bSstefano_zampini if (!mat_ctx->rhs_flip) { 2218229984c5Sstefano_zampini ierr = VecScale(fetidp_flux_rhs,-1.);CHKERRQ(ierr); 2219229984c5Sstefano_zampini } 22206cc1294bSstefano_zampini } 2221c08af4c6SStefano Zampini /* 2222c08af4c6SStefano Zampini change of basis for physical rhs if needed 2223c08af4c6SStefano Zampini It also changes the rhs in case of dirichlet boundaries 2224c08af4c6SStefano Zampini */ 22253738a8e6SStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,pcbddc->original_rhs,NULL);CHKERRQ(ierr); 2226fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 22273738a8e6SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcbddc->original_rhs,pcbddc->work_change);CHKERRQ(ierr); 22283738a8e6SStefano Zampini work = pcbddc->work_change; 2229fc17d649SStefano Zampini } else { 22303738a8e6SStefano Zampini work = pcbddc->original_rhs; 2231fc17d649SStefano Zampini } 22323425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 2233266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2234266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2235fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 2236fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 2237266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2238266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2239674ae819SStefano Zampini /* Apply partition of unity */ 22403425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 2241266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 22428eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 22433425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 22443425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 22453425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 22463425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 2247266e20e9SStefano Zampini ierr = VecSet(work,0.0);CHKERRQ(ierr); 2248266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2249266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2250266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 2251266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2252266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22533425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 22543425bc38SStefano Zampini } 22553425bc38SStefano Zampini /* BDDC rhs */ 22563425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 22578eeda7d8SStefano Zampini if (pcbddc->switch_static) { 22583425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 22593425bc38SStefano Zampini } 22603425bc38SStefano Zampini /* apply BDDC */ 2261229984c5Sstefano_zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 2262dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2263266e20e9SStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 2264229984c5Sstefano_zampini 22653425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 22663425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 22673425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22683425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2269229984c5Sstefano_zampini /* Add contribution to interface pressures */ 2270229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2271229984c5Sstefano_zampini ierr = MatMult(mat_ctx->B_BB,pcis->vec1_B,mat_ctx->vP);CHKERRQ(ierr); 2272229984c5Sstefano_zampini if (pcbddc->switch_static) { 2273229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->B_BI,pcis->vec1_D,mat_ctx->vP,mat_ctx->vP);CHKERRQ(ierr); 2274229984c5Sstefano_zampini } 2275229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->l2g_p,mat_ctx->vP,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2276229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->l2g_p,mat_ctx->vP,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2277229984c5Sstefano_zampini } 22783425bc38SStefano Zampini PetscFunctionReturn(0); 22793425bc38SStefano Zampini } 22801e6b0712SBarry Smith 22813425bc38SStefano Zampini /*@ 22820f202f7eSStefano Zampini PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETI-DP linear system using the physical right-hand side 22833425bc38SStefano Zampini 22843425bc38SStefano Zampini Collective 22853425bc38SStefano Zampini 22863425bc38SStefano Zampini Input Parameters: 22870f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix object obtained by a call to PCBDDCCreateFETIDPOperators 22880f202f7eSStefano Zampini - standard_rhs - the right-hand side of the original linear system 22893425bc38SStefano Zampini 22903425bc38SStefano Zampini Output Parameters: 22910f202f7eSStefano Zampini . fetidp_flux_rhs - the right-hand side for the FETI-DP linear system 22923425bc38SStefano Zampini 22933425bc38SStefano Zampini Level: developer 22943425bc38SStefano Zampini 22953425bc38SStefano Zampini Notes: 22963425bc38SStefano Zampini 22970f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetSolution 22983425bc38SStefano Zampini @*/ 22993425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 23003425bc38SStefano Zampini { 2301674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 23023425bc38SStefano Zampini PetscErrorCode ierr; 23033425bc38SStefano Zampini 23043425bc38SStefano Zampini PetscFunctionBegin; 2305266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2306266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_rhs,VEC_CLASSID,2); 2307266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_rhs,VEC_CLASSID,3); 23083425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2309163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 23103425bc38SStefano Zampini PetscFunctionReturn(0); 23113425bc38SStefano Zampini } 23121e6b0712SBarry Smith 23133425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 23143425bc38SStefano Zampini { 2315674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 23163425bc38SStefano Zampini PC_IS* pcis; 23173425bc38SStefano Zampini PC_BDDC* pcbddc; 23183425bc38SStefano Zampini PetscErrorCode ierr; 2319229984c5Sstefano_zampini Vec work; 23203425bc38SStefano Zampini 23213425bc38SStefano Zampini PetscFunctionBegin; 23223425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 23233425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 23243425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 23253425bc38SStefano Zampini 23263425bc38SStefano Zampini /* apply B_delta^T */ 2327af140850Sstefano_zampini ierr = VecSet(pcis->vec1_B,0.);CHKERRQ(ierr); 23283425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23293425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23303425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 2331229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2332229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->l2g_p,fetidp_flux_sol,mat_ctx->vP,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2333229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->l2g_p,fetidp_flux_sol,mat_ctx->vP,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2334229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->Bt_BB,mat_ctx->vP,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 2335229984c5Sstefano_zampini } 2336229984c5Sstefano_zampini 23373425bc38SStefano Zampini /* compute rhs for BDDC application */ 23383425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 23398eeda7d8SStefano Zampini if (pcbddc->switch_static) { 23403425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 2341229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2342229984c5Sstefano_zampini ierr = VecScale(mat_ctx->vP,-1.);CHKERRQ(ierr); 2343229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->Bt_BI,mat_ctx->vP,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); 23443425bc38SStefano Zampini } 2345229984c5Sstefano_zampini } 2346229984c5Sstefano_zampini 23473425bc38SStefano Zampini /* apply BDDC */ 2348229984c5Sstefano_zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 2349dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2350229984c5Sstefano_zampini 2351229984c5Sstefano_zampini /* put values into global vector */ 2352af140850Sstefano_zampini if (pcbddc->ChangeOfBasisMatrix) work = pcbddc->work_change; 2353af140850Sstefano_zampini else work = standard_sol; 2354229984c5Sstefano_zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2355229984c5Sstefano_zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23568eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 23573425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 23583425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 235900f6b531SStefano Zampini ierr = VecAYPX(pcis->vec1_D,-1.0,mat_ctx->temp_solution_D);CHKERRQ(ierr); 236000f6b531SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); 23613425bc38SStefano Zampini } 2362229984c5Sstefano_zampini 2363229984c5Sstefano_zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2364229984c5Sstefano_zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_D,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2365266e20e9SStefano Zampini /* add p0 solution to final solution */ 2366229984c5Sstefano_zampini ierr = PCBDDCBenignGetOrSetP0(mat_ctx->pc,work,PETSC_FALSE);CHKERRQ(ierr); 2367fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2368af140850Sstefano_zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,work,standard_sol);CHKERRQ(ierr); 2369fc17d649SStefano Zampini } 2370af140850Sstefano_zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 2371af140850Sstefano_zampini if (mat_ctx->g2g_p) { 2372229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,fetidp_flux_sol,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2373229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,fetidp_flux_sol,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2374229984c5Sstefano_zampini } 23753425bc38SStefano Zampini PetscFunctionReturn(0); 23763425bc38SStefano Zampini } 23771e6b0712SBarry Smith 23783425bc38SStefano Zampini /*@ 23790f202f7eSStefano Zampini PCBDDCMatFETIDPGetSolution - Compute the physical solution using the solution of the FETI-DP linear system 23803425bc38SStefano Zampini 23813425bc38SStefano Zampini Collective 23823425bc38SStefano Zampini 23833425bc38SStefano Zampini Input Parameters: 23840f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix obtained by a call to PCBDDCCreateFETIDPOperators 23850f202f7eSStefano Zampini - fetidp_flux_sol - the solution of the FETI-DP linear system 23863425bc38SStefano Zampini 23873425bc38SStefano Zampini Output Parameters: 23880f202f7eSStefano Zampini . standard_sol - the solution defined on the physical domain 23893425bc38SStefano Zampini 23903425bc38SStefano Zampini Level: developer 23913425bc38SStefano Zampini 23923425bc38SStefano Zampini Notes: 23933425bc38SStefano Zampini 23940f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetRHS 23953425bc38SStefano Zampini @*/ 23963425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 23973425bc38SStefano Zampini { 2398674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 23993425bc38SStefano Zampini PetscErrorCode ierr; 24003425bc38SStefano Zampini 24013425bc38SStefano Zampini PetscFunctionBegin; 2402266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2403266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_sol,VEC_CLASSID,2); 2404266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_sol,VEC_CLASSID,3); 24053425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2406163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 24073425bc38SStefano Zampini PetscFunctionReturn(0); 24083425bc38SStefano Zampini } 24091e6b0712SBarry Smith 2410547c9a8eSstefano_zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, PetscBool fully_redundant, const char* prefix, Mat *fetidp_mat, PC *fetidp_pc) 24113425bc38SStefano Zampini { 2412674ae819SStefano Zampini 2413674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 24143425bc38SStefano Zampini Mat newmat; 2415674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 24163425bc38SStefano Zampini PC newpc; 2417ce94432eSBarry Smith MPI_Comm comm; 24183425bc38SStefano Zampini PetscErrorCode ierr; 24193425bc38SStefano Zampini 24203425bc38SStefano Zampini PetscFunctionBegin; 2421ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 24223425bc38SStefano Zampini /* FETIDP linear matrix */ 24233425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 24241720468bSStefano Zampini fetidpmat_ctx->fully_redundant = fully_redundant; 24253425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 2426a5bb87b3Sstefano_zampini ierr = MatCreateShell(comm,fetidpmat_ctx->n,fetidpmat_ctx->n,fetidpmat_ctx->N,fetidpmat_ctx->N,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 24273425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 2428edf7251bSStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT_TRANSPOSE,(void (*)(void))FETIDPMatMultTranspose);CHKERRQ(ierr); 24293425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 2430547c9a8eSstefano_zampini ierr = MatSetOptionsPrefix(newmat,prefix);CHKERRQ(ierr); 2431547c9a8eSstefano_zampini ierr = MatAppendOptionsPrefix(newmat,"fetidp_");CHKERRQ(ierr); 24323425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 24333425bc38SStefano Zampini /* FETIDP preconditioner */ 24343425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 24353425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 24363425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 2437e1214c54Sstefano_zampini ierr = PCSetOperators(newpc,newmat,newmat);CHKERRQ(ierr); 2438e1214c54Sstefano_zampini ierr = PCSetOptionsPrefix(newpc,prefix);CHKERRQ(ierr); 2439e1214c54Sstefano_zampini ierr = PCAppendOptionsPrefix(newpc,"fetidp_");CHKERRQ(ierr); 2440e1214c54Sstefano_zampini if (!fetidpmat_ctx->l2g_lambda_only) { 24413425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 24423425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 24433425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 2444edf7251bSStefano Zampini ierr = PCShellSetApplyTranspose(newpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 2445c45b8d2dSstefano_zampini ierr = PCShellSetView(newpc,FETIDPPCView);CHKERRQ(ierr); 24463425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 2447e1214c54Sstefano_zampini } else { 2448e1214c54Sstefano_zampini KSP *ksps; 2449e1214c54Sstefano_zampini PC lagpc; 2450e1214c54Sstefano_zampini Mat M,AM,PM; 2451e1214c54Sstefano_zampini PetscInt nn; 2452e1214c54Sstefano_zampini 2453e1214c54Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_PPmat",(PetscObject*)&M);CHKERRQ(ierr); 2454e1214c54Sstefano_zampini ierr = PCSetType(newpc,PCFIELDSPLIT);CHKERRQ(ierr); 2455e1214c54Sstefano_zampini ierr = PCFieldSplitSetIS(newpc,"lag",fetidpmat_ctx->lagrange);CHKERRQ(ierr); 2456e1214c54Sstefano_zampini ierr = PCFieldSplitSetIS(newpc,"p",fetidpmat_ctx->pressure);CHKERRQ(ierr); 2457e1214c54Sstefano_zampini ierr = PCFieldSplitSetType(newpc,PC_COMPOSITE_SCHUR);CHKERRQ(ierr); 245840c75d76SStefano Zampini ierr = PCFieldSplitSetSchurFactType(newpc,PC_FIELDSPLIT_SCHUR_FACT_DIAG);CHKERRQ(ierr); 2459e1214c54Sstefano_zampini ierr = PCFieldSplitSetSchurPre(newpc,PC_FIELDSPLIT_SCHUR_PRE_USER,M);CHKERRQ(ierr); 2460c096484dSStefano Zampini ierr = PCFieldSplitSetSchurScale(newpc,1.0);CHKERRQ(ierr); 2461e1214c54Sstefano_zampini ierr = PCSetFromOptions(newpc);CHKERRQ(ierr); 2462e1214c54Sstefano_zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 2463e1214c54Sstefano_zampini 2464e1214c54Sstefano_zampini /* set the solver for the (0,0) block */ 246540c75d76SStefano Zampini ierr = PCFieldSplitGetSubKSP(newpc,&nn,&ksps);CHKERRQ(ierr); 2466e1214c54Sstefano_zampini ierr = PCCreate(comm,&lagpc);CHKERRQ(ierr); 2467e1214c54Sstefano_zampini ierr = PCSetType(lagpc,PCSHELL);CHKERRQ(ierr); 2468e1214c54Sstefano_zampini ierr = KSPGetOperators(ksps[0],&AM,&PM);CHKERRQ(ierr); 2469e1214c54Sstefano_zampini ierr = PCSetOperators(lagpc,AM,PM);CHKERRQ(ierr); 2470e1214c54Sstefano_zampini ierr = PCShellSetContext(lagpc,fetidppc_ctx);CHKERRQ(ierr); 2471e1214c54Sstefano_zampini ierr = PCShellSetApply(lagpc,FETIDPPCApply);CHKERRQ(ierr); 2472e1214c54Sstefano_zampini ierr = PCShellSetApplyTranspose(lagpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 2473e1214c54Sstefano_zampini ierr = PCShellSetView(lagpc,FETIDPPCView);CHKERRQ(ierr); 2474e1214c54Sstefano_zampini ierr = PCShellSetDestroy(lagpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 2475e1214c54Sstefano_zampini ierr = KSPSetPC(ksps[0],lagpc);CHKERRQ(ierr); 2476e1214c54Sstefano_zampini ierr = PCDestroy(&lagpc);CHKERRQ(ierr); 2477e1214c54Sstefano_zampini ierr = PetscFree(ksps);CHKERRQ(ierr); 2478e1214c54Sstefano_zampini } 24793425bc38SStefano Zampini /* return pointers for objects created */ 24803425bc38SStefano Zampini *fetidp_mat = newmat; 24813425bc38SStefano Zampini *fetidp_pc = newpc; 24823425bc38SStefano Zampini PetscFunctionReturn(0); 24833425bc38SStefano Zampini } 24841e6b0712SBarry Smith 248594ef8ddeSSatish Balay /*@C 24860f202f7eSStefano Zampini PCBDDCCreateFETIDPOperators - Create FETI-DP operators 24873425bc38SStefano Zampini 24883425bc38SStefano Zampini Collective 24893425bc38SStefano Zampini 24903425bc38SStefano Zampini Input Parameters: 24911720468bSStefano Zampini + pc - the BDDC preconditioning context (setup should have been called before) 2492547c9a8eSstefano_zampini . fully_redundant - true for a fully redundant set of Lagrange multipliers 2493547c9a8eSstefano_zampini - prefix - optional options database prefix for the objects to be created (can be NULL) 249428509bceSStefano Zampini 249528509bceSStefano Zampini Output Parameters: 24960f202f7eSStefano Zampini + fetidp_mat - shell FETI-DP matrix object 24970f202f7eSStefano Zampini - fetidp_pc - shell Dirichlet preconditioner for FETI-DP matrix 249828509bceSStefano Zampini 24993425bc38SStefano Zampini Level: developer 25003425bc38SStefano Zampini 25013425bc38SStefano Zampini Notes: 25020f202f7eSStefano Zampini Currently the only operations provided for FETI-DP matrix are MatMult and MatMultTranspose 25033425bc38SStefano Zampini 25040f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCMatFETIDPGetRHS, PCBDDCMatFETIDPGetSolution 25053425bc38SStefano Zampini @*/ 2506547c9a8eSstefano_zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, PetscBool fully_redundant, const char *prefix, Mat *fetidp_mat, PC *fetidp_pc) 25073425bc38SStefano Zampini { 25083425bc38SStefano Zampini PetscErrorCode ierr; 25093425bc38SStefano Zampini 25103425bc38SStefano Zampini PetscFunctionBegin; 25113425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 25123425bc38SStefano Zampini if (pc->setupcalled) { 2513547c9a8eSstefano_zampini ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,PetscBool,const char*,Mat*,PC*),(pc,fully_redundant,prefix,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 25144247aa23Sstefano_zampini } else SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n"); 25153425bc38SStefano Zampini PetscFunctionReturn(0); 25163425bc38SStefano Zampini } 25170c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2518da1bb401SStefano Zampini /*MC 2519da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 25200c7d97c5SJed Brown 252128509bceSStefano Zampini An implementation of the BDDC preconditioner based on 252228509bceSStefano Zampini 252328509bceSStefano Zampini .vb 252428509bceSStefano Zampini [1] C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 252528509bceSStefano Zampini [2] A. Klawonn and O. B. Widlund. "Dual-Primal FETI Methods for Linear Elasticity", http://cs.nyu.edu/csweb/Research/TechReports/TR2004-855/TR2004-855.pdf 252628509bceSStefano Zampini [3] J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", http://arxiv.org/abs/0712.3977 25270f202f7eSStefano Zampini [4] C. Pechstein and C. R. Dohrmann. "Modern domain decomposition methods BDDC, deluxe scaling, and an algebraic approach", Seminar talk, Linz, December 2013, http://people.ricam.oeaw.ac.at/c.pechstein/pechstein-bddc2013.pdf 252828509bceSStefano Zampini .ve 252928509bceSStefano Zampini 253028509bceSStefano Zampini The matrix to be preconditioned (Pmat) must be of type MATIS. 253128509bceSStefano Zampini 25320f202f7eSStefano Zampini Currently works with MATIS matrices with local matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers. 253328509bceSStefano Zampini 253428509bceSStefano Zampini It also works with unsymmetric and indefinite problems. 253528509bceSStefano Zampini 2536b6fdb6dfSStefano 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. 2537b6fdb6dfSStefano Zampini 2538c7017625SStefano 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). 253928509bceSStefano Zampini 25400f202f7eSStefano 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() 254130368db7SStefano Zampini Additional information on dofs can be provided by using PCBDDCSetDofsSplitting(), PCBDDCSetDirichletBoundaries(), PCBDDCSetNeumannBoundaries(), and PCBDDCSetPrimalVerticesIS() and their local counterparts. 254228509bceSStefano Zampini 25430f202f7eSStefano Zampini Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace(). Non-singular modes are retained via SVD. 254428509bceSStefano Zampini 25450f202f7eSStefano 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. 25460f202f7eSStefano Zampini User defined change of basis can be passed to PCBDDC by using PCBDDCSetChangeOfBasisMat() 254728509bceSStefano Zampini 25480f202f7eSStefano Zampini The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using a MatPartitioning object. 254928509bceSStefano Zampini 2550df4d28bfSStefano 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. 255128509bceSStefano Zampini 25520f202f7eSStefano 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. 25530f202f7eSStefano Zampini Deluxe scaling is not supported yet for FETI-DP. 25540f202f7eSStefano Zampini 25550f202f7eSStefano Zampini Options Database Keys (some of them, run with -h for a complete list): 25560f202f7eSStefano Zampini 25570f202f7eSStefano Zampini . -pc_bddc_use_vertices <true> - use or not vertices in primal space 25580f202f7eSStefano Zampini . -pc_bddc_use_edges <true> - use or not edges in primal space 25590f202f7eSStefano Zampini . -pc_bddc_use_faces <false> - use or not faces in primal space 25600f202f7eSStefano Zampini . -pc_bddc_symmetric <true> - symmetric computation of primal basis functions. Specify false for unsymmetric problems 25610f202f7eSStefano Zampini . -pc_bddc_use_change_of_basis <false> - use change of basis approach (on edges only) 25620f202f7eSStefano Zampini . -pc_bddc_use_change_on_faces <false> - use change of basis approach on faces if change of basis has been requested 25630f202f7eSStefano Zampini . -pc_bddc_switch_static <false> - switches from M_2 (default) to M_3 operator (see reference article [1]) 256428509bceSStefano Zampini . -pc_bddc_levels <0> - maximum number of levels for multilevel 25650f202f7eSStefano 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) 25665459c157SBarry 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) 25670f202f7eSStefano Zampini . -pc_bddc_use_deluxe_scaling <false> - use deluxe scaling 25680f202f7eSStefano Zampini . -pc_bddc_schur_layers <-1> - select the economic version of deluxe scaling by specifying the number of layers (-1 corresponds to the original deluxe scaling) 2569bd2a564bSStefano 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) 257028509bceSStefano Zampini - -pc_bddc_check_level <0> - set verbosity level of debugging output 257128509bceSStefano Zampini 257228509bceSStefano Zampini Options for Dirichlet, Neumann or coarse solver can be set with 257328509bceSStefano Zampini .vb 257428509bceSStefano Zampini -pc_bddc_dirichlet_ 257528509bceSStefano Zampini -pc_bddc_neumann_ 257628509bceSStefano Zampini -pc_bddc_coarse_ 257728509bceSStefano Zampini .ve 25780f202f7eSStefano Zampini e.g -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg. PCBDDC uses by default KPSPREONLY and PCLU. 257928509bceSStefano Zampini 25800f202f7eSStefano Zampini When using a multilevel approach, solvers' options at the N-th level (N > 1) can be specified as 258128509bceSStefano Zampini .vb 2582312be037SStefano Zampini -pc_bddc_dirichlet_lN_ 2583312be037SStefano Zampini -pc_bddc_neumann_lN_ 2584312be037SStefano Zampini -pc_bddc_coarse_lN_ 258528509bceSStefano Zampini .ve 25860f202f7eSStefano Zampini Note that level number ranges from the finest (0) to the coarsest (N). 25870f202f7eSStefano 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. 25880f202f7eSStefano Zampini .vb 25890f202f7eSStefano Zampini -pc_bddc_coarse_pc_bddc_adaptive_threshold 5 -pc_bddc_coarse_l1_pc_bddc_redistribute 3 25900f202f7eSStefano Zampini .ve 25910f202f7eSStefano 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 2592da1bb401SStefano Zampini 2593da1bb401SStefano Zampini Level: intermediate 2594da1bb401SStefano Zampini 2595e94cfbe0SPatrick Sanan Developer Notes: 2596da1bb401SStefano Zampini 2597da1bb401SStefano Zampini Contributed by Stefano Zampini 2598da1bb401SStefano Zampini 2599da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 2600da1bb401SStefano Zampini M*/ 2601b2573a8aSBarry Smith 26028cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 2603da1bb401SStefano Zampini { 2604da1bb401SStefano Zampini PetscErrorCode ierr; 2605da1bb401SStefano Zampini PC_BDDC *pcbddc; 2606da1bb401SStefano Zampini 2607da1bb401SStefano Zampini PetscFunctionBegin; 2608b00a9115SJed Brown ierr = PetscNewLog(pc,&pcbddc);CHKERRQ(ierr); 2609da1bb401SStefano Zampini pc->data = (void*)pcbddc; 2610da1bb401SStefano Zampini 2611da1bb401SStefano Zampini /* create PCIS data structure */ 2612da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 2613da1bb401SStefano Zampini 26149326c5c6Sstefano_zampini /* create local graph structure */ 26159326c5c6Sstefano_zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 26169326c5c6Sstefano_zampini 26179326c5c6Sstefano_zampini /* BDDC nonzero defaults */ 261808a5cf49SStefano Zampini pcbddc->use_local_adj = PETSC_TRUE; 261947d04d0dSStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 262047d04d0dSStefano Zampini pcbddc->use_edges = PETSC_TRUE; 26213301b35fSStefano Zampini pcbddc->symmetric_primal = PETSC_TRUE; 262214f95afaSStefano Zampini pcbddc->vertex_size = 1; 2623c703fcc7SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 262468457ee5SStefano Zampini pcbddc->coarse_size = -1; 262585c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 262647d04d0dSStefano Zampini pcbddc->coarsening_ratio = 8; 262757de7509SStefano Zampini pcbddc->coarse_eqs_per_proc = 1; 262827b6a85dSStefano Zampini pcbddc->benign_compute_correction = PETSC_TRUE; 26291e0482f5SStefano Zampini pcbddc->nedfield = -1; 26301e0482f5SStefano Zampini pcbddc->nedglobal = PETSC_TRUE; 2631be12c134Sstefano_zampini pcbddc->graphmaxcount = PETSC_MAX_INT; 2632b96c3477SStefano Zampini pcbddc->sub_schurs_layers = -1; 2633bd2a564bSStefano Zampini pcbddc->adaptive_threshold[0] = 0.0; 2634bd2a564bSStefano Zampini pcbddc->adaptive_threshold[1] = 0.0; 2635b7eb3628SStefano Zampini 2636da1bb401SStefano Zampini /* function pointers */ 2637da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 263893bd9ae7SStefano Zampini pc->ops->applytranspose = PCApplyTranspose_BDDC; 2639da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 2640da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 2641da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 26426b78500eSPatrick Sanan pc->ops->view = PCView_BDDC; 2643da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 2644da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 2645da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 2646534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 2647534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 26489326c5c6Sstefano_zampini pc->ops->reset = PCReset_BDDC; 2649da1bb401SStefano Zampini 2650da1bb401SStefano Zampini /* composing function */ 2651a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",PCBDDCSetDiscreteGradient_BDDC);CHKERRQ(ierr); 2652a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",PCBDDCSetDivergenceMat_BDDC);CHKERRQ(ierr); 2653906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",PCBDDCSetChangeOfBasisMat_BDDC);CHKERRQ(ierr); 2654674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 265530368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",PCBDDCSetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 2656bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 26572b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr); 2658b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr); 26592b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr); 2660bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 266182ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2662bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 266382ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2664bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 266582ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2666bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 266782ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2668bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 266963602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",PCBDDCSetDofsSplittingLocal_BDDC);CHKERRQ(ierr); 2670bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 2671bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 2672bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 2673bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 2674a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",PCPreSolveChangeRHS_BDDC);CHKERRQ(ierr); 2675ab8c8b98SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_BDDC);CHKERRQ(ierr); 2676da1bb401SStefano Zampini PetscFunctionReturn(0); 2677da1bb401SStefano Zampini } 2678