153cdbc3dSStefano Zampini /* TODOLIST 2eb97c9d2SStefano Zampini 3eb97c9d2SStefano Zampini Solvers 4a0d3c3abSStefano Zampini - Add support for cholesky for coarse solver (similar to local solvers) 5eb97c9d2SStefano Zampini - Propagate ksp prefixes for solvers to mat objects? 6eb97c9d2SStefano Zampini 7eb97c9d2SStefano Zampini User interface 80f202f7eSStefano Zampini - ** DM attached to pc? 9eb97c9d2SStefano Zampini 10eb97c9d2SStefano Zampini Debugging output 11b9b85e73SStefano Zampini - * Better management of verbosity levels of debugging output 12eb97c9d2SStefano Zampini 13eb97c9d2SStefano Zampini Extra 14b9b85e73SStefano Zampini - *** Is it possible to work with PCBDDCGraph on boundary indices only (less memory consumed)? 15eb97c9d2SStefano Zampini - BDDC with MG framework? 16eb97c9d2SStefano Zampini 17eb97c9d2SStefano Zampini MATIS related operations contained in BDDC code 18eb97c9d2SStefano Zampini - Provide general case for subassembling 19eb97c9d2SStefano Zampini 2053cdbc3dSStefano Zampini */ 210c7d97c5SJed Brown 22ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 23ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 243b03a366Sstefano_zampini #include <petscblaslapack.h> 25674ae819SStefano Zampini 2643371fb9SStefano Zampini static PetscBool PCBDDCPackageInitialized = PETSC_FALSE; 2743371fb9SStefano Zampini 28f3d41395Sstefano_zampini static PetscBool cited = PETSC_FALSE; 29f3d41395Sstefano_zampini static const char citation[] = 30f3d41395Sstefano_zampini "@article{ZampiniPCBDDC,\n" 31f3d41395Sstefano_zampini "author = {Stefano Zampini},\n" 32f3d41395Sstefano_zampini "title = {{PCBDDC}: A Class of Robust Dual-Primal Methods in {PETS}c},\n" 33f3d41395Sstefano_zampini "journal = {SIAM Journal on Scientific Computing},\n" 34f3d41395Sstefano_zampini "volume = {38},\n" 35f3d41395Sstefano_zampini "number = {5},\n" 36f3d41395Sstefano_zampini "pages = {S282-S306},\n" 37f3d41395Sstefano_zampini "year = {2016},\n" 38f3d41395Sstefano_zampini "doi = {10.1137/15M1025785},\n" 39f3d41395Sstefano_zampini "URL = {http://dx.doi.org/10.1137/15M1025785},\n" 40f3d41395Sstefano_zampini "eprint = {http://dx.doi.org/10.1137/15M1025785}\n" 41f3d41395Sstefano_zampini "}\n"; 42f3d41395Sstefano_zampini 4343371fb9SStefano Zampini PetscLogEvent PC_BDDC_Topology[PETSC_PCBDDC_MAXLEVELS]; 4443371fb9SStefano Zampini PetscLogEvent PC_BDDC_LocalSolvers[PETSC_PCBDDC_MAXLEVELS]; 4543371fb9SStefano Zampini PetscLogEvent PC_BDDC_LocalWork[PETSC_PCBDDC_MAXLEVELS]; 4643371fb9SStefano Zampini PetscLogEvent PC_BDDC_CorrectionSetUp[PETSC_PCBDDC_MAXLEVELS]; 4743371fb9SStefano Zampini PetscLogEvent PC_BDDC_CoarseSetUp[PETSC_PCBDDC_MAXLEVELS]; 4843371fb9SStefano Zampini PetscLogEvent PC_BDDC_CoarseSolver[PETSC_PCBDDC_MAXLEVELS]; 4943371fb9SStefano Zampini PetscLogEvent PC_BDDC_AdaptiveSetUp[PETSC_PCBDDC_MAXLEVELS]; 5043371fb9SStefano Zampini PetscLogEvent PC_BDDC_Scaling[PETSC_PCBDDC_MAXLEVELS]; 5143371fb9SStefano Zampini PetscLogEvent PC_BDDC_Schurs[PETSC_PCBDDC_MAXLEVELS]; 5243371fb9SStefano Zampini 530369aaf7SStefano Zampini PetscErrorCode PCApply_BDDC(PC,Vec,Vec); 540369aaf7SStefano Zampini 554416b707SBarry Smith PetscErrorCode PCSetFromOptions_BDDC(PetscOptionItems *PetscOptionsObject,PC pc) 560c7d97c5SJed Brown { 570c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 58bd2a564bSStefano Zampini PetscInt nt; 590c7d97c5SJed Brown PetscErrorCode ierr; 600c7d97c5SJed Brown 610c7d97c5SJed Brown PetscFunctionBegin; 62e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"BDDC options");CHKERRQ(ierr); 638eeda7d8SStefano Zampini /* Verbose debugging */ 64a13144ffSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_check_level","Verbose output for PCBDDC (intended for debug)","none",pcbddc->dbg_flag,&pcbddc->dbg_flag,NULL);CHKERRQ(ierr); 65a13144ffSStefano Zampini /* Approximate solvers */ 66c7017625SStefano 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); 67c7017625SStefano 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); 68c7017625SStefano 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); 69c7017625SStefano 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); 706b78500eSPatrick Sanan /* Primal space customization */ 7108a5cf49SStefano 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); 72be12c134Sstefano_zampini ierr = PetscOptionsInt("-pc_bddc_graph_maxcount","Maximum number of shared subdomains for a connected component","none",pcbddc->graphmaxcount,&pcbddc->graphmaxcount,NULL);CHKERRQ(ierr); 731c7a958bSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_corner_selection","Activates face-based corner selection","none",pcbddc->corner_selection,&pcbddc->corner_selection,NULL);CHKERRQ(ierr); 748eeda7d8SStefano 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); 758eeda7d8SStefano 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); 768eeda7d8SStefano 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); 7714f95afaSStefano 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); 786661aa1dSStefano 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); 7914f95afaSStefano 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); 808eeda7d8SStefano Zampini /* Change of basis */ 81b9b85e73SStefano 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); 82b9b85e73SStefano 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); 83674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 84674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 85674ae819SStefano Zampini } 868eeda7d8SStefano Zampini /* Switch between M_2 (default) and M_3 preconditioners (as defined by C. Dohrmann in the ref. article) */ 878eeda7d8SStefano 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); 8857de7509SStefano 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); 890298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr); 902b510759SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr); 91323d395dSStefano 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); 92674ae819SStefano 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); 93b96c3477SStefano 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); 94b96c3477SStefano 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); 95b96c3477SStefano 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); 96683d3df6SStefano 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); 97bf3a8328SStefano 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); 98839e9adbSstefano_zampini ierr = PetscOptionsBool("-pc_bddc_deluxe_singlemat","Collapse deluxe operators","none",pcbddc->deluxe_singlemat,&pcbddc->deluxe_singlemat,NULL);CHKERRQ(ierr); 99bf3a8328SStefano 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); 100bd2a564bSStefano Zampini nt = 2; 101bd2a564bSStefano Zampini ierr = PetscOptionsRealArray("-pc_bddc_adaptive_threshold","Thresholds to be used for adaptive selection of constraints","none",pcbddc->adaptive_threshold,&nt,NULL);CHKERRQ(ierr); 102bd2a564bSStefano Zampini if (nt == 1) pcbddc->adaptive_threshold[1] = pcbddc->adaptive_threshold[0]; 10308122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmin","Minimum number of constraints per connected components","none",pcbddc->adaptive_nmin,&pcbddc->adaptive_nmin,NULL);CHKERRQ(ierr); 10408122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmax","Maximum number of constraints per connected components","none",pcbddc->adaptive_nmax,&pcbddc->adaptive_nmax,NULL);CHKERRQ(ierr); 1053301b35fSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_symmetric","Symmetric computation of primal basis functions","none",pcbddc->symmetric_primal,&pcbddc->symmetric_primal,NULL);CHKERRQ(ierr); 106b0c7d250SStefano 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); 107b3afcdbeSStefano 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); 108e9627c49SStefano 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); 10927b6a85dSStefano 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); 110a198735bSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nonetflux","Automatic computation of no-net-flux quadrature weights","none",pcbddc->compute_nonetflux,&pcbddc->compute_nonetflux,NULL);CHKERRQ(ierr); 1114f1b2e48SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_detect_disconnected","Detects disconnected subdomains","none",pcbddc->detect_disconnected,&pcbddc->detect_disconnected,NULL);CHKERRQ(ierr); 1128361f951SStefano 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); 11370c64980SStefano 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); 1140c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 1150c7d97c5SJed Brown PetscFunctionReturn(0); 1160c7d97c5SJed Brown } 1176b78500eSPatrick Sanan 1186b78500eSPatrick Sanan static PetscErrorCode PCView_BDDC(PC pc,PetscViewer viewer) 1196b78500eSPatrick Sanan { 1206b78500eSPatrick Sanan PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 121e9627c49SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1226b78500eSPatrick Sanan PetscErrorCode ierr; 12371783a16SStefano Zampini PetscBool isascii; 124e9627c49SStefano Zampini PetscSubcomm subcomm; 125e9627c49SStefano Zampini PetscViewer subviewer; 1266b78500eSPatrick Sanan 1276b78500eSPatrick Sanan PetscFunctionBegin; 1286b78500eSPatrick Sanan ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1296b78500eSPatrick Sanan /* ASCII viewer */ 1306b78500eSPatrick Sanan if (isascii) { 1314b2aedd3SStefano Zampini PetscMPIInt color,rank,size; 132fbad9177SStefano Zampini PetscInt64 loc[7],gsum[6],gmax[6],gmin[6],totbenign; 133e9627c49SStefano Zampini PetscScalar interface_size; 134e9627c49SStefano Zampini PetscReal ratio1=0.,ratio2=0.; 135e9627c49SStefano Zampini Vec counter; 1366b78500eSPatrick Sanan 137b74ba07aSstefano_zampini if (!pc->setupcalled) { 138b74ba07aSstefano_zampini ierr = PetscViewerASCIIPrintf(viewer," Partial information available: preconditioner has not been setup yet\n");CHKERRQ(ierr); 139b74ba07aSstefano_zampini } 140efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use verbose output: %D\n",pcbddc->dbg_flag);CHKERRQ(ierr); 1416f0c0a6aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use user-defined CSR: %d\n",!!pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 1426f0c0a6aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use local mat graph: %d\n",pcbddc->use_local_adj && !pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 143e9627c49SStefano Zampini if (pcbddc->mat_graph->twodim) { 144efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Connectivity graph topological dimension: 2\n");CHKERRQ(ierr); 145e9627c49SStefano Zampini } else { 146efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Connectivity graph topological dimension: 3\n");CHKERRQ(ierr); 147e9627c49SStefano Zampini } 148aefa1729SStefano Zampini if (pcbddc->graphmaxcount != PETSC_MAX_INT) { 149efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Graph max count: %D\n",pcbddc->graphmaxcount);CHKERRQ(ierr); 150aefa1729SStefano Zampini } 15150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use vertices: %d (vertex size %D)\n",pcbddc->use_vertices,pcbddc->vertex_size);CHKERRQ(ierr); 152efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use edges: %d\n",pcbddc->use_edges);CHKERRQ(ierr); 153efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use faces: %d\n",pcbddc->use_faces);CHKERRQ(ierr); 154efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use true near null space: %d\n",pcbddc->use_nnsp_true);CHKERRQ(ierr); 155efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use QR for single constraints on cc: %d\n",pcbddc->use_qr_single);CHKERRQ(ierr); 156efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use change of basis on local edge nodes: %d\n",pcbddc->use_change_of_basis);CHKERRQ(ierr); 157efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use change of basis on local face nodes: %d\n",pcbddc->use_change_on_faces);CHKERRQ(ierr); 158efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," User defined change of basis matrix: %d\n",!!pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 159efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Has change of basis matrix: %d\n",!!pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 160efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eliminate dirichlet boundary dofs: %d\n",pcbddc->eliminate_dirdofs);CHKERRQ(ierr); 161efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Switch on static condensation ops around the interface preconditioner: %d\n",pcbddc->switch_static);CHKERRQ(ierr); 162efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use exact dirichlet trick: %d\n",pcbddc->use_exact_dirichlet_trick);CHKERRQ(ierr); 16350e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Multilevel max levels: %D\n",pcbddc->max_levels);CHKERRQ(ierr); 16450e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Multilevel coarsening ratio: %D\n",pcbddc->coarsening_ratio);CHKERRQ(ierr); 165efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use estimated eigs for coarse problem: %d\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 166efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe scaling: %d\n",pcbddc->use_deluxe_scaling);CHKERRQ(ierr); 167efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe zerorows: %d\n",pcbddc->deluxe_zerorows);CHKERRQ(ierr); 168efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe singlemat: %d\n",pcbddc->deluxe_singlemat);CHKERRQ(ierr); 169efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Rebuild interface graph for Schur principal minors: %d\n",pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 17050e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Number of dofs' layers for the computation of principal minors: %D\n",pcbddc->sub_schurs_layers);CHKERRQ(ierr); 171efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use user CSR graph to compute successive layers: %d\n",pcbddc->sub_schurs_use_useradj);CHKERRQ(ierr); 172bd2a564bSStefano Zampini if (pcbddc->adaptive_threshold[1] != pcbddc->adaptive_threshold[0]) { 173bd2a564bSStefano 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); 174bd2a564bSStefano Zampini } else { 175bd2a564bSStefano 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); 176bd2a564bSStefano Zampini } 17750e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Min constraints / connected component: %D\n",pcbddc->adaptive_nmin);CHKERRQ(ierr); 17850e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Max constraints / connected component: %D\n",pcbddc->adaptive_nmax);CHKERRQ(ierr); 179efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Invert exact Schur complement for adaptive selection: %d\n",pcbddc->sub_schurs_exact_schur);CHKERRQ(ierr); 180efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Symmetric computation of primal basis functions: %d\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 18150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Num. Procs. to map coarse adjacency list: %D\n",pcbddc->coarse_adj_red);CHKERRQ(ierr); 18250e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Coarse eqs per proc (significant at the coarsest level): %D\n",pcbddc->coarse_eqs_per_proc);CHKERRQ(ierr); 1838361f951SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Detect disconnected: %d (filter %d)\n",pcbddc->detect_disconnected,pcbddc->detect_disconnected_filter);CHKERRQ(ierr); 184efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Benign subspace trick: %d (change explicit %d)\n",pcbddc->benign_saddle_point,pcbddc->benign_change_explicit);CHKERRQ(ierr); 185efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Benign subspace trick is active: %d\n",pcbddc->benign_have_null);CHKERRQ(ierr); 186efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Algebraic computation of no-net-flux %d\n",pcbddc->compute_nonetflux);CHKERRQ(ierr); 187b74ba07aSstefano_zampini if (!pc->setupcalled) PetscFunctionReturn(0); 1886b78500eSPatrick Sanan 189fbad9177SStefano Zampini /* compute interface size */ 190e9627c49SStefano Zampini ierr = VecSet(pcis->vec1_B,1.0);CHKERRQ(ierr); 191e9627c49SStefano Zampini ierr = MatCreateVecs(pc->pmat,&counter,0);CHKERRQ(ierr); 192e9627c49SStefano Zampini ierr = VecSet(counter,0.0);CHKERRQ(ierr); 193e9627c49SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 194e9627c49SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 195e9627c49SStefano Zampini ierr = VecSum(counter,&interface_size);CHKERRQ(ierr); 196e9627c49SStefano Zampini ierr = VecDestroy(&counter);CHKERRQ(ierr); 197fbad9177SStefano Zampini 198fbad9177SStefano Zampini /* compute some statistics on the domain decomposition */ 199e9627c49SStefano Zampini gsum[0] = 1; 200fbad9177SStefano Zampini gsum[1] = gsum[2] = gsum[3] = gsum[4] = gsum[5] = 0; 201e9627c49SStefano Zampini loc[0] = !!pcis->n; 202e9627c49SStefano Zampini loc[1] = pcis->n - pcis->n_B; 203e9627c49SStefano Zampini loc[2] = pcis->n_B; 204e9627c49SStefano Zampini loc[3] = pcbddc->local_primal_size; 205345ecf6cSStefano Zampini loc[4] = pcis->n; 206fbad9177SStefano Zampini loc[5] = pcbddc->n_local_subs > 0 ? pcbddc->n_local_subs : (pcis->n ? 1 : 0); 207fbad9177SStefano Zampini loc[6] = pcbddc->benign_n; 208fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gsum,6,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 209fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = -1; 210fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gmax,6,MPIU_INT64,MPI_MAX,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 211fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = PETSC_MAX_INT; 212fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gmin,6,MPIU_INT64,MPI_MIN,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 213fbad9177SStefano Zampini ierr = MPI_Reduce(&loc[6],&totbenign,1,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 214e9627c49SStefano Zampini if (pcbddc->coarse_size) { 215e9627c49SStefano Zampini ratio1 = pc->pmat->rmap->N/(1.*pcbddc->coarse_size); 216e9627c49SStefano Zampini ratio2 = PetscRealPart(interface_size)/pcbddc->coarse_size; 217e9627c49SStefano Zampini } 218efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ********************************** STATISTICS AT LEVEL %d **********************************\n",pcbddc->current_level);CHKERRQ(ierr); 21950e0721cSStefano 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); 22050e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Coarsening ratios: all/coarse %D interface/coarse %D\n",(PetscInt)ratio1,(PetscInt)ratio2);CHKERRQ(ierr); 22150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Active processes : %D\n",(PetscInt)gsum[0]);CHKERRQ(ierr); 22250e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Total subdomains : %D\n",(PetscInt)gsum[5]);CHKERRQ(ierr); 223345ecf6cSStefano Zampini if (pcbddc->benign_have_null) { 22450e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Benign subs : %D\n",(PetscInt)totbenign);CHKERRQ(ierr); 225345ecf6cSStefano Zampini } 22650e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Dofs type :\tMIN\tMAX\tMEAN\n");CHKERRQ(ierr); 22750e0721cSStefano 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); 22850e0721cSStefano 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); 22950e0721cSStefano 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); 23050e0721cSStefano 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); 23150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Local subs :\t%D\t%D\n" ,(PetscInt)gmin[5],(PetscInt)gmax[5]);CHKERRQ(ierr); 23250e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," ********************************** COARSE PROBLEM DETAILS *********************************\n");CHKERRQ(ierr); 23327b6a85dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 234e9627c49SStefano Zampini 235fbad9177SStefano Zampini /* the coarse problem can be handled by a different communicator */ 236e9627c49SStefano Zampini if (pcbddc->coarse_ksp) color = 1; 237e9627c49SStefano Zampini else color = 0; 238e9627c49SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 2394b2aedd3SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 240e9627c49SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)pc),&subcomm);CHKERRQ(ierr); 2414b2aedd3SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,PetscMin(size,2));CHKERRQ(ierr); 242e9627c49SStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 243e9627c49SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 244e9627c49SStefano Zampini if (color == 1) { 245e9627c49SStefano Zampini ierr = KSPView(pcbddc->coarse_ksp,subviewer);CHKERRQ(ierr); 246e9627c49SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 247e9627c49SStefano Zampini } 248e9627c49SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 249e9627c49SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 250e9627c49SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 251e9627c49SStefano Zampini } 2526b78500eSPatrick Sanan PetscFunctionReturn(0); 2536b78500eSPatrick Sanan } 254a13144ffSStefano Zampini 2551e0482f5SStefano Zampini static PetscErrorCode PCBDDCSetDiscreteGradient_BDDC(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 256a13144ffSStefano Zampini { 257a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 258a13144ffSStefano Zampini PetscErrorCode ierr; 259a13144ffSStefano Zampini 260a13144ffSStefano Zampini PetscFunctionBegin; 261a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr); 262a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 263a13144ffSStefano Zampini pcbddc->discretegradient = G; 264a13144ffSStefano Zampini pcbddc->nedorder = order > 0 ? order : -order; 265495a2a07SStefano Zampini pcbddc->nedfield = field; 2661e0482f5SStefano Zampini pcbddc->nedglobal = global; 2671e0482f5SStefano Zampini pcbddc->conforming = conforming; 268a13144ffSStefano Zampini PetscFunctionReturn(0); 269a13144ffSStefano Zampini } 270a13144ffSStefano Zampini 271a13144ffSStefano Zampini /*@ 272a13144ffSStefano Zampini PCBDDCSetDiscreteGradient - Sets the discrete gradient 273a13144ffSStefano Zampini 274a13144ffSStefano Zampini Collective on PC 275a13144ffSStefano Zampini 276a13144ffSStefano Zampini Input Parameters: 277a13144ffSStefano Zampini + pc - the preconditioning context 278a13144ffSStefano Zampini . G - the discrete gradient matrix (should be in AIJ format) 279a13144ffSStefano Zampini . order - the order of the Nedelec space (1 for the lowest order) 280495a2a07SStefano Zampini . field - the field id of the Nedelec dofs (not used if the fields have not been specified) 2811e0482f5SStefano Zampini . global - the type of global ordering for the rows of G 282a13144ffSStefano Zampini - conforming - whether the mesh is conforming or not 283a13144ffSStefano Zampini 284a13144ffSStefano Zampini Level: advanced 285a13144ffSStefano Zampini 28695452b02SPatrick Sanan Notes: 28795452b02SPatrick Sanan The discrete gradient matrix G is used to analyze the subdomain edges, and it should not contain any zero entry. 288495a2a07SStefano Zampini For variable order spaces, the order should be set to zero. 2891e0482f5SStefano Zampini If global is true, the rows of G should be given in global ordering for the whole dofs; 2901e0482f5SStefano Zampini if false, the ordering should be global for the Nedelec field. 2911e0482f5SStefano 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 2921e0482f5SStefano Zampini and geid the one for the Nedelec field. 293a13144ffSStefano Zampini 294495a2a07SStefano Zampini .seealso: PCBDDC,PCBDDCSetDofsSplitting(),PCBDDCSetDofsSplittingLocal() 295a13144ffSStefano Zampini @*/ 2961e0482f5SStefano Zampini PetscErrorCode PCBDDCSetDiscreteGradient(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 297a13144ffSStefano Zampini { 298a13144ffSStefano Zampini PetscErrorCode ierr; 299a13144ffSStefano Zampini 300a13144ffSStefano Zampini PetscFunctionBegin; 301a13144ffSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 302a13144ffSStefano Zampini PetscValidHeaderSpecific(G,MAT_CLASSID,2); 303a13144ffSStefano Zampini PetscValidLogicalCollectiveInt(pc,order,3); 3041e0482f5SStefano Zampini PetscValidLogicalCollectiveInt(pc,field,4); 3051e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,global,5); 3061e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,conforming,6); 3071e0482f5SStefano Zampini PetscCheckSameComm(pc,1,G,2); 3081e0482f5SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDiscreteGradient_C",(PC,Mat,PetscInt,PetscInt,PetscBool,PetscBool),(pc,G,order,field,global,conforming));CHKERRQ(ierr); 309a13144ffSStefano Zampini PetscFunctionReturn(0); 310a13144ffSStefano Zampini } 311a13144ffSStefano Zampini 3128ae0ca82SStefano Zampini static PetscErrorCode PCBDDCSetDivergenceMat_BDDC(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 313a198735bSStefano Zampini { 314a198735bSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 315a198735bSStefano Zampini PetscErrorCode ierr; 3166b78500eSPatrick Sanan 317a198735bSStefano Zampini PetscFunctionBegin; 318a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)divudotp);CHKERRQ(ierr); 319a198735bSStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 320a198735bSStefano Zampini pcbddc->divudotp = divudotp; 3218ae0ca82SStefano Zampini pcbddc->divudotp_trans = trans; 322a198735bSStefano Zampini pcbddc->compute_nonetflux = PETSC_TRUE; 323a198735bSStefano Zampini if (vl2l) { 324a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2l);CHKERRQ(ierr); 325fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 326a198735bSStefano Zampini pcbddc->divudotp_vl2l = vl2l; 327a198735bSStefano Zampini } 328a198735bSStefano Zampini PetscFunctionReturn(0); 329a198735bSStefano Zampini } 3303d996552SStefano Zampini 331a198735bSStefano Zampini /*@ 332a198735bSStefano Zampini PCBDDCSetDivergenceMat - Sets the linear operator representing \int_\Omega \div {\bf u} \cdot p dx 333a198735bSStefano Zampini 334a198735bSStefano Zampini Collective on PC 335a198735bSStefano Zampini 336a198735bSStefano Zampini Input Parameters: 337a198735bSStefano Zampini + pc - the preconditioning context 338a198735bSStefano Zampini . divudotp - the matrix (must be of type MATIS) 3398ae0ca82SStefano Zampini . trans - if trans if false (resp. true), then pressures are in the test (trial) space and velocities are in the trial (test) space. 34005a3bf82SStefano 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 341a198735bSStefano Zampini 342a198735bSStefano Zampini Level: advanced 343a198735bSStefano Zampini 34495452b02SPatrick Sanan Notes: 34595452b02SPatrick Sanan This auxiliary matrix is used to compute quadrature weights representing the net-flux across subdomain boundaries 34605a3bf82SStefano Zampini If vl2l is NULL, the local ordering for velocities in divudotp should match that of the preconditioning matrix 347a198735bSStefano Zampini 348a198735bSStefano Zampini .seealso: PCBDDC 349a198735bSStefano Zampini @*/ 3508ae0ca82SStefano Zampini PetscErrorCode PCBDDCSetDivergenceMat(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 351a198735bSStefano Zampini { 352a198735bSStefano Zampini PetscBool ismatis; 353a198735bSStefano Zampini PetscErrorCode ierr; 354a198735bSStefano Zampini 355a198735bSStefano Zampini PetscFunctionBegin; 356a198735bSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 357a198735bSStefano Zampini PetscValidHeaderSpecific(divudotp,MAT_CLASSID,2); 358a198735bSStefano Zampini PetscCheckSameComm(pc,1,divudotp,2); 3598ae0ca82SStefano Zampini PetscValidLogicalCollectiveBool(pc,trans,3); 3608ae0ca82SStefano Zampini if (vl2l) PetscValidHeaderSpecific(divudotp,IS_CLASSID,4); 361a198735bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)divudotp,MATIS,&ismatis);CHKERRQ(ierr); 362a198735bSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Divergence matrix needs to be of type MATIS"); 3638ae0ca82SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDivergenceMat_C",(PC,Mat,PetscBool,IS),(pc,divudotp,trans,vl2l));CHKERRQ(ierr); 364a198735bSStefano Zampini PetscFunctionReturn(0); 365a198735bSStefano Zampini } 3662d505d7fSStefano Zampini 3671dd7afcfSStefano Zampini static PetscErrorCode PCBDDCSetChangeOfBasisMat_BDDC(PC pc, Mat change, PetscBool interior) 368b9b85e73SStefano Zampini { 369b9b85e73SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 370b9b85e73SStefano Zampini PetscErrorCode ierr; 371b9b85e73SStefano Zampini 372b9b85e73SStefano Zampini PetscFunctionBegin; 373b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)change);CHKERRQ(ierr); 37456282151SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 375b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = change; 3761dd7afcfSStefano Zampini pcbddc->change_interior = interior; 377b9b85e73SStefano Zampini PetscFunctionReturn(0); 378b9b85e73SStefano Zampini } 379b9b85e73SStefano Zampini /*@ 380906d46d4SStefano Zampini PCBDDCSetChangeOfBasisMat - Set user defined change of basis for dofs 381b9b85e73SStefano Zampini 382b9b85e73SStefano Zampini Collective on PC 383b9b85e73SStefano Zampini 384b9b85e73SStefano Zampini Input Parameters: 385b9b85e73SStefano Zampini + pc - the preconditioning context 3861dd7afcfSStefano Zampini . change - the change of basis matrix 3871dd7afcfSStefano Zampini - interior - whether or not the change of basis modifies interior dofs 388b9b85e73SStefano Zampini 389b9b85e73SStefano Zampini Level: intermediate 390b9b85e73SStefano Zampini 391b9b85e73SStefano Zampini Notes: 392b9b85e73SStefano Zampini 393b9b85e73SStefano Zampini .seealso: PCBDDC 394b9b85e73SStefano Zampini @*/ 3951dd7afcfSStefano Zampini PetscErrorCode PCBDDCSetChangeOfBasisMat(PC pc, Mat change, PetscBool interior) 396b9b85e73SStefano Zampini { 397b9b85e73SStefano Zampini PetscErrorCode ierr; 398b9b85e73SStefano Zampini 399b9b85e73SStefano Zampini PetscFunctionBegin; 400b9b85e73SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 401b9b85e73SStefano Zampini PetscValidHeaderSpecific(change,MAT_CLASSID,2); 402906d46d4SStefano Zampini PetscCheckSameComm(pc,1,change,2); 403906d46d4SStefano Zampini if (pc->mat) { 404906d46d4SStefano Zampini PetscInt rows_c,cols_c,rows,cols; 405906d46d4SStefano Zampini ierr = MatGetSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 406906d46d4SStefano Zampini ierr = MatGetSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 407e0fe2d75SToby 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); 408e0fe2d75SToby 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); 409906d46d4SStefano Zampini ierr = MatGetLocalSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 410906d46d4SStefano Zampini ierr = MatGetLocalSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 411e0fe2d75SToby 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); 412e0fe2d75SToby 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); 413906d46d4SStefano Zampini } 4141dd7afcfSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetChangeOfBasisMat_C",(PC,Mat,PetscBool),(pc,change,interior));CHKERRQ(ierr); 415b9b85e73SStefano Zampini PetscFunctionReturn(0); 416b9b85e73SStefano Zampini } 4172d505d7fSStefano Zampini 41830368db7SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesIS_BDDC(PC pc, IS PrimalVertices) 41930368db7SStefano Zampini { 42030368db7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 42156282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 42230368db7SStefano Zampini PetscErrorCode ierr; 42330368db7SStefano Zampini 42430368db7SStefano Zampini PetscFunctionBegin; 42556282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 42656282151SStefano Zampini if (pcbddc->user_primal_vertices) { 42756282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices,&isequal);CHKERRQ(ierr); 42856282151SStefano Zampini } 42930368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 43030368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 43130368db7SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 43256282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 43330368db7SStefano Zampini PetscFunctionReturn(0); 43430368db7SStefano Zampini } 435ab8c8b98SStefano Zampini 43630368db7SStefano Zampini /*@ 43730368db7SStefano Zampini PCBDDCSetPrimalVerticesIS - Set additional user defined primal vertices in PCBDDC 43830368db7SStefano Zampini 43930368db7SStefano Zampini Collective 44030368db7SStefano Zampini 44130368db7SStefano Zampini Input Parameters: 44230368db7SStefano Zampini + pc - the preconditioning context 44330368db7SStefano Zampini - PrimalVertices - index set of primal vertices in global numbering (can be empty) 44430368db7SStefano Zampini 44530368db7SStefano Zampini Level: intermediate 44630368db7SStefano Zampini 44730368db7SStefano Zampini Notes: 44830368db7SStefano Zampini Any process can list any global node 44930368db7SStefano Zampini 45030368db7SStefano Zampini .seealso: PCBDDC 45130368db7SStefano Zampini @*/ 45230368db7SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesIS(PC pc, IS PrimalVertices) 45330368db7SStefano Zampini { 45430368db7SStefano Zampini PetscErrorCode ierr; 45530368db7SStefano Zampini 45630368db7SStefano Zampini PetscFunctionBegin; 45730368db7SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 45830368db7SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 45930368db7SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 46030368db7SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 46130368db7SStefano Zampini PetscFunctionReturn(0); 46230368db7SStefano Zampini } 4632d505d7fSStefano Zampini 464674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 465674ae819SStefano Zampini { 466674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 46756282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 468674ae819SStefano Zampini PetscErrorCode ierr; 4691e6b0712SBarry Smith 470674ae819SStefano Zampini PetscFunctionBegin; 47156282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 47256282151SStefano Zampini if (pcbddc->user_primal_vertices_local) { 47356282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices_local,&isequal);CHKERRQ(ierr); 47456282151SStefano Zampini } 475674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 47630368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 47730368db7SStefano Zampini pcbddc->user_primal_vertices_local = PrimalVertices; 47856282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 479674ae819SStefano Zampini PetscFunctionReturn(0); 480674ae819SStefano Zampini } 481674ae819SStefano Zampini /*@ 48228509bceSStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC 483674ae819SStefano Zampini 48417eb1463SStefano Zampini Collective 485674ae819SStefano Zampini 486674ae819SStefano Zampini Input Parameters: 487674ae819SStefano Zampini + pc - the preconditioning context 48817eb1463SStefano Zampini - PrimalVertices - index set of primal vertices in local numbering (can be empty) 489674ae819SStefano Zampini 490674ae819SStefano Zampini Level: intermediate 491674ae819SStefano Zampini 492674ae819SStefano Zampini Notes: 493674ae819SStefano Zampini 494674ae819SStefano Zampini .seealso: PCBDDC 495674ae819SStefano Zampini @*/ 496674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 497674ae819SStefano Zampini { 498674ae819SStefano Zampini PetscErrorCode ierr; 499674ae819SStefano Zampini 500674ae819SStefano Zampini PetscFunctionBegin; 501674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 502674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 50317eb1463SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 504674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 505674ae819SStefano Zampini PetscFunctionReturn(0); 506674ae819SStefano Zampini } 5072d505d7fSStefano Zampini 5084fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 5094fad6a16SStefano Zampini { 5104fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5114fad6a16SStefano Zampini 5124fad6a16SStefano Zampini PetscFunctionBegin; 5134fad6a16SStefano Zampini pcbddc->coarsening_ratio = k; 5144fad6a16SStefano Zampini PetscFunctionReturn(0); 5154fad6a16SStefano Zampini } 5161e6b0712SBarry Smith 5174fad6a16SStefano Zampini /*@ 51828509bceSStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel 5194fad6a16SStefano Zampini 5204fad6a16SStefano Zampini Logically collective on PC 5214fad6a16SStefano Zampini 5224fad6a16SStefano Zampini Input Parameters: 5234fad6a16SStefano Zampini + pc - the preconditioning context 52428509bceSStefano Zampini - k - coarsening ratio (H/h at the coarser level) 5254fad6a16SStefano Zampini 5260f202f7eSStefano Zampini Options Database Keys: 5270f202f7eSStefano Zampini . -pc_bddc_coarsening_ratio 5284fad6a16SStefano Zampini 5294fad6a16SStefano Zampini Level: intermediate 5304fad6a16SStefano Zampini 5314fad6a16SStefano Zampini Notes: 5320f202f7eSStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level 5334fad6a16SStefano Zampini 5340f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetLevels() 5354fad6a16SStefano Zampini @*/ 5364fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 5374fad6a16SStefano Zampini { 5384fad6a16SStefano Zampini PetscErrorCode ierr; 5394fad6a16SStefano Zampini 5404fad6a16SStefano Zampini PetscFunctionBegin; 5414fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5422b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,k,2); 5434fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 5444fad6a16SStefano Zampini PetscFunctionReturn(0); 5454fad6a16SStefano Zampini } 5462b510759SStefano Zampini 547b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */ 548b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg) 549b8ffe317SStefano Zampini { 550b8ffe317SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 551b8ffe317SStefano Zampini 552b8ffe317SStefano Zampini PetscFunctionBegin; 55385c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = flg; 554b8ffe317SStefano Zampini PetscFunctionReturn(0); 555b8ffe317SStefano Zampini } 556b8ffe317SStefano Zampini 557b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg) 5582b510759SStefano Zampini { 5592b510759SStefano Zampini PetscErrorCode ierr; 5602b510759SStefano Zampini 5612b510759SStefano Zampini PetscFunctionBegin; 5622b510759SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 563b8ffe317SStefano Zampini PetscValidLogicalCollectiveBool(pc,flg,2); 564b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr); 5652b510759SStefano Zampini PetscFunctionReturn(0); 5662b510759SStefano Zampini } 5671e6b0712SBarry Smith 5682b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level) 5694fad6a16SStefano Zampini { 5704fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5714fad6a16SStefano Zampini 5724fad6a16SStefano Zampini PetscFunctionBegin; 5732b510759SStefano Zampini pcbddc->current_level = level; 5744fad6a16SStefano Zampini PetscFunctionReturn(0); 5754fad6a16SStefano Zampini } 5761e6b0712SBarry Smith 577b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 578b8ffe317SStefano Zampini { 579b8ffe317SStefano Zampini PetscErrorCode ierr; 580b8ffe317SStefano Zampini 581b8ffe317SStefano Zampini PetscFunctionBegin; 582b8ffe317SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 583b8ffe317SStefano Zampini PetscValidLogicalCollectiveInt(pc,level,2); 584b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr); 585b8ffe317SStefano Zampini PetscFunctionReturn(0); 586b8ffe317SStefano Zampini } 587b8ffe317SStefano Zampini 5882b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels) 5892b510759SStefano Zampini { 5902b510759SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5912b510759SStefano Zampini 5922b510759SStefano Zampini PetscFunctionBegin; 5932b510759SStefano Zampini pcbddc->max_levels = levels; 5942b510759SStefano Zampini PetscFunctionReturn(0); 5952b510759SStefano Zampini } 5962b510759SStefano Zampini 5974fad6a16SStefano Zampini /*@ 59837ebbdf7SStefano Zampini PCBDDCSetLevels - Sets the maximum number of additional levels allowed for multilevel BDDC 5994fad6a16SStefano Zampini 6004fad6a16SStefano Zampini Logically collective on PC 6014fad6a16SStefano Zampini 6024fad6a16SStefano Zampini Input Parameters: 6034fad6a16SStefano Zampini + pc - the preconditioning context 60437ebbdf7SStefano Zampini - levels - the maximum number of levels 6054fad6a16SStefano Zampini 6060f202f7eSStefano Zampini Options Database Keys: 6070f202f7eSStefano Zampini . -pc_bddc_levels 6084fad6a16SStefano Zampini 6094fad6a16SStefano Zampini Level: intermediate 6104fad6a16SStefano Zampini 6114fad6a16SStefano Zampini Notes: 61237ebbdf7SStefano Zampini The default value is 0, that gives the classical two-levels BDDC 6134fad6a16SStefano Zampini 6140f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetCoarseningRatio() 6154fad6a16SStefano Zampini @*/ 6162b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels) 6174fad6a16SStefano Zampini { 6184fad6a16SStefano Zampini PetscErrorCode ierr; 6194fad6a16SStefano Zampini 6204fad6a16SStefano Zampini PetscFunctionBegin; 6214fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6222b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,levels,2); 62337ebbdf7SStefano 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); 6242b510759SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr); 6254fad6a16SStefano Zampini PetscFunctionReturn(0); 6264fad6a16SStefano Zampini } 6271e6b0712SBarry Smith 6283b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 6293b03a366Sstefano_zampini { 6303b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 63156282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 6323b03a366Sstefano_zampini PetscErrorCode ierr; 6333b03a366Sstefano_zampini 6343b03a366Sstefano_zampini PetscFunctionBegin; 63556282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 63656282151SStefano Zampini if (pcbddc->DirichletBoundaries) { 63756282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundaries,&isequal);CHKERRQ(ierr); 63856282151SStefano Zampini } 639785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 640785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 6413b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 64236e030ebSStefano Zampini pcbddc->DirichletBoundaries = DirichletBoundaries; 64356282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 6443b03a366Sstefano_zampini PetscFunctionReturn(0); 6453b03a366Sstefano_zampini } 6461e6b0712SBarry Smith 6473b03a366Sstefano_zampini /*@ 64828509bceSStefano Zampini PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem. 6493b03a366Sstefano_zampini 650785d1243SStefano Zampini Collective 6513b03a366Sstefano_zampini 6523b03a366Sstefano_zampini Input Parameters: 6533b03a366Sstefano_zampini + pc - the preconditioning context 654785d1243SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries 6553b03a366Sstefano_zampini 6563b03a366Sstefano_zampini Level: intermediate 6573b03a366Sstefano_zampini 6580f202f7eSStefano Zampini Notes: 6590f202f7eSStefano Zampini Provide the information if you used MatZeroRows/Columns routines. Any process can list any global node 6603b03a366Sstefano_zampini 6610f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundariesLocal(), MatZeroRows(), MatZeroRowsColumns() 6623b03a366Sstefano_zampini @*/ 6633b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 6643b03a366Sstefano_zampini { 6653b03a366Sstefano_zampini PetscErrorCode ierr; 6663b03a366Sstefano_zampini 6673b03a366Sstefano_zampini PetscFunctionBegin; 6683b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 669674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 670785d1243SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 6713b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 6723b03a366Sstefano_zampini PetscFunctionReturn(0); 6733b03a366Sstefano_zampini } 6741e6b0712SBarry Smith 67582ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries) 6763b03a366Sstefano_zampini { 6773b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 67856282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 6793b03a366Sstefano_zampini PetscErrorCode ierr; 6803b03a366Sstefano_zampini 6813b03a366Sstefano_zampini PetscFunctionBegin; 68256282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 68356282151SStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 68456282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundariesLocal,&isequal);CHKERRQ(ierr); 68556282151SStefano Zampini } 686785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 687785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 6883b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 689785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = DirichletBoundaries; 69056282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 6913b03a366Sstefano_zampini PetscFunctionReturn(0); 6923b03a366Sstefano_zampini } 6933b03a366Sstefano_zampini 6943b03a366Sstefano_zampini /*@ 69582ba6b80SStefano Zampini PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering. 6963b03a366Sstefano_zampini 697785d1243SStefano Zampini Collective 6983b03a366Sstefano_zampini 6993b03a366Sstefano_zampini Input Parameters: 7003b03a366Sstefano_zampini + pc - the preconditioning context 70182ba6b80SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering) 7023b03a366Sstefano_zampini 7033b03a366Sstefano_zampini Level: intermediate 7043b03a366Sstefano_zampini 7053b03a366Sstefano_zampini Notes: 7063b03a366Sstefano_zampini 7070f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundaries(), MatZeroRows(), MatZeroRowsColumns() 7083b03a366Sstefano_zampini @*/ 70982ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries) 7103b03a366Sstefano_zampini { 7113b03a366Sstefano_zampini PetscErrorCode ierr; 7123b03a366Sstefano_zampini 7133b03a366Sstefano_zampini PetscFunctionBegin; 7143b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 7153b03a366Sstefano_zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 71682ba6b80SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 71782ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 7183b03a366Sstefano_zampini PetscFunctionReturn(0); 7193b03a366Sstefano_zampini } 7203b03a366Sstefano_zampini 72153cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 7220c7d97c5SJed Brown { 7230c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 72456282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 72553cdbc3dSStefano Zampini PetscErrorCode ierr; 7260c7d97c5SJed Brown 7270c7d97c5SJed Brown PetscFunctionBegin; 72856282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 72956282151SStefano Zampini if (pcbddc->NeumannBoundaries) { 73056282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundaries,&isequal);CHKERRQ(ierr); 73156282151SStefano Zampini } 732785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 733785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 73453cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 73536e030ebSStefano Zampini pcbddc->NeumannBoundaries = NeumannBoundaries; 73656282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7370c7d97c5SJed Brown PetscFunctionReturn(0); 7380c7d97c5SJed Brown } 7391e6b0712SBarry Smith 74057527edcSJed Brown /*@ 74128509bceSStefano Zampini PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem. 74257527edcSJed Brown 743785d1243SStefano Zampini Collective 74457527edcSJed Brown 74557527edcSJed Brown Input Parameters: 74657527edcSJed Brown + pc - the preconditioning context 747785d1243SStefano Zampini - NeumannBoundaries - parallel IS defining the Neumann boundaries 74857527edcSJed Brown 74957527edcSJed Brown Level: intermediate 75057527edcSJed Brown 7510f202f7eSStefano Zampini Notes: 7520f202f7eSStefano Zampini Any process can list any global node 75357527edcSJed Brown 7540f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundariesLocal() 75557527edcSJed Brown @*/ 75653cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 7570c7d97c5SJed Brown { 7580c7d97c5SJed Brown PetscErrorCode ierr; 7590c7d97c5SJed Brown 7600c7d97c5SJed Brown PetscFunctionBegin; 7610c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 762674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 763785d1243SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 76453cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 76553cdbc3dSStefano Zampini PetscFunctionReturn(0); 76653cdbc3dSStefano Zampini } 7671e6b0712SBarry Smith 76882ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries) 7690c7d97c5SJed Brown { 7700c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 77156282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 7720c7d97c5SJed Brown PetscErrorCode ierr; 7730c7d97c5SJed Brown 7740c7d97c5SJed Brown PetscFunctionBegin; 77556282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 77656282151SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 77756282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundariesLocal,&isequal);CHKERRQ(ierr); 77856282151SStefano Zampini } 779785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 780785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 7810c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 782785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = NeumannBoundaries; 78356282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7840c7d97c5SJed Brown PetscFunctionReturn(0); 7850c7d97c5SJed Brown } 7860c7d97c5SJed Brown 7870c7d97c5SJed Brown /*@ 78882ba6b80SStefano Zampini PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering. 7890c7d97c5SJed Brown 790785d1243SStefano Zampini Collective 7910c7d97c5SJed Brown 7920c7d97c5SJed Brown Input Parameters: 7930c7d97c5SJed Brown + pc - the preconditioning context 79482ba6b80SStefano Zampini - NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering) 7950c7d97c5SJed Brown 7960c7d97c5SJed Brown Level: intermediate 7970c7d97c5SJed Brown 7980c7d97c5SJed Brown Notes: 7990c7d97c5SJed Brown 8000f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundaries() 8010c7d97c5SJed Brown @*/ 80282ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries) 8030c7d97c5SJed Brown { 8040c7d97c5SJed Brown PetscErrorCode ierr; 8050c7d97c5SJed Brown 8060c7d97c5SJed Brown PetscFunctionBegin; 8070c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 8080c7d97c5SJed Brown PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 80982ba6b80SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 81082ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 81153cdbc3dSStefano Zampini PetscFunctionReturn(0); 81253cdbc3dSStefano Zampini } 81353cdbc3dSStefano Zampini 814da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 815da1bb401SStefano Zampini { 816da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 817da1bb401SStefano Zampini 818da1bb401SStefano Zampini PetscFunctionBegin; 819da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 820da1bb401SStefano Zampini PetscFunctionReturn(0); 821da1bb401SStefano Zampini } 8221e6b0712SBarry Smith 823da1bb401SStefano Zampini /*@ 824785d1243SStefano Zampini PCBDDCGetDirichletBoundaries - Get parallel IS for Dirichlet boundaries 825da1bb401SStefano Zampini 826785d1243SStefano Zampini Collective 827785d1243SStefano Zampini 828785d1243SStefano Zampini Input Parameters: 829785d1243SStefano Zampini . pc - the preconditioning context 830785d1243SStefano Zampini 831785d1243SStefano Zampini Output Parameters: 832785d1243SStefano Zampini . DirichletBoundaries - index set defining the Dirichlet boundaries 833785d1243SStefano Zampini 834785d1243SStefano Zampini Level: intermediate 835785d1243SStefano Zampini 8360f202f7eSStefano Zampini Notes: 8370f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetDirichletBoundaries 838785d1243SStefano Zampini 839785d1243SStefano Zampini .seealso: PCBDDC 840785d1243SStefano Zampini @*/ 841785d1243SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 842785d1243SStefano Zampini { 843785d1243SStefano Zampini PetscErrorCode ierr; 844785d1243SStefano Zampini 845785d1243SStefano Zampini PetscFunctionBegin; 846785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 847785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 848785d1243SStefano Zampini PetscFunctionReturn(0); 849785d1243SStefano Zampini } 850785d1243SStefano Zampini 851785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries) 852785d1243SStefano Zampini { 853785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 854785d1243SStefano Zampini 855785d1243SStefano Zampini PetscFunctionBegin; 856785d1243SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundariesLocal; 857785d1243SStefano Zampini PetscFunctionReturn(0); 858785d1243SStefano Zampini } 859785d1243SStefano Zampini 860da1bb401SStefano Zampini /*@ 86182ba6b80SStefano Zampini PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering) 862da1bb401SStefano Zampini 863785d1243SStefano Zampini Collective 864da1bb401SStefano Zampini 865da1bb401SStefano Zampini Input Parameters: 86628509bceSStefano Zampini . pc - the preconditioning context 867da1bb401SStefano Zampini 868da1bb401SStefano Zampini Output Parameters: 86928509bceSStefano Zampini . DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 870da1bb401SStefano Zampini 871da1bb401SStefano Zampini Level: intermediate 872da1bb401SStefano Zampini 873da1bb401SStefano Zampini Notes: 8740f202f7eSStefano 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). 8750f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 876da1bb401SStefano Zampini 877da1bb401SStefano Zampini .seealso: PCBDDC 878da1bb401SStefano Zampini @*/ 87982ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries) 880da1bb401SStefano Zampini { 881da1bb401SStefano Zampini PetscErrorCode ierr; 882da1bb401SStefano Zampini 883da1bb401SStefano Zampini PetscFunctionBegin; 884da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 88582ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 886da1bb401SStefano Zampini PetscFunctionReturn(0); 887da1bb401SStefano Zampini } 8881e6b0712SBarry Smith 88953cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 89053cdbc3dSStefano Zampini { 89153cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 89253cdbc3dSStefano Zampini 89353cdbc3dSStefano Zampini PetscFunctionBegin; 89453cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 89553cdbc3dSStefano Zampini PetscFunctionReturn(0); 89653cdbc3dSStefano Zampini } 8971e6b0712SBarry Smith 89853cdbc3dSStefano Zampini /*@ 899785d1243SStefano Zampini PCBDDCGetNeumannBoundaries - Get parallel IS for Neumann boundaries 90053cdbc3dSStefano Zampini 901785d1243SStefano Zampini Collective 902785d1243SStefano Zampini 903785d1243SStefano Zampini Input Parameters: 904785d1243SStefano Zampini . pc - the preconditioning context 905785d1243SStefano Zampini 906785d1243SStefano Zampini Output Parameters: 907785d1243SStefano Zampini . NeumannBoundaries - index set defining the Neumann boundaries 908785d1243SStefano Zampini 909785d1243SStefano Zampini Level: intermediate 910785d1243SStefano Zampini 9110f202f7eSStefano Zampini Notes: 9120f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetNeumannBoundaries 913785d1243SStefano Zampini 914785d1243SStefano Zampini .seealso: PCBDDC 915785d1243SStefano Zampini @*/ 916785d1243SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 917785d1243SStefano Zampini { 918785d1243SStefano Zampini PetscErrorCode ierr; 919785d1243SStefano Zampini 920785d1243SStefano Zampini PetscFunctionBegin; 921785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 922785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 923785d1243SStefano Zampini PetscFunctionReturn(0); 924785d1243SStefano Zampini } 925785d1243SStefano Zampini 926785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries) 927785d1243SStefano Zampini { 928785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 929785d1243SStefano Zampini 930785d1243SStefano Zampini PetscFunctionBegin; 931785d1243SStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundariesLocal; 932785d1243SStefano Zampini PetscFunctionReturn(0); 933785d1243SStefano Zampini } 934785d1243SStefano Zampini 93553cdbc3dSStefano Zampini /*@ 93682ba6b80SStefano Zampini PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering) 93753cdbc3dSStefano Zampini 938785d1243SStefano Zampini Collective 93953cdbc3dSStefano Zampini 94053cdbc3dSStefano Zampini Input Parameters: 94128509bceSStefano Zampini . pc - the preconditioning context 94253cdbc3dSStefano Zampini 94353cdbc3dSStefano Zampini Output Parameters: 94428509bceSStefano Zampini . NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 94553cdbc3dSStefano Zampini 94653cdbc3dSStefano Zampini Level: intermediate 94753cdbc3dSStefano Zampini 94853cdbc3dSStefano Zampini Notes: 9490f202f7eSStefano 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). 9500f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 95153cdbc3dSStefano Zampini 95253cdbc3dSStefano Zampini .seealso: PCBDDC 95353cdbc3dSStefano Zampini @*/ 95482ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries) 95553cdbc3dSStefano Zampini { 95653cdbc3dSStefano Zampini PetscErrorCode ierr; 95753cdbc3dSStefano Zampini 95853cdbc3dSStefano Zampini PetscFunctionBegin; 95953cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 96082ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 9610c7d97c5SJed Brown PetscFunctionReturn(0); 9620c7d97c5SJed Brown } 9631e6b0712SBarry Smith 9641a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 96536e030ebSStefano Zampini { 96636e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 967da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 96856282151SStefano Zampini PetscBool same_data = PETSC_FALSE; 969da1bb401SStefano Zampini PetscErrorCode ierr; 97036e030ebSStefano Zampini 97136e030ebSStefano Zampini PetscFunctionBegin; 9728687889aSStefano Zampini if (!nvtxs) { 97304194a47SStefano Zampini if (copymode == PETSC_OWN_POINTER) { 97404194a47SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 97504194a47SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 97604194a47SStefano Zampini } 9778687889aSStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 9788687889aSStefano Zampini PetscFunctionReturn(0); 9798687889aSStefano Zampini } 98066da6bd7Sstefano_zampini if (mat_graph->nvtxs == nvtxs && mat_graph->freecsr) { /* we own the data */ 98156282151SStefano Zampini if (mat_graph->xadj == xadj && mat_graph->adjncy == adjncy) same_data = PETSC_TRUE; 98256282151SStefano Zampini if (!same_data && mat_graph->xadj[nvtxs] == xadj[nvtxs]) { 9832d505d7fSStefano Zampini ierr = PetscMemcmp(xadj,mat_graph->xadj,(nvtxs+1)*sizeof(PetscInt),&same_data);CHKERRQ(ierr); 9842d505d7fSStefano Zampini if (same_data) { 9852d505d7fSStefano Zampini ierr = PetscMemcmp(adjncy,mat_graph->adjncy,xadj[nvtxs]*sizeof(PetscInt),&same_data);CHKERRQ(ierr); 9862d505d7fSStefano Zampini } 98756282151SStefano Zampini } 98856282151SStefano Zampini } 98956282151SStefano Zampini if (!same_data) { 990674ae819SStefano Zampini /* free old CSR */ 991674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 992674ae819SStefano Zampini /* get CSR into graph structure */ 993da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 994854ce69bSBarry Smith ierr = PetscMalloc1(nvtxs+1,&mat_graph->xadj);CHKERRQ(ierr); 995785e854fSJed Brown ierr = PetscMalloc1(xadj[nvtxs],&mat_graph->adjncy);CHKERRQ(ierr); 996674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 997674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 998a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 999da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 10001a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 10011a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 1002a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 1003a1dbd327SStefano Zampini } else if (copymode == PETSC_USE_POINTER) { 1004a1dbd327SStefano Zampini mat_graph->xadj = (PetscInt*)xadj; 1005a1dbd327SStefano Zampini mat_graph->adjncy = (PetscInt*)adjncy; 1006a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_FALSE; 1007e0fe2d75SToby Isaac } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %D",copymode); 1008575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 100956282151SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 101056282151SStefano Zampini } 101136e030ebSStefano Zampini PetscFunctionReturn(0); 101236e030ebSStefano Zampini } 10131e6b0712SBarry Smith 101436e030ebSStefano Zampini /*@ 101554fffbccSStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local degrees of freedom. 101636e030ebSStefano Zampini 101736e030ebSStefano Zampini Not collective 101836e030ebSStefano Zampini 101936e030ebSStefano Zampini Input Parameters: 102054fffbccSStefano Zampini + pc - the preconditioning context. 102154fffbccSStefano Zampini . nvtxs - number of local vertices of the graph (i.e., the number of local dofs). 102254fffbccSStefano Zampini . xadj, adjncy - the connectivity of the dofs in CSR format. 102354fffbccSStefano Zampini - copymode - supported modes are PETSC_COPY_VALUES, PETSC_USE_POINTER or PETSC_OWN_POINTER. 102436e030ebSStefano Zampini 102536e030ebSStefano Zampini Level: intermediate 102636e030ebSStefano Zampini 102795452b02SPatrick Sanan Notes: 102895452b02SPatrick Sanan A dof is considered connected with all local dofs if xadj[dof+1]-xadj[dof] == 1 and adjncy[xadj[dof]] is negative. 102936e030ebSStefano Zampini 103028509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode 103136e030ebSStefano Zampini @*/ 10321a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 103336e030ebSStefano Zampini { 1034575ad6abSStefano Zampini void (*f)(void) = 0; 103536e030ebSStefano Zampini PetscErrorCode ierr; 103636e030ebSStefano Zampini 103736e030ebSStefano Zampini PetscFunctionBegin; 103836e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 10398687889aSStefano Zampini if (nvtxs) { 1040674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 10411633d1f0SStefano Zampini if (xadj[nvtxs]) PetscValidIntPointer(adjncy,4); 10428687889aSStefano Zampini } 10431a83f524SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 1044575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 1045575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 1046575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 1047575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 1048575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 1049da1bb401SStefano Zampini } 105036e030ebSStefano Zampini PetscFunctionReturn(0); 105136e030ebSStefano Zampini } 10521e6b0712SBarry Smith 105363602bcaSStefano Zampini static PetscErrorCode PCBDDCSetDofsSplittingLocal_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 105463602bcaSStefano Zampini { 105563602bcaSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 105663602bcaSStefano Zampini PetscInt i; 105756282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 105863602bcaSStefano Zampini PetscErrorCode ierr; 105963602bcaSStefano Zampini 106063602bcaSStefano Zampini PetscFunctionBegin; 106156282151SStefano Zampini if (pcbddc->n_ISForDofsLocal == n_is) { 106256282151SStefano Zampini for (i=0;i<n_is;i++) { 106356282151SStefano Zampini PetscBool isequalt; 106456282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofsLocal[i],&isequalt);CHKERRQ(ierr); 106556282151SStefano Zampini if (!isequalt) break; 106656282151SStefano Zampini } 106756282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 106856282151SStefano Zampini } 106956282151SStefano Zampini for (i=0;i<n_is;i++) { 107056282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 107156282151SStefano Zampini } 107263602bcaSStefano Zampini /* Destroy ISes if they were already set */ 107363602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 107463602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 107563602bcaSStefano Zampini } 107663602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 107763602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 107863602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 107963602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 108063602bcaSStefano Zampini } 108163602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 108263602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 108363602bcaSStefano Zampini /* allocate space then set */ 1084d02579f5SStefano Zampini if (n_is) { 1085d02579f5SStefano Zampini ierr = PetscMalloc1(n_is,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1086d02579f5SStefano Zampini } 108763602bcaSStefano Zampini for (i=0;i<n_is;i++) { 108863602bcaSStefano Zampini pcbddc->ISForDofsLocal[i] = ISForDofs[i]; 108963602bcaSStefano Zampini } 109063602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = n_is; 109163602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 109256282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 109363602bcaSStefano Zampini PetscFunctionReturn(0); 109463602bcaSStefano Zampini } 109563602bcaSStefano Zampini 109663602bcaSStefano Zampini /*@ 109763602bcaSStefano Zampini PCBDDCSetDofsSplittingLocal - Set index sets defining fields of the local subdomain matrix 109863602bcaSStefano Zampini 109963602bcaSStefano Zampini Collective 110063602bcaSStefano Zampini 110163602bcaSStefano Zampini Input Parameters: 110263602bcaSStefano Zampini + pc - the preconditioning context 11030f202f7eSStefano Zampini . n_is - number of index sets defining the fields 11040f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in local ordering 110563602bcaSStefano Zampini 110663602bcaSStefano Zampini Level: intermediate 110763602bcaSStefano Zampini 11080f202f7eSStefano Zampini Notes: 11090f202f7eSStefano Zampini n_is should be the same among processes. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 111063602bcaSStefano Zampini 111163602bcaSStefano Zampini .seealso: PCBDDC 111263602bcaSStefano Zampini @*/ 111363602bcaSStefano Zampini PetscErrorCode PCBDDCSetDofsSplittingLocal(PC pc,PetscInt n_is, IS ISForDofs[]) 111463602bcaSStefano Zampini { 111563602bcaSStefano Zampini PetscInt i; 111663602bcaSStefano Zampini PetscErrorCode ierr; 111763602bcaSStefano Zampini 111863602bcaSStefano Zampini PetscFunctionBegin; 111963602bcaSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 112063602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 112163602bcaSStefano Zampini for (i=0;i<n_is;i++) { 112263602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 112363602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 112463602bcaSStefano Zampini } 1125e71e7a71SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplittingLocal_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 112663602bcaSStefano Zampini PetscFunctionReturn(0); 112763602bcaSStefano Zampini } 112863602bcaSStefano Zampini 11299c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 11309c0446d6SStefano Zampini { 11319c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 11329c0446d6SStefano Zampini PetscInt i; 113356282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 11349c0446d6SStefano Zampini PetscErrorCode ierr; 11359c0446d6SStefano Zampini 11369c0446d6SStefano Zampini PetscFunctionBegin; 113756282151SStefano Zampini if (pcbddc->n_ISForDofs == n_is) { 113856282151SStefano Zampini for (i=0;i<n_is;i++) { 113956282151SStefano Zampini PetscBool isequalt; 114056282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofs[i],&isequalt);CHKERRQ(ierr); 114156282151SStefano Zampini if (!isequalt) break; 114256282151SStefano Zampini } 114356282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 114456282151SStefano Zampini } 114556282151SStefano Zampini for (i=0;i<n_is;i++) { 114656282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 114756282151SStefano Zampini } 1148da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 11499c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 11509c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 11519c0446d6SStefano Zampini } 1152d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 115363602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 115463602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 115563602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 115663602bcaSStefano Zampini } 115763602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 115863602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 1159da1bb401SStefano Zampini /* allocate space then set */ 1160d02579f5SStefano Zampini if (n_is) { 1161785e854fSJed Brown ierr = PetscMalloc1(n_is,&pcbddc->ISForDofs);CHKERRQ(ierr); 1162d02579f5SStefano Zampini } 11639c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 1164da1bb401SStefano Zampini pcbddc->ISForDofs[i] = ISForDofs[i]; 11659c0446d6SStefano Zampini } 11669c0446d6SStefano Zampini pcbddc->n_ISForDofs = n_is; 116763602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 116856282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 11699c0446d6SStefano Zampini PetscFunctionReturn(0); 11709c0446d6SStefano Zampini } 11711e6b0712SBarry Smith 11729c0446d6SStefano Zampini /*@ 117363602bcaSStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of the global matrix 11749c0446d6SStefano Zampini 117563602bcaSStefano Zampini Collective 11769c0446d6SStefano Zampini 11779c0446d6SStefano Zampini Input Parameters: 11789c0446d6SStefano Zampini + pc - the preconditioning context 11790f202f7eSStefano Zampini . n_is - number of index sets defining the fields 11800f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in global ordering 11819c0446d6SStefano Zampini 11829c0446d6SStefano Zampini Level: intermediate 11839c0446d6SStefano Zampini 11840f202f7eSStefano Zampini Notes: 11850f202f7eSStefano Zampini Any process can list any global node. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 11869c0446d6SStefano Zampini 11879c0446d6SStefano Zampini .seealso: PCBDDC 11889c0446d6SStefano Zampini @*/ 11899c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 11909c0446d6SStefano Zampini { 11912b510759SStefano Zampini PetscInt i; 11929c0446d6SStefano Zampini PetscErrorCode ierr; 11939c0446d6SStefano Zampini 11949c0446d6SStefano Zampini PetscFunctionBegin; 11959c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 119663602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 11972b510759SStefano Zampini for (i=0;i<n_is;i++) { 119863602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 1199a011d5a7Sstefano_zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 12002b510759SStefano Zampini } 12019c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 12029c0446d6SStefano Zampini PetscFunctionReturn(0); 12039c0446d6SStefano Zampini } 1204906d46d4SStefano Zampini 1205534831adSStefano Zampini /* 1206534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 1207534831adSStefano Zampini guess if a transformation of basis approach has been selected. 12089c0446d6SStefano Zampini 1209534831adSStefano Zampini Input Parameter: 1210534831adSStefano Zampini + pc - the preconditioner contex 1211534831adSStefano Zampini 1212534831adSStefano Zampini Application Interface Routine: PCPreSolve() 1213534831adSStefano Zampini 1214534831adSStefano Zampini Notes: 1215534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 1216534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1217534831adSStefano Zampini */ 1218534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1219534831adSStefano Zampini { 1220534831adSStefano Zampini PetscErrorCode ierr; 1221534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1222534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 12233972b0daSStefano Zampini Vec used_vec; 122427b6a85dSStefano Zampini PetscBool save_rhs = PETSC_TRUE, benign_correction_computed; 1225534831adSStefano Zampini 1226534831adSStefano Zampini PetscFunctionBegin; 12271f4df5f7SStefano Zampini /* if we are working with CG, one dirichlet solve can be avoided during Krylov iterations */ 122885c4d303SStefano Zampini if (ksp) { 12291f4df5f7SStefano Zampini PetscBool iscg, isgroppcg, ispipecg, ispipecgrr; 123085c4d303SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr); 123127b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPGROPPCG,&isgroppcg);CHKERRQ(ierr); 123227b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECG,&ispipecg);CHKERRQ(ierr); 1233f94e96cbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECGRR,&ispipecgrr);CHKERRQ(ierr); 12341f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static || (!iscg && !isgroppcg && !ispipecg && !ispipecgrr)) { 123585c4d303SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 123685c4d303SStefano Zampini } 123785c4d303SStefano Zampini } 1238fc17d649SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static) { 1239fc17d649SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 1240fc17d649SStefano Zampini } 12411f4df5f7SStefano Zampini 124285c4d303SStefano Zampini /* Creates parallel work vectors used in presolve */ 124362a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 124462a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 124562a6ff1dSStefano Zampini } 124662a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 124762a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 124862a6ff1dSStefano Zampini } 12498d00608fSStefano Zampini 125027b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_FALSE; 12513972b0daSStefano Zampini if (x) { 12523972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 12533972b0daSStefano Zampini used_vec = x; 12548d00608fSStefano Zampini } else { /* it can only happen when calling PCBDDCMatFETIDPGetRHS */ 12553972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 12563972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 12573972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 125827b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 1259266e20e9SStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 1260266e20e9SStefano Zampini save_rhs = PETSC_FALSE; 1261266e20e9SStefano Zampini pcbddc->eliminate_dirdofs = PETSC_TRUE; 12623972b0daSStefano Zampini } 12638efcfb23SStefano Zampini 12648efcfb23SStefano Zampini /* hack into ksp data structure since PCPreSolve comes earlier than setting to zero the guess in src/ksp/ksp/interface/itfunc.c */ 12653972b0daSStefano Zampini if (ksp) { 1266a0cb1b98SStefano Zampini /* store the flag for the initial guess since it will be restored back during PCPostSolve_BDDC */ 12678efcfb23SStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 12688efcfb23SStefano Zampini if (!pcbddc->ksp_guess_nonzero) { 12693972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 12703972b0daSStefano Zampini } 12713972b0daSStefano Zampini } 12723308cffdSStefano Zampini 12738d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 12743972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 127570c64980SStefano Zampini if (rhs && pcbddc->eliminate_dirdofs) { 12763975b054SStefano Zampini IS dirIS = NULL; 12773975b054SStefano Zampini 1278a07ea27aSStefano Zampini /* DirichletBoundariesLocal may not be consistent among neighbours; gets a dirichlet dofs IS from graph (may be cached) */ 12793975b054SStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 12803975b054SStefano Zampini if (dirIS) { 1281906d46d4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1282785d1243SStefano Zampini PetscInt dirsize,i,*is_indices; 12832b095fd8SStefano Zampini PetscScalar *array_x; 12842b095fd8SStefano Zampini const PetscScalar *array_diagonal; 1285785d1243SStefano Zampini 12863972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 12873972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 1288e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1289e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1290e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1291e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 129282ba6b80SStefano Zampini ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr); 12933972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 12942b095fd8SStefano Zampini ierr = VecGetArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 12953972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 12962fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 12973972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 12982b095fd8SStefano Zampini ierr = VecRestoreArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 12993972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 1300e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1301e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13028d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 13031b968477SStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 13048efcfb23SStefano Zampini } 1305a07ea27aSStefano Zampini } 1306b76ba322SStefano Zampini 13078efcfb23SStefano Zampini /* remove the computed solution or the initial guess from the rhs */ 13088d00608fSStefano Zampini if (pcbddc->rhs_change || (ksp && pcbddc->ksp_guess_nonzero) ) { 130927b6a85dSStefano Zampini /* save the original rhs */ 131027b6a85dSStefano Zampini if (save_rhs) { 131127b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 131227b6a85dSStefano Zampini save_rhs = PETSC_FALSE; 13138d00608fSStefano Zampini } 13148d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 13153972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 131627b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,used_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 13173972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 13188efcfb23SStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 131927b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 13207acc28cbSStefano Zampini if (ksp) { 13217acc28cbSStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_FALSE);CHKERRQ(ierr); 13227acc28cbSStefano Zampini } 13233308cffdSStefano Zampini } 13248efcfb23SStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 1325b76ba322SStefano Zampini 1326fc17d649SStefano Zampini /* compute initial vector in benign space if needed 132727b6a85dSStefano Zampini and remove non-benign solution from the rhs */ 132827b6a85dSStefano Zampini benign_correction_computed = PETSC_FALSE; 1329c69e9cc1SStefano Zampini if (rhs && pcbddc->benign_compute_correction && (pcbddc->benign_have_null || pcbddc->benign_apply_coarse_only)) { 13301f4df5f7SStefano Zampini /* compute u^*_h using ideas similar to those in Xuemin Tu's PhD thesis (see Section 4.8.1) 13311f4df5f7SStefano Zampini Recursively apply BDDC in the multilevel case */ 13320369aaf7SStefano Zampini if (!pcbddc->benign_vec) { 13330369aaf7SStefano Zampini ierr = VecDuplicate(rhs,&pcbddc->benign_vec);CHKERRQ(ierr); 13340369aaf7SStefano Zampini } 1335c69e9cc1SStefano Zampini /* keep applying coarse solver unless we no longer have benign subdomains */ 1336c69e9cc1SStefano Zampini pcbddc->benign_apply_coarse_only = pcbddc->benign_have_null ? PETSC_TRUE : PETSC_FALSE; 133727b6a85dSStefano Zampini if (!pcbddc->benign_skip_correction) { 13381dd7afcfSStefano Zampini ierr = PCApply_BDDC(pc,rhs,pcbddc->benign_vec);CHKERRQ(ierr); 13393bca92a6SStefano Zampini benign_correction_computed = PETSC_TRUE; 13401f4df5f7SStefano Zampini if (pcbddc->temp_solution_used) { 13411f4df5f7SStefano Zampini ierr = VecAXPY(pcbddc->temp_solution,1.0,pcbddc->benign_vec);CHKERRQ(ierr); 13421f4df5f7SStefano Zampini } 13431f4df5f7SStefano Zampini ierr = VecScale(pcbddc->benign_vec,-1.0);CHKERRQ(ierr); 134427b6a85dSStefano Zampini /* store the original rhs if not done earlier */ 134527b6a85dSStefano Zampini if (save_rhs) { 134627b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 134792e3dcfbSStefano Zampini } 134827b6a85dSStefano Zampini if (pcbddc->rhs_change) { 13490369aaf7SStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,rhs,rhs);CHKERRQ(ierr); 135027b6a85dSStefano Zampini } else { 135127b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 135227b6a85dSStefano Zampini } 13530369aaf7SStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 135427b6a85dSStefano Zampini } 135527b6a85dSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_FALSE; 13560369aaf7SStefano Zampini } 13572d4c4fecSStefano Zampini 13582d4c4fecSStefano Zampini /* dbg output */ 1359a198735bSStefano Zampini if (pcbddc->dbg_flag && benign_correction_computed) { 13601f4df5f7SStefano Zampini Vec v; 1361c69e9cc1SStefano Zampini 13621f4df5f7SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&v);CHKERRQ(ierr); 1363c69e9cc1SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 13641f4df5f7SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,v);CHKERRQ(ierr); 1365c69e9cc1SStefano Zampini } else { 1366c69e9cc1SStefano Zampini ierr = VecCopy(rhs,v);CHKERRQ(ierr); 1367c69e9cc1SStefano Zampini } 13681f4df5f7SStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,v,PETSC_TRUE);CHKERRQ(ierr); 1369e0fe2d75SToby Isaac ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"LEVEL %D: is the correction benign?\n",pcbddc->current_level);CHKERRQ(ierr); 1370c69e9cc1SStefano Zampini ierr = PetscScalarView(pcbddc->benign_n,pcbddc->benign_p0,pcbddc->dbg_viewer);CHKERRQ(ierr); 1371c69e9cc1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 13721f4df5f7SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 13731f4df5f7SStefano Zampini } 13740369aaf7SStefano Zampini 13750369aaf7SStefano Zampini /* set initial guess if using PCG */ 13768ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 13770369aaf7SStefano Zampini if (x && pcbddc->use_exact_dirichlet_trick) { 13780369aaf7SStefano Zampini ierr = VecSet(x,0.0);CHKERRQ(ierr); 13791dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 138027b6a85dSStefano Zampini if (benign_correction_computed) { /* we have already saved the changed rhs */ 13811dd7afcfSStefano Zampini ierr = VecLockPop(pcis->vec1_global);CHKERRQ(ierr); 13821dd7afcfSStefano Zampini } else { 13831dd7afcfSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,pcis->vec1_global);CHKERRQ(ierr); 13841dd7afcfSStefano Zampini } 13851dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13861dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13871dd7afcfSStefano Zampini } else { 13880369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13890369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13901dd7afcfSStefano Zampini } 13910369aaf7SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 13921dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 13931dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.);CHKERRQ(ierr); 13941dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13951dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13961dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x);CHKERRQ(ierr); 13971dd7afcfSStefano Zampini } else { 13980369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13990369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 14001dd7afcfSStefano Zampini } 14010369aaf7SStefano Zampini if (ksp) { 14020369aaf7SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 14030369aaf7SStefano Zampini } 14048ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_TRUE; 1405266e20e9SStefano Zampini } else if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior && benign_correction_computed && pcbddc->use_exact_dirichlet_trick) { 1406266e20e9SStefano Zampini ierr = VecLockPop(pcis->vec1_global);CHKERRQ(ierr); 14070369aaf7SStefano Zampini } 1408534831adSStefano Zampini PetscFunctionReturn(0); 1409534831adSStefano Zampini } 1410906d46d4SStefano Zampini 1411534831adSStefano Zampini /* 1412534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 1413534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 1414534831adSStefano Zampini 1415534831adSStefano Zampini Input Parameter: 1416534831adSStefano Zampini + pc - the preconditioner contex 1417534831adSStefano Zampini 1418534831adSStefano Zampini Application Interface Routine: PCPostSolve() 1419534831adSStefano Zampini 1420534831adSStefano Zampini Notes: 1421534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 1422534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1423534831adSStefano Zampini */ 1424534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1425534831adSStefano Zampini { 1426534831adSStefano Zampini PetscErrorCode ierr; 1427534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1428534831adSStefano Zampini 1429534831adSStefano Zampini PetscFunctionBegin; 14303972b0daSStefano Zampini /* add solution removed in presolve */ 14316bcfc461SStefano Zampini if (x && pcbddc->rhs_change) { 143227b6a85dSStefano Zampini if (pcbddc->temp_solution_used) { 14333425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 1434af140850Sstefano_zampini } else if (pcbddc->benign_compute_correction && pcbddc->benign_vec) { 143527b6a85dSStefano Zampini ierr = VecAXPY(x,-1.0,pcbddc->benign_vec);CHKERRQ(ierr); 14363425bc38SStefano Zampini } 1437af140850Sstefano_zampini /* restore to original state (not for FETI-DP) */ 1438af140850Sstefano_zampini if (ksp) pcbddc->temp_solution_used = PETSC_FALSE; 143927b6a85dSStefano Zampini } 144027b6a85dSStefano Zampini 1441266e20e9SStefano Zampini /* restore rhs to its original state (not needed for FETI-DP) */ 14428d00608fSStefano Zampini if (rhs && pcbddc->rhs_change) { 144327b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 14448d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 1445af140850Sstefano_zampini } 14468efcfb23SStefano Zampini /* restore ksp guess state */ 14478efcfb23SStefano Zampini if (ksp) { 14488efcfb23SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 14498ae0ca82SStefano Zampini /* reset flag for exact dirichlet trick */ 14508ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 1451af140850Sstefano_zampini } 1452534831adSStefano Zampini PetscFunctionReturn(0); 1453534831adSStefano Zampini } 1454af140850Sstefano_zampini 14550c7d97c5SJed Brown /* 14560c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 14570c7d97c5SJed Brown by setting data structures and options. 14580c7d97c5SJed Brown 14590c7d97c5SJed Brown Input Parameter: 146053cdbc3dSStefano Zampini + pc - the preconditioner context 14610c7d97c5SJed Brown 14620c7d97c5SJed Brown Application Interface Routine: PCSetUp() 14630c7d97c5SJed Brown 14640c7d97c5SJed Brown Notes: 14650c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 14660c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 14670c7d97c5SJed Brown */ 146853cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 14690c7d97c5SJed Brown { 14700c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1471c703fcc7SStefano Zampini PCBDDCSubSchurs sub_schurs; 14725e8657edSStefano Zampini Mat_IS* matis; 147308122e43SStefano Zampini MatNullSpace nearnullspace; 147435509ce9Sstefano_zampini Mat lA; 147535509ce9Sstefano_zampini IS lP,zerodiag = NULL; 147691e8d312SStefano Zampini PetscInt nrows,ncols; 147786bfa4cfSStefano Zampini PetscMPIInt size; 1478c703fcc7SStefano Zampini PetscBool computesubschurs; 14798de1fae6SStefano Zampini PetscBool computeconstraintsmatrix; 14805e8657edSStefano Zampini PetscBool new_nearnullspace_provided,ismatis; 1481c703fcc7SStefano Zampini PetscErrorCode ierr; 14820c7d97c5SJed Brown 14830c7d97c5SJed Brown PetscFunctionBegin; 14845e8657edSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATIS,&ismatis);CHKERRQ(ierr); 14856c4ed002SBarry Smith if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner requires matrix of type MATIS"); 148691e8d312SStefano Zampini ierr = MatGetSize(pc->pmat,&nrows,&ncols);CHKERRQ(ierr); 14876c4ed002SBarry Smith if (nrows != ncols) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PCBDDC preconditioner requires a square preconditioning matrix"); 148886bfa4cfSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 148986bfa4cfSStefano Zampini 14905e8657edSStefano Zampini matis = (Mat_IS*)pc->pmat->data; 1491f4ddd8eeSStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other future nonoverlapping preconditioners */ 14923b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 149371582508SStefano Zampini Also, BDDC builds its own KSP for the Dirichlet problem */ 1494a485753aSstefano_zampini if (!pc->setupcalled || pc->flag == DIFFERENT_NONZERO_PATTERN) pcbddc->recompute_topography = PETSC_TRUE; 1495c83e1ba7SStefano Zampini if (pcbddc->recompute_topography) { 1496c83e1ba7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 1497c83e1ba7SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1498c83e1ba7SStefano Zampini } else { 14998de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_FALSE; 1500c83e1ba7SStefano Zampini } 1501b087196eSStefano Zampini 1502b087196eSStefano Zampini /* check parameters' compatibility */ 1503b7ab4a40SStefano Zampini if (!pcbddc->use_deluxe_scaling) pcbddc->deluxe_zerorows = PETSC_FALSE; 1504bd2a564bSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_threshold[0] != 0.0 || pcbddc->adaptive_threshold[1] != 0.0); 150586bfa4cfSStefano Zampini pcbddc->use_deluxe_scaling = (PetscBool)(pcbddc->use_deluxe_scaling && size > 1); 150686bfa4cfSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_selection && size > 1); 1507bf3a8328SStefano Zampini pcbddc->adaptive_userdefined = (PetscBool)(pcbddc->adaptive_selection && pcbddc->adaptive_userdefined); 1508862806e4SStefano Zampini if (pcbddc->adaptive_selection) pcbddc->use_faces = PETSC_TRUE; 1509862806e4SStefano Zampini 15105a95e1ceSStefano Zampini computesubschurs = (PetscBool)(pcbddc->adaptive_selection || pcbddc->use_deluxe_scaling); 151116909a7fSStefano Zampini if (pcbddc->switch_static) { 151216909a7fSStefano Zampini PetscBool ismatis; 1513d9869140SStefano Zampini 151416909a7fSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->mat,MATIS,&ismatis);CHKERRQ(ierr); 151516909a7fSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"When the static switch is one, the iteration matrix should be of type MATIS"); 151616909a7fSStefano Zampini } 151716909a7fSStefano Zampini 151871582508SStefano Zampini /* activate all connected components if the netflux has been requested */ 1519bb05f991SStefano Zampini if (pcbddc->compute_nonetflux) { 1520bb05f991SStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 1521bb05f991SStefano Zampini pcbddc->use_edges = PETSC_TRUE; 1522bb05f991SStefano Zampini pcbddc->use_faces = PETSC_TRUE; 1523bb05f991SStefano Zampini } 1524bb05f991SStefano Zampini 1525f4ddd8eeSStefano Zampini /* Get stdout for dbg */ 152670cf5478SStefano Zampini if (pcbddc->dbg_flag) { 152770cf5478SStefano Zampini if (!pcbddc->dbg_viewer) { 152858a03d70SStefano Zampini pcbddc->dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pc)); 1529f4ddd8eeSStefano Zampini } 1530d9869140SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 153158a03d70SStefano Zampini ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1532f4ddd8eeSStefano Zampini } 1533f4ddd8eeSStefano Zampini 1534c703fcc7SStefano Zampini /* process topology information */ 153543371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Topology[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 153671582508SStefano Zampini if (pcbddc->recompute_topography) { 153771582508SStefano Zampini ierr = PCBDDCComputeLocalTopologyInfo(pc);CHKERRQ(ierr); 1538c703fcc7SStefano Zampini if (pcbddc->discretegradient) { 1539a13144ffSStefano Zampini ierr = PCBDDCNedelecSupport(pc);CHKERRQ(ierr); 1540a13144ffSStefano Zampini } 1541c703fcc7SStefano Zampini } 1542a13144ffSStefano Zampini 1543c703fcc7SStefano Zampini /* change basis if requested by the user */ 15445e8657edSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 15455e8657edSStefano Zampini /* use_change_of_basis flag is used to automatically compute a change of basis from constraints */ 15465e8657edSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 15475e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 15485e8657edSStefano Zampini } else { 1549b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 15505e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 15515e8657edSStefano Zampini pcbddc->local_mat = matis->A; 1552d16cbb6bSStefano Zampini } 1553d16cbb6bSStefano Zampini 15544f1b2e48SStefano Zampini /* 1555c703fcc7SStefano Zampini Compute change of basis on local pressures (aka zerodiag dofs) with the benign trick 15564f1b2e48SStefano Zampini This should come earlier then PCISSetUp for extracting the correct subdomain matrices 15574f1b2e48SStefano Zampini */ 15581dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 1559d16cbb6bSStefano Zampini if (pcbddc->benign_saddle_point) { 15609f47a83aSStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 15619f47a83aSStefano Zampini 156205b28244SStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->use_change_of_basis || !computesubschurs) pcbddc->benign_change_explicit = PETSC_TRUE; 1563669cc0f4SStefano Zampini /* detect local saddle point and change the basis in pcbddc->local_mat (TODO: reuse case) */ 1564339f8db1SStefano Zampini ierr = PCBDDCBenignDetectSaddlePoint(pc,&zerodiag);CHKERRQ(ierr); 1565a3df083aSStefano Zampini /* pop B0 mat from local mat */ 1566c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 15671dd7afcfSStefano Zampini /* give pcis a hint to not reuse submatrices during PCISCreate */ 15681dd7afcfSStefano Zampini if (pc->flag == SAME_NONZERO_PATTERN && pcis->reusesubmatrices == PETSC_TRUE) { 15691dd7afcfSStefano Zampini if (pcbddc->benign_n && (pcbddc->benign_change_explicit || pcbddc->dbg_flag)) { 15701dd7afcfSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 15711dd7afcfSStefano Zampini } else { 1572a3df083aSStefano Zampini pcis->reusesubmatrices = PETSC_TRUE; 15731dd7afcfSStefano Zampini } 1574a3df083aSStefano Zampini } else { 15759f47a83aSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 1576674ae819SStefano Zampini } 1577a3df083aSStefano Zampini } 157827b6a85dSStefano Zampini 15798037d520SStefano Zampini /* propagate relevant information */ 158006a4e24aSStefano Zampini if (matis->A->symmetric_set) { 158106a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 158206a4e24aSStefano Zampini } 158306a4e24aSStefano Zampini if (matis->A->spd_set) { 158406a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SPD,matis->A->spd);CHKERRQ(ierr); 158506a4e24aSStefano Zampini } 1586e496cd5dSStefano Zampini 15875e8657edSStefano Zampini /* Set up all the "iterative substructuring" common block without computing solvers */ 15885e8657edSStefano Zampini { 15895e8657edSStefano Zampini Mat temp_mat; 15905e8657edSStefano Zampini 15915e8657edSStefano Zampini temp_mat = matis->A; 15925e8657edSStefano Zampini matis->A = pcbddc->local_mat; 1593d9869140SStefano Zampini ierr = PCISSetUp(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 15945e8657edSStefano Zampini pcbddc->local_mat = matis->A; 15955e8657edSStefano Zampini matis->A = temp_mat; 15965e8657edSStefano Zampini } 1597684f6988SStefano Zampini 159881d14e9dSStefano Zampini /* Analyze interface */ 159964ac59b8SStefano Zampini if (!pcbddc->graphanalyzed) { 1600674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 16018de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1602345ecf6cSStefano Zampini if (pcbddc->adaptive_selection && !pcbddc->use_deluxe_scaling && !pcbddc->mat_graph->twodim) { 16034247aa23Sstefano_zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot compute the adaptive primal space for a problem with 3D edges without deluxe scaling"); 1604345ecf6cSStefano Zampini } 1605a198735bSStefano Zampini if (pcbddc->compute_nonetflux) { 1606669cc0f4SStefano Zampini MatNullSpace nnfnnsp; 1607669cc0f4SStefano Zampini 160821ef3d20SStefano Zampini if (!pcbddc->divudotp) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Missing divudotp operator"); 16098ae0ca82SStefano Zampini ierr = PCBDDCComputeNoNetFlux(pc->pmat,pcbddc->divudotp,pcbddc->divudotp_trans,pcbddc->divudotp_vl2l,pcbddc->mat_graph,&nnfnnsp);CHKERRQ(ierr); 161071582508SStefano Zampini /* TODO what if a nearnullspace is already attached? */ 16118037d520SStefano Zampini if (nnfnnsp) { 1612669cc0f4SStefano Zampini ierr = MatSetNearNullSpace(pc->pmat,nnfnnsp);CHKERRQ(ierr); 1613669cc0f4SStefano Zampini ierr = MatNullSpaceDestroy(&nnfnnsp);CHKERRQ(ierr); 1614669cc0f4SStefano Zampini } 1615674ae819SStefano Zampini } 16168037d520SStefano Zampini } 161743371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Topology[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 1618fb8d54d4SStefano Zampini 16195408967cSStefano Zampini /* check existence of a divergence free extension, i.e. 16205408967cSStefano Zampini b(v_I,p_0) = 0 for all v_I (raise error if not). 16215408967cSStefano Zampini Also, check that PCBDDCBenignGetOrSetP0 works */ 1622ff1f7e73Sstefano_zampini if (pcbddc->benign_saddle_point && pcbddc->dbg_flag > 1) { 16235408967cSStefano Zampini ierr = PCBDDCBenignCheck(pc,zerodiag);CHKERRQ(ierr); 162409f581a4SStefano Zampini } 16254f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 162606f24817SStefano Zampini 1627b96c3477SStefano Zampini /* Setup local dirichlet solver ksp_D and sub_schurs solvers */ 1628c703fcc7SStefano Zampini if (computesubschurs && pcbddc->recompute_topography) { 162908122e43SStefano Zampini ierr = PCBDDCInitSubSchurs(pc);CHKERRQ(ierr); 1630b1b3d7a2SStefano Zampini } 16319d54b7f4SStefano Zampini /* SetUp Scaling operator (scaling matrices could be needed in SubSchursSetUp)*/ 16329d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) { 16339d54b7f4SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 16349d54b7f4SStefano Zampini } 1635c703fcc7SStefano Zampini 1636c703fcc7SStefano Zampini /* finish setup solvers and do adaptive selection of constraints */ 1637b334f244SStefano Zampini sub_schurs = pcbddc->sub_schurs; 1638b334f244SStefano Zampini if (sub_schurs && sub_schurs->schur_explicit) { 16392070dbb6SStefano Zampini if (computesubschurs) { 164008122e43SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 16412070dbb6SStefano Zampini } 1642d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 1643d5574798SStefano Zampini } else { 1644d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 16452070dbb6SStefano Zampini if (computesubschurs) { 1646d5574798SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 1647d5574798SStefano Zampini } 16482070dbb6SStefano Zampini } 164908122e43SStefano Zampini if (pcbddc->adaptive_selection) { 165008122e43SStefano Zampini ierr = PCBDDCAdaptiveSelection(pc);CHKERRQ(ierr); 16518de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1652b7eb3628SStefano Zampini } 1653684f6988SStefano Zampini 1654f4ddd8eeSStefano Zampini /* infer if NullSpace object attached to Mat via MatSetNearNullSpace has changed */ 1655fb8d54d4SStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1656f4ddd8eeSStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullspace);CHKERRQ(ierr); 1657f4ddd8eeSStefano Zampini if (pcbddc->onearnullspace) { /* already used nearnullspace */ 1658f4ddd8eeSStefano Zampini if (!nearnullspace) { /* near null space attached to mat has been destroyed */ 1659f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1660f4ddd8eeSStefano Zampini } else { 1661f4ddd8eeSStefano Zampini /* determine if the two nullspaces are different (should be lightweight) */ 1662f4ddd8eeSStefano Zampini if (nearnullspace != pcbddc->onearnullspace) { 1663f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1664165b64e2SStefano Zampini } else { /* maybe the user has changed the content of the nearnullspace so check vectors ObjectStateId */ 1665f4ddd8eeSStefano Zampini PetscInt i; 1666165b64e2SStefano Zampini const Vec *nearnullvecs; 1667165b64e2SStefano Zampini PetscObjectState state; 1668165b64e2SStefano Zampini PetscInt nnsp_size; 1669165b64e2SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullspace,NULL,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1670f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1671f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&state);CHKERRQ(ierr); 1672165b64e2SStefano Zampini if (pcbddc->onearnullvecs_state[i] != state) { 1673f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1674f4ddd8eeSStefano Zampini break; 1675f4ddd8eeSStefano Zampini } 1676f4ddd8eeSStefano Zampini } 1677f4ddd8eeSStefano Zampini } 1678f4ddd8eeSStefano Zampini } 1679f4ddd8eeSStefano Zampini } else { 1680f4ddd8eeSStefano Zampini if (!nearnullspace) { /* both nearnullspaces are null */ 1681f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1682f4ddd8eeSStefano Zampini } else { /* nearnullspace attached later */ 1683f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1684f4ddd8eeSStefano Zampini } 1685f4ddd8eeSStefano Zampini } 1686f4ddd8eeSStefano Zampini 1687f4ddd8eeSStefano Zampini /* Setup constraints and related work vectors */ 1688727cdba6SStefano Zampini /* reset primal space flags */ 168943371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_LocalWork[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 1690f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 1691727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 16928de1fae6SStefano Zampini if (computeconstraintsmatrix || new_nearnullspace_provided) { 1693727cdba6SStefano Zampini /* It also sets the primal space flags */ 1694674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 16959543d0ffSStefano Zampini } 1696e7b262bdSStefano Zampini /* Allocate needed local vectors (which depends on quantities defined during ConstraintsSetUp) */ 1697f4ddd8eeSStefano Zampini ierr = PCBDDCSetUpLocalWorkVectors(pc);CHKERRQ(ierr); 16985e8657edSStefano Zampini 16995e8657edSStefano Zampini if (pcbddc->use_change_of_basis) { 17005e8657edSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 17015e8657edSStefano Zampini 17025e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 17034f1b2e48SStefano Zampini if (pcbddc->benign_change) { 17041dd7afcfSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 1705c263805aSStefano Zampini /* pop B0 from pcbddc->local_mat */ 1706c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 1707c263805aSStefano Zampini } 17085e8657edSStefano Zampini /* get submatrices */ 17095e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 17105e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 17115e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 17127dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 17137dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 17147dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 17153975b054SStefano Zampini /* set flag in pcis to not reuse submatrices during PCISCreate */ 17163975b054SStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 17179c6a02ceSStefano Zampini } else if (!pcbddc->user_ChangeOfBasisMatrix && !pcbddc->benign_change) { 1718b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 17195e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 17205e8657edSStefano Zampini pcbddc->local_mat = matis->A; 17215e8657edSStefano Zampini } 172235509ce9Sstefano_zampini 172335509ce9Sstefano_zampini /* interface pressure block row for B_C */ 172435509ce9Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lP" ,(PetscObject*)&lP);CHKERRQ(ierr); 172535509ce9Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject*)&lA);CHKERRQ(ierr); 172635509ce9Sstefano_zampini if (lA && lP) { 172735509ce9Sstefano_zampini PC_IS* pcis = (PC_IS*)pc->data; 172835509ce9Sstefano_zampini Mat B_BI,B_BB,Bt_BI,Bt_BB; 172935509ce9Sstefano_zampini PetscBool issym; 173035509ce9Sstefano_zampini ierr = MatIsSymmetric(lA,PETSC_SMALL,&issym);CHKERRQ(ierr); 17316cc1294bSstefano_zampini if (issym) { 17327dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_I_local,MAT_INITIAL_MATRIX,&B_BI);CHKERRQ(ierr); 17337dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_B_local,MAT_INITIAL_MATRIX,&B_BB);CHKERRQ(ierr); 173435509ce9Sstefano_zampini ierr = MatCreateTranspose(B_BI,&Bt_BI);CHKERRQ(ierr); 173535509ce9Sstefano_zampini ierr = MatCreateTranspose(B_BB,&Bt_BB);CHKERRQ(ierr); 173635509ce9Sstefano_zampini } else { 17377dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_I_local,MAT_INITIAL_MATRIX,&B_BI);CHKERRQ(ierr); 17387dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_B_local,MAT_INITIAL_MATRIX,&B_BB);CHKERRQ(ierr); 17397dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,pcis->is_I_local,lP,MAT_INITIAL_MATRIX,&Bt_BI);CHKERRQ(ierr); 17407dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,pcis->is_B_local,lP,MAT_INITIAL_MATRIX,&Bt_BB);CHKERRQ(ierr); 174135509ce9Sstefano_zampini } 174235509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_B_BI",(PetscObject)B_BI);CHKERRQ(ierr); 174335509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_B_BB",(PetscObject)B_BB);CHKERRQ(ierr); 174435509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_Bt_BI",(PetscObject)Bt_BI);CHKERRQ(ierr); 174535509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_Bt_BB",(PetscObject)Bt_BB);CHKERRQ(ierr); 174635509ce9Sstefano_zampini ierr = MatDestroy(&B_BI);CHKERRQ(ierr); 174735509ce9Sstefano_zampini ierr = MatDestroy(&B_BB);CHKERRQ(ierr); 174835509ce9Sstefano_zampini ierr = MatDestroy(&Bt_BI);CHKERRQ(ierr); 174935509ce9Sstefano_zampini ierr = MatDestroy(&Bt_BB);CHKERRQ(ierr); 175035509ce9Sstefano_zampini } 175143371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_LocalWork[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 175235509ce9Sstefano_zampini 1753b96c3477SStefano Zampini /* SetUp coarse and local Neumann solvers */ 175499cc7994SStefano Zampini ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr); 1755b96c3477SStefano Zampini /* SetUp Scaling operator */ 17569d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1757674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 17580c7d97c5SJed Brown } 1759c703fcc7SStefano Zampini 17601dd7afcfSStefano Zampini /* mark topography as done */ 176156282151SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 17620369aaf7SStefano Zampini 17631dd7afcfSStefano Zampini /* wrap pcis->A_IB and pcis->A_BI if we did not change explicitly the variables on the pressures */ 17641dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_FALSE);CHKERRQ(ierr); 17651dd7afcfSStefano Zampini 176658a03d70SStefano Zampini if (pcbddc->dbg_flag) { 176758a03d70SStefano Zampini ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1768d9869140SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 17692b510759SStefano Zampini } 17700c7d97c5SJed Brown PetscFunctionReturn(0); 17710c7d97c5SJed Brown } 17720c7d97c5SJed Brown 17730c7d97c5SJed Brown /* 177450efa1b5SStefano Zampini PCApply_BDDC - Applies the BDDC operator to a vector. 17750c7d97c5SJed Brown 17760c7d97c5SJed Brown Input Parameters: 17770f202f7eSStefano Zampini + pc - the preconditioner context 17780f202f7eSStefano Zampini - r - input vector (global) 17790c7d97c5SJed Brown 17800c7d97c5SJed Brown Output Parameter: 17810c7d97c5SJed Brown . z - output vector (global) 17820c7d97c5SJed Brown 17830c7d97c5SJed Brown Application Interface Routine: PCApply() 17840c7d97c5SJed Brown */ 178553cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 17860c7d97c5SJed Brown { 17870c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 17880c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1789b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 17900c7d97c5SJed Brown PetscErrorCode ierr; 17913b03a366Sstefano_zampini const PetscScalar one = 1.0; 17923b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 17932617d88aSStefano Zampini const PetscScalar zero = 0.0; 17940c7d97c5SJed Brown 17950c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 17960c7d97c5SJed Brown NN interface preconditioner changed to BDDC 1797b097fa66SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static == PETSC_TRUE) */ 17980c7d97c5SJed Brown 17990c7d97c5SJed Brown PetscFunctionBegin; 1800f3d41395Sstefano_zampini ierr = PetscCitationsRegister(citation,&cited);CHKERRQ(ierr); 18011dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 18021dd7afcfSStefano Zampini Vec swap; 180327b6a85dSStefano Zampini 180427b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 18051dd7afcfSStefano Zampini swap = pcbddc->work_change; 18061dd7afcfSStefano Zampini pcbddc->work_change = r; 18071dd7afcfSStefano Zampini r = swap; 18081dd7afcfSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 18099cc2a9b1Sstefano_zampini if (pcbddc->benign_apply_coarse_only && pcbddc->use_exact_dirichlet_trick && pcbddc->change_interior) { 18101dd7afcfSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 18111dd7afcfSStefano Zampini ierr = VecLockPush(pcis->vec1_global);CHKERRQ(ierr); 18121dd7afcfSStefano Zampini } 18131dd7afcfSStefano Zampini } 181427b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 1815015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1816efc2fbd9SStefano Zampini } 18178ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 1818b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 18190c7d97c5SJed Brown /* First Dirichlet solve */ 18200c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18210c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18220c7d97c5SJed Brown /* 18230c7d97c5SJed Brown Assembling right hand side for BDDC operator 1824b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 1825674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 18260c7d97c5SJed Brown */ 1827b097fa66SStefano Zampini if (n_D) { 1828b097fa66SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 18290c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 183016909a7fSStefano Zampini if (pcbddc->switch_static) { 183116909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 183216909a7fSStefano Zampini 183316909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 183416909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 183516909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 183616909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 183716909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 183816909a7fSStefano Zampini } else { 183916909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 184016909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 184116909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 184216909a7fSStefano Zampini } 184316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 184416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 184516909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 184616909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 184716909a7fSStefano Zampini } else { 1848b097fa66SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 184916909a7fSStefano Zampini } 1850b097fa66SStefano Zampini } else { 1851b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1852b097fa66SStefano Zampini } 18530c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 18540c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1855674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 1856b76ba322SStefano Zampini } else { 18574fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 1858674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 1859b76ba322SStefano Zampini } 18604fee134fSStefano Zampini } 1861b76ba322SStefano Zampini 18622617d88aSStefano Zampini /* Apply interface preconditioner 18632617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1864dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 18652617d88aSStefano Zampini 1866674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 1867674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 18680c7d97c5SJed Brown 18693b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 18700c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18710c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1872b097fa66SStefano Zampini if (n_B) { 187316909a7fSStefano Zampini if (pcbddc->switch_static) { 187416909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 187516909a7fSStefano Zampini 187616909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 187716909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 187816909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 187916909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 188016909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 188116909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 188216909a7fSStefano Zampini } else { 188316909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 188416909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 188516909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 188616909a7fSStefano Zampini } 188716909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 188816909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 188916909a7fSStefano Zampini } else { 18900c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 189116909a7fSStefano Zampini } 189216909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 189316909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 189416909a7fSStefano Zampini 189516909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 189616909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 189716909a7fSStefano Zampini } else { 189816909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 189916909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 190016909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 190116909a7fSStefano Zampini } 1902b097fa66SStefano Zampini } 1903df187020SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 1904efc2fbd9SStefano Zampini 19058ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 1906b097fa66SStefano Zampini if (pcbddc->switch_static) { 1907b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 1908b097fa66SStefano Zampini } else { 1909b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 1910b097fa66SStefano Zampini } 19110c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19120c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1913b097fa66SStefano Zampini } else { 1914b097fa66SStefano Zampini if (pcbddc->switch_static) { 1915b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 1916b097fa66SStefano Zampini } else { 1917b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 1918b097fa66SStefano Zampini } 1919b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1920b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1921b097fa66SStefano Zampini } 192227b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 19231dd7afcfSStefano Zampini if (pcbddc->benign_apply_coarse_only) { 19241dd7afcfSStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 19251dd7afcfSStefano Zampini } 1926015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 1927efc2fbd9SStefano Zampini } 19281f4df5f7SStefano Zampini 19291dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1930f913dca9SStefano Zampini pcbddc->work_change = r; 19311dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 19321dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 19331dd7afcfSStefano Zampini } 19340c7d97c5SJed Brown PetscFunctionReturn(0); 19350c7d97c5SJed Brown } 193650efa1b5SStefano Zampini 193750efa1b5SStefano Zampini /* 193850efa1b5SStefano Zampini PCApplyTranspose_BDDC - Applies the transpose of the BDDC operator to a vector. 193950efa1b5SStefano Zampini 194050efa1b5SStefano Zampini Input Parameters: 19410f202f7eSStefano Zampini + pc - the preconditioner context 19420f202f7eSStefano Zampini - r - input vector (global) 194350efa1b5SStefano Zampini 194450efa1b5SStefano Zampini Output Parameter: 194550efa1b5SStefano Zampini . z - output vector (global) 194650efa1b5SStefano Zampini 194750efa1b5SStefano Zampini Application Interface Routine: PCApplyTranspose() 194850efa1b5SStefano Zampini */ 194950efa1b5SStefano Zampini PetscErrorCode PCApplyTranspose_BDDC(PC pc,Vec r,Vec z) 195050efa1b5SStefano Zampini { 195150efa1b5SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 195250efa1b5SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1953b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 195450efa1b5SStefano Zampini PetscErrorCode ierr; 195550efa1b5SStefano Zampini const PetscScalar one = 1.0; 195650efa1b5SStefano Zampini const PetscScalar m_one = -1.0; 195750efa1b5SStefano Zampini const PetscScalar zero = 0.0; 195850efa1b5SStefano Zampini 195950efa1b5SStefano Zampini PetscFunctionBegin; 1960f3d41395Sstefano_zampini ierr = PetscCitationsRegister(citation,&cited);CHKERRQ(ierr); 19611dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 19621dd7afcfSStefano Zampini Vec swap; 196327b6a85dSStefano Zampini 196427b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 19651dd7afcfSStefano Zampini swap = pcbddc->work_change; 19661dd7afcfSStefano Zampini pcbddc->work_change = r; 19671dd7afcfSStefano Zampini r = swap; 196827b6a85dSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 19698ae0ca82SStefano Zampini if (pcbddc->benign_apply_coarse_only && pcbddc->exact_dirichlet_trick_app && pcbddc->change_interior) { 197027b6a85dSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 197127b6a85dSStefano Zampini ierr = VecLockPush(pcis->vec1_global);CHKERRQ(ierr); 19721dd7afcfSStefano Zampini } 197327b6a85dSStefano Zampini } 197427b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 1975537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1976537c1cdfSStefano Zampini } 19778ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 1978b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 197950efa1b5SStefano Zampini /* First Dirichlet solve */ 198050efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 198150efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 198250efa1b5SStefano Zampini /* 198350efa1b5SStefano Zampini Assembling right hand side for BDDC operator 1984b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 198550efa1b5SStefano Zampini - pcis->vec1_B the interface part of the global vector z 198650efa1b5SStefano Zampini */ 1987b097fa66SStefano Zampini if (n_D) { 1988b097fa66SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 198950efa1b5SStefano Zampini ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 199016909a7fSStefano Zampini if (pcbddc->switch_static) { 199116909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 199216909a7fSStefano Zampini 199316909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 199416909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 199516909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 199616909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 199716909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 199816909a7fSStefano Zampini } else { 199916909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 200016909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 200116909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 200216909a7fSStefano Zampini } 200316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 200416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 200516909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 200616909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 200716909a7fSStefano Zampini } else { 2008b097fa66SStefano Zampini ierr = MatMultTranspose(pcis->A_IB,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 200916909a7fSStefano Zampini } 2010b097fa66SStefano Zampini } else { 2011b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 2012b097fa66SStefano Zampini } 201350efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 201450efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 201550efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 201650efa1b5SStefano Zampini } else { 201750efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 201850efa1b5SStefano Zampini } 201950efa1b5SStefano Zampini 202050efa1b5SStefano Zampini /* Apply interface preconditioner 202150efa1b5SStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 2022dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_TRUE);CHKERRQ(ierr); 202350efa1b5SStefano Zampini 202450efa1b5SStefano Zampini /* Apply transpose of partition of unity operator */ 202550efa1b5SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 202650efa1b5SStefano Zampini 202750efa1b5SStefano Zampini /* Second Dirichlet solve and assembling of output */ 202850efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 202950efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2030b097fa66SStefano Zampini if (n_B) { 203116909a7fSStefano Zampini if (pcbddc->switch_static) { 203216909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 203316909a7fSStefano Zampini 203416909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 203516909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 203616909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 203716909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 203816909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 203916909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 204016909a7fSStefano Zampini } else { 204116909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 204216909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 204316909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 204416909a7fSStefano Zampini } 204516909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 204616909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 204716909a7fSStefano Zampini } else { 204850efa1b5SStefano Zampini ierr = MatMultTranspose(pcis->A_BI,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 204916909a7fSStefano Zampini } 205016909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 205116909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 205216909a7fSStefano Zampini 205316909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 205416909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 205516909a7fSStefano Zampini } else { 205616909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 205716909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 205816909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 205916909a7fSStefano Zampini } 2060b097fa66SStefano Zampini } 2061b0147a47SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 20628ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2063b097fa66SStefano Zampini if (pcbddc->switch_static) { 2064b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 2065b097fa66SStefano Zampini } else { 2066b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 2067b097fa66SStefano Zampini } 206850efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 206950efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2070b097fa66SStefano Zampini } else { 2071b097fa66SStefano Zampini if (pcbddc->switch_static) { 2072b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 2073b097fa66SStefano Zampini } else { 2074b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 2075b097fa66SStefano Zampini } 2076b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2077b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2078b097fa66SStefano Zampini } 207927b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 2080537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 2081537c1cdfSStefano Zampini } 20821dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2083f913dca9SStefano Zampini pcbddc->work_change = r; 20841dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 20851dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 20861dd7afcfSStefano Zampini } 208750efa1b5SStefano Zampini PetscFunctionReturn(0); 208850efa1b5SStefano Zampini } 2089674ae819SStefano Zampini 20909326c5c6Sstefano_zampini PetscErrorCode PCReset_BDDC(PC pc) 2091da1bb401SStefano Zampini { 2092da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 20939326c5c6Sstefano_zampini PC_IS *pcis = (PC_IS*)pc->data; 20949326c5c6Sstefano_zampini KSP kspD,kspR,kspC; 2095da1bb401SStefano Zampini PetscErrorCode ierr; 2096da1bb401SStefano Zampini 2097da1bb401SStefano Zampini PetscFunctionBegin; 2098674ae819SStefano Zampini /* free BDDC custom data */ 2099674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 2100674ae819SStefano Zampini /* destroy objects related to topography */ 2101674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 210234a97f8cSStefano Zampini /* destroy objects for scaling operator */ 2103674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 2104674ae819SStefano Zampini /* free solvers stuff */ 2105674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 210662a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 210762a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 210862a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 21091dd7afcfSStefano Zampini /* free data created by PCIS */ 21101dd7afcfSStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 21119326c5c6Sstefano_zampini 21129326c5c6Sstefano_zampini /* restore defaults */ 21139326c5c6Sstefano_zampini kspD = pcbddc->ksp_D; 21149326c5c6Sstefano_zampini kspR = pcbddc->ksp_R; 21159326c5c6Sstefano_zampini kspC = pcbddc->coarse_ksp; 21169326c5c6Sstefano_zampini ierr = PetscMemzero(pc->data,sizeof(*pcbddc));CHKERRQ(ierr); 21179326c5c6Sstefano_zampini pcis->n_neigh = -1; 21189326c5c6Sstefano_zampini pcis->scaling_factor = 1.0; 21199326c5c6Sstefano_zampini pcis->reusesubmatrices = PETSC_TRUE; 21209326c5c6Sstefano_zampini pcbddc->use_local_adj = PETSC_TRUE; 21219326c5c6Sstefano_zampini pcbddc->use_vertices = PETSC_TRUE; 21229326c5c6Sstefano_zampini pcbddc->use_edges = PETSC_TRUE; 21239326c5c6Sstefano_zampini pcbddc->symmetric_primal = PETSC_TRUE; 21249326c5c6Sstefano_zampini pcbddc->vertex_size = 1; 21259326c5c6Sstefano_zampini pcbddc->recompute_topography = PETSC_TRUE; 21269326c5c6Sstefano_zampini pcbddc->coarse_size = -1; 21279326c5c6Sstefano_zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 21289326c5c6Sstefano_zampini pcbddc->coarsening_ratio = 8; 21299326c5c6Sstefano_zampini pcbddc->coarse_eqs_per_proc = 1; 21309326c5c6Sstefano_zampini pcbddc->benign_compute_correction = PETSC_TRUE; 21319326c5c6Sstefano_zampini pcbddc->nedfield = -1; 21329326c5c6Sstefano_zampini pcbddc->nedglobal = PETSC_TRUE; 21339326c5c6Sstefano_zampini pcbddc->graphmaxcount = PETSC_MAX_INT; 21349326c5c6Sstefano_zampini pcbddc->sub_schurs_layers = -1; 21359326c5c6Sstefano_zampini pcbddc->ksp_D = kspD; 21369326c5c6Sstefano_zampini pcbddc->ksp_R = kspR; 21379326c5c6Sstefano_zampini pcbddc->coarse_ksp = kspC; 21389326c5c6Sstefano_zampini PetscFunctionReturn(0); 21399326c5c6Sstefano_zampini } 21409326c5c6Sstefano_zampini 21419326c5c6Sstefano_zampini PetscErrorCode PCDestroy_BDDC(PC pc) 21429326c5c6Sstefano_zampini { 21439326c5c6Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 21449326c5c6Sstefano_zampini PetscErrorCode ierr; 21459326c5c6Sstefano_zampini 21469326c5c6Sstefano_zampini PetscFunctionBegin; 21479326c5c6Sstefano_zampini ierr = PCReset_BDDC(pc);CHKERRQ(ierr); 21489326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 21499326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 21509326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 2151a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",NULL);CHKERRQ(ierr); 2152a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",NULL);CHKERRQ(ierr); 2153906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",NULL);CHKERRQ(ierr); 2154674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 215530368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",NULL);CHKERRQ(ierr); 2156bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 21572b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr); 2158b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr); 21592b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr); 2160bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 216182ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2162bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 216382ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2164bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 216582ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2166bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 2167785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2168bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 216963602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",NULL);CHKERRQ(ierr); 2170bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 2171bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 2172bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 2173bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 2174a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",NULL);CHKERRQ(ierr); 2175ab8c8b98SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",NULL);CHKERRQ(ierr); 2176674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 2177da1bb401SStefano Zampini PetscFunctionReturn(0); 2178da1bb401SStefano Zampini } 21791e6b0712SBarry Smith 2180ab8c8b98SStefano Zampini static PetscErrorCode PCSetCoordinates_BDDC(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 2181ab8c8b98SStefano Zampini { 2182ab8c8b98SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2183ab8c8b98SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 2184ab8c8b98SStefano Zampini PetscErrorCode ierr; 2185ab8c8b98SStefano Zampini 2186ab8c8b98SStefano Zampini PetscFunctionBegin; 2187ab8c8b98SStefano Zampini ierr = PetscFree(mat_graph->coords);CHKERRQ(ierr); 2188ab8c8b98SStefano Zampini ierr = PetscMalloc1(nloc*dim,&mat_graph->coords);CHKERRQ(ierr); 2189ab8c8b98SStefano Zampini ierr = PetscMemcpy(mat_graph->coords,coords,nloc*dim*sizeof(PetscReal));CHKERRQ(ierr); 2190ab8c8b98SStefano Zampini mat_graph->cnloc = nloc; 2191ab8c8b98SStefano Zampini mat_graph->cdim = dim; 2192ab8c8b98SStefano Zampini mat_graph->cloc = PETSC_FALSE; 2193ab8c8b98SStefano Zampini PetscFunctionReturn(0); 2194ab8c8b98SStefano Zampini } 2195ab8c8b98SStefano Zampini 2196a06fd7f2SStefano Zampini static PetscErrorCode PCPreSolveChangeRHS_BDDC(PC pc, PetscBool* change) 2197a06fd7f2SStefano Zampini { 2198a06fd7f2SStefano Zampini PetscFunctionBegin; 2199a06fd7f2SStefano Zampini *change = PETSC_TRUE; 2200a06fd7f2SStefano Zampini PetscFunctionReturn(0); 2201a06fd7f2SStefano Zampini } 2202a06fd7f2SStefano Zampini 22033425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 22043425bc38SStefano Zampini { 2205674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 2206266e20e9SStefano Zampini Vec work; 22073425bc38SStefano Zampini PC_IS* pcis; 22083425bc38SStefano Zampini PC_BDDC* pcbddc; 22093425bc38SStefano Zampini PetscErrorCode ierr; 22100c7d97c5SJed Brown 22113425bc38SStefano Zampini PetscFunctionBegin; 22123425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 22133425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 22143425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 22153425bc38SStefano Zampini 2216229984c5Sstefano_zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 2217229984c5Sstefano_zampini /* copy rhs since we may change it during PCPreSolve_BDDC */ 2218229984c5Sstefano_zampini if (!pcbddc->original_rhs) { 2219229984c5Sstefano_zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 2220229984c5Sstefano_zampini } 22216cc1294bSstefano_zampini if (mat_ctx->rhs_flip) { 22226cc1294bSstefano_zampini ierr = VecPointwiseMult(pcbddc->original_rhs,standard_rhs,mat_ctx->rhs_flip);CHKERRQ(ierr); 22236cc1294bSstefano_zampini } else { 2224229984c5Sstefano_zampini ierr = VecCopy(standard_rhs,pcbddc->original_rhs);CHKERRQ(ierr); 22256cc1294bSstefano_zampini } 2226af140850Sstefano_zampini if (mat_ctx->g2g_p) { 2227229984c5Sstefano_zampini /* interface pressure rhs */ 2228022d8d2bSstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,fetidp_flux_rhs,pcbddc->original_rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2229022d8d2bSstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,fetidp_flux_rhs,pcbddc->original_rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2230229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,standard_rhs,fetidp_flux_rhs,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2231229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,standard_rhs,fetidp_flux_rhs,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22326cc1294bSstefano_zampini if (!mat_ctx->rhs_flip) { 2233229984c5Sstefano_zampini ierr = VecScale(fetidp_flux_rhs,-1.);CHKERRQ(ierr); 2234229984c5Sstefano_zampini } 22356cc1294bSstefano_zampini } 2236c08af4c6SStefano Zampini /* 2237c08af4c6SStefano Zampini change of basis for physical rhs if needed 2238c08af4c6SStefano Zampini It also changes the rhs in case of dirichlet boundaries 2239c08af4c6SStefano Zampini */ 22403738a8e6SStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,pcbddc->original_rhs,NULL);CHKERRQ(ierr); 2241fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 22423738a8e6SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcbddc->original_rhs,pcbddc->work_change);CHKERRQ(ierr); 22433738a8e6SStefano Zampini work = pcbddc->work_change; 2244fc17d649SStefano Zampini } else { 22453738a8e6SStefano Zampini work = pcbddc->original_rhs; 2246fc17d649SStefano Zampini } 22473425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 2248266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2249266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2250fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 2251fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 2252266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2253266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2254674ae819SStefano Zampini /* Apply partition of unity */ 22553425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 2256266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 22578eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 22583425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 22593425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 22603425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 22613425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 2262266e20e9SStefano Zampini ierr = VecSet(work,0.0);CHKERRQ(ierr); 2263266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2264266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2265266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 2266266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2267266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22683425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 22693425bc38SStefano Zampini } 22703425bc38SStefano Zampini /* BDDC rhs */ 22713425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 22728eeda7d8SStefano Zampini if (pcbddc->switch_static) { 22733425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 22743425bc38SStefano Zampini } 22753425bc38SStefano Zampini /* apply BDDC */ 2276229984c5Sstefano_zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 2277dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2278266e20e9SStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 2279229984c5Sstefano_zampini 22803425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 22813425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 22823425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22833425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2284229984c5Sstefano_zampini /* Add contribution to interface pressures */ 2285229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2286229984c5Sstefano_zampini ierr = MatMult(mat_ctx->B_BB,pcis->vec1_B,mat_ctx->vP);CHKERRQ(ierr); 2287229984c5Sstefano_zampini if (pcbddc->switch_static) { 2288229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->B_BI,pcis->vec1_D,mat_ctx->vP,mat_ctx->vP);CHKERRQ(ierr); 2289229984c5Sstefano_zampini } 2290229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->l2g_p,mat_ctx->vP,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2291229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->l2g_p,mat_ctx->vP,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2292229984c5Sstefano_zampini } 22933425bc38SStefano Zampini PetscFunctionReturn(0); 22943425bc38SStefano Zampini } 22951e6b0712SBarry Smith 22963425bc38SStefano Zampini /*@ 22970f202f7eSStefano Zampini PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETI-DP linear system using the physical right-hand side 22983425bc38SStefano Zampini 22993425bc38SStefano Zampini Collective 23003425bc38SStefano Zampini 23013425bc38SStefano Zampini Input Parameters: 23020f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix object obtained by a call to PCBDDCCreateFETIDPOperators 23030f202f7eSStefano Zampini - standard_rhs - the right-hand side of the original linear system 23043425bc38SStefano Zampini 23053425bc38SStefano Zampini Output Parameters: 23060f202f7eSStefano Zampini . fetidp_flux_rhs - the right-hand side for the FETI-DP linear system 23073425bc38SStefano Zampini 23083425bc38SStefano Zampini Level: developer 23093425bc38SStefano Zampini 23103425bc38SStefano Zampini Notes: 23113425bc38SStefano Zampini 23120f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetSolution 23133425bc38SStefano Zampini @*/ 23143425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 23153425bc38SStefano Zampini { 2316674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 23173425bc38SStefano Zampini PetscErrorCode ierr; 23183425bc38SStefano Zampini 23193425bc38SStefano Zampini PetscFunctionBegin; 2320266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2321266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_rhs,VEC_CLASSID,2); 2322266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_rhs,VEC_CLASSID,3); 23233425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2324163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 23253425bc38SStefano Zampini PetscFunctionReturn(0); 23263425bc38SStefano Zampini } 23271e6b0712SBarry Smith 23283425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 23293425bc38SStefano Zampini { 2330674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 23313425bc38SStefano Zampini PC_IS* pcis; 23323425bc38SStefano Zampini PC_BDDC* pcbddc; 23333425bc38SStefano Zampini PetscErrorCode ierr; 2334229984c5Sstefano_zampini Vec work; 23353425bc38SStefano Zampini 23363425bc38SStefano Zampini PetscFunctionBegin; 23373425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 23383425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 23393425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 23403425bc38SStefano Zampini 23413425bc38SStefano Zampini /* apply B_delta^T */ 2342af140850Sstefano_zampini ierr = VecSet(pcis->vec1_B,0.);CHKERRQ(ierr); 23433425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23443425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23453425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 2346229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2347229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->l2g_p,fetidp_flux_sol,mat_ctx->vP,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2348229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->l2g_p,fetidp_flux_sol,mat_ctx->vP,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2349229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->Bt_BB,mat_ctx->vP,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 2350229984c5Sstefano_zampini } 2351229984c5Sstefano_zampini 23523425bc38SStefano Zampini /* compute rhs for BDDC application */ 23533425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 23548eeda7d8SStefano Zampini if (pcbddc->switch_static) { 23553425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 2356229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2357229984c5Sstefano_zampini ierr = VecScale(mat_ctx->vP,-1.);CHKERRQ(ierr); 2358229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->Bt_BI,mat_ctx->vP,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); 23593425bc38SStefano Zampini } 2360229984c5Sstefano_zampini } 2361229984c5Sstefano_zampini 23623425bc38SStefano Zampini /* apply BDDC */ 2363229984c5Sstefano_zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 2364dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2365229984c5Sstefano_zampini 2366229984c5Sstefano_zampini /* put values into global vector */ 2367af140850Sstefano_zampini if (pcbddc->ChangeOfBasisMatrix) work = pcbddc->work_change; 2368af140850Sstefano_zampini else work = standard_sol; 2369229984c5Sstefano_zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2370229984c5Sstefano_zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23718eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 23723425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 23733425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 237400f6b531SStefano Zampini ierr = VecAYPX(pcis->vec1_D,-1.0,mat_ctx->temp_solution_D);CHKERRQ(ierr); 237500f6b531SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); 23763425bc38SStefano Zampini } 2377229984c5Sstefano_zampini 2378229984c5Sstefano_zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2379229984c5Sstefano_zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_D,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2380266e20e9SStefano Zampini /* add p0 solution to final solution */ 2381229984c5Sstefano_zampini ierr = PCBDDCBenignGetOrSetP0(mat_ctx->pc,work,PETSC_FALSE);CHKERRQ(ierr); 2382fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2383af140850Sstefano_zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,work,standard_sol);CHKERRQ(ierr); 2384fc17d649SStefano Zampini } 2385af140850Sstefano_zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 2386af140850Sstefano_zampini if (mat_ctx->g2g_p) { 2387229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,fetidp_flux_sol,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2388229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,fetidp_flux_sol,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2389229984c5Sstefano_zampini } 23903425bc38SStefano Zampini PetscFunctionReturn(0); 23913425bc38SStefano Zampini } 23921e6b0712SBarry Smith 23933425bc38SStefano Zampini /*@ 23940f202f7eSStefano Zampini PCBDDCMatFETIDPGetSolution - Compute the physical solution using the solution of the FETI-DP linear system 23953425bc38SStefano Zampini 23963425bc38SStefano Zampini Collective 23973425bc38SStefano Zampini 23983425bc38SStefano Zampini Input Parameters: 23990f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix obtained by a call to PCBDDCCreateFETIDPOperators 24000f202f7eSStefano Zampini - fetidp_flux_sol - the solution of the FETI-DP linear system 24013425bc38SStefano Zampini 24023425bc38SStefano Zampini Output Parameters: 24030f202f7eSStefano Zampini . standard_sol - the solution defined on the physical domain 24043425bc38SStefano Zampini 24053425bc38SStefano Zampini Level: developer 24063425bc38SStefano Zampini 24073425bc38SStefano Zampini Notes: 24083425bc38SStefano Zampini 24090f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetRHS 24103425bc38SStefano Zampini @*/ 24113425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 24123425bc38SStefano Zampini { 2413674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 24143425bc38SStefano Zampini PetscErrorCode ierr; 24153425bc38SStefano Zampini 24163425bc38SStefano Zampini PetscFunctionBegin; 2417266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2418266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_sol,VEC_CLASSID,2); 2419266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_sol,VEC_CLASSID,3); 24203425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2421163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 24223425bc38SStefano Zampini PetscFunctionReturn(0); 24233425bc38SStefano Zampini } 24241e6b0712SBarry Smith 2425547c9a8eSstefano_zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, PetscBool fully_redundant, const char* prefix, Mat *fetidp_mat, PC *fetidp_pc) 24263425bc38SStefano Zampini { 2427674ae819SStefano Zampini 2428674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 24293425bc38SStefano Zampini Mat newmat; 2430674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 24313425bc38SStefano Zampini PC newpc; 2432ce94432eSBarry Smith MPI_Comm comm; 24333425bc38SStefano Zampini PetscErrorCode ierr; 24343425bc38SStefano Zampini 24353425bc38SStefano Zampini PetscFunctionBegin; 2436ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 24373425bc38SStefano Zampini /* FETIDP linear matrix */ 24383425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 24391720468bSStefano Zampini fetidpmat_ctx->fully_redundant = fully_redundant; 24403425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 2441a5bb87b3Sstefano_zampini ierr = MatCreateShell(comm,fetidpmat_ctx->n,fetidpmat_ctx->n,fetidpmat_ctx->N,fetidpmat_ctx->N,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 24423425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 2443edf7251bSStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT_TRANSPOSE,(void (*)(void))FETIDPMatMultTranspose);CHKERRQ(ierr); 24443425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 2445547c9a8eSstefano_zampini ierr = MatSetOptionsPrefix(newmat,prefix);CHKERRQ(ierr); 2446547c9a8eSstefano_zampini ierr = MatAppendOptionsPrefix(newmat,"fetidp_");CHKERRQ(ierr); 24473425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 24483425bc38SStefano Zampini /* FETIDP preconditioner */ 24493425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 24503425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 24513425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 2452e1214c54Sstefano_zampini ierr = PCSetOperators(newpc,newmat,newmat);CHKERRQ(ierr); 2453e1214c54Sstefano_zampini ierr = PCSetOptionsPrefix(newpc,prefix);CHKERRQ(ierr); 2454e1214c54Sstefano_zampini ierr = PCAppendOptionsPrefix(newpc,"fetidp_");CHKERRQ(ierr); 2455*399ffe99SStefano Zampini ierr = PCSetErrorIfFailure(newpc,pc->erroriffailure);CHKERRQ(ierr); 2456e1214c54Sstefano_zampini if (!fetidpmat_ctx->l2g_lambda_only) { 24573425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 24583425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 24593425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 2460edf7251bSStefano Zampini ierr = PCShellSetApplyTranspose(newpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 2461c45b8d2dSstefano_zampini ierr = PCShellSetView(newpc,FETIDPPCView);CHKERRQ(ierr); 24623425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 2463e1214c54Sstefano_zampini } else { 2464e1214c54Sstefano_zampini KSP *ksps; 2465e1214c54Sstefano_zampini PC lagpc; 2466e1214c54Sstefano_zampini Mat M,AM,PM; 2467e1214c54Sstefano_zampini PetscInt nn; 2468e1214c54Sstefano_zampini 2469e1214c54Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_PPmat",(PetscObject*)&M);CHKERRQ(ierr); 2470e1214c54Sstefano_zampini ierr = PCSetType(newpc,PCFIELDSPLIT);CHKERRQ(ierr); 2471e1214c54Sstefano_zampini ierr = PCFieldSplitSetIS(newpc,"lag",fetidpmat_ctx->lagrange);CHKERRQ(ierr); 2472e1214c54Sstefano_zampini ierr = PCFieldSplitSetIS(newpc,"p",fetidpmat_ctx->pressure);CHKERRQ(ierr); 2473e1214c54Sstefano_zampini ierr = PCFieldSplitSetType(newpc,PC_COMPOSITE_SCHUR);CHKERRQ(ierr); 247440c75d76SStefano Zampini ierr = PCFieldSplitSetSchurFactType(newpc,PC_FIELDSPLIT_SCHUR_FACT_DIAG);CHKERRQ(ierr); 2475e1214c54Sstefano_zampini ierr = PCFieldSplitSetSchurPre(newpc,PC_FIELDSPLIT_SCHUR_PRE_USER,M);CHKERRQ(ierr); 2476c096484dSStefano Zampini ierr = PCFieldSplitSetSchurScale(newpc,1.0);CHKERRQ(ierr); 2477e1214c54Sstefano_zampini ierr = PCSetFromOptions(newpc);CHKERRQ(ierr); 2478e1214c54Sstefano_zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 2479e1214c54Sstefano_zampini 2480e1214c54Sstefano_zampini /* set the solver for the (0,0) block */ 248140c75d76SStefano Zampini ierr = PCFieldSplitGetSubKSP(newpc,&nn,&ksps);CHKERRQ(ierr); 2482e1214c54Sstefano_zampini ierr = PCCreate(comm,&lagpc);CHKERRQ(ierr); 2483e1214c54Sstefano_zampini ierr = PCSetType(lagpc,PCSHELL);CHKERRQ(ierr); 2484e1214c54Sstefano_zampini ierr = KSPGetOperators(ksps[0],&AM,&PM);CHKERRQ(ierr); 2485e1214c54Sstefano_zampini ierr = PCSetOperators(lagpc,AM,PM);CHKERRQ(ierr); 2486e1214c54Sstefano_zampini ierr = PCShellSetContext(lagpc,fetidppc_ctx);CHKERRQ(ierr); 2487e1214c54Sstefano_zampini ierr = PCShellSetApply(lagpc,FETIDPPCApply);CHKERRQ(ierr); 2488e1214c54Sstefano_zampini ierr = PCShellSetApplyTranspose(lagpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 2489e1214c54Sstefano_zampini ierr = PCShellSetView(lagpc,FETIDPPCView);CHKERRQ(ierr); 2490e1214c54Sstefano_zampini ierr = PCShellSetDestroy(lagpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 2491e1214c54Sstefano_zampini ierr = KSPSetPC(ksps[0],lagpc);CHKERRQ(ierr); 2492e1214c54Sstefano_zampini ierr = PCDestroy(&lagpc);CHKERRQ(ierr); 2493e1214c54Sstefano_zampini ierr = PetscFree(ksps);CHKERRQ(ierr); 2494e1214c54Sstefano_zampini } 24953425bc38SStefano Zampini /* return pointers for objects created */ 24963425bc38SStefano Zampini *fetidp_mat = newmat; 24973425bc38SStefano Zampini *fetidp_pc = newpc; 24983425bc38SStefano Zampini PetscFunctionReturn(0); 24993425bc38SStefano Zampini } 25001e6b0712SBarry Smith 250194ef8ddeSSatish Balay /*@C 25020f202f7eSStefano Zampini PCBDDCCreateFETIDPOperators - Create FETI-DP operators 25033425bc38SStefano Zampini 25043425bc38SStefano Zampini Collective 25053425bc38SStefano Zampini 25063425bc38SStefano Zampini Input Parameters: 25071720468bSStefano Zampini + pc - the BDDC preconditioning context (setup should have been called before) 2508547c9a8eSstefano_zampini . fully_redundant - true for a fully redundant set of Lagrange multipliers 2509547c9a8eSstefano_zampini - prefix - optional options database prefix for the objects to be created (can be NULL) 251028509bceSStefano Zampini 251128509bceSStefano Zampini Output Parameters: 25120f202f7eSStefano Zampini + fetidp_mat - shell FETI-DP matrix object 25130f202f7eSStefano Zampini - fetidp_pc - shell Dirichlet preconditioner for FETI-DP matrix 251428509bceSStefano Zampini 25153425bc38SStefano Zampini Level: developer 25163425bc38SStefano Zampini 25173425bc38SStefano Zampini Notes: 25180f202f7eSStefano Zampini Currently the only operations provided for FETI-DP matrix are MatMult and MatMultTranspose 25193425bc38SStefano Zampini 25200f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCMatFETIDPGetRHS, PCBDDCMatFETIDPGetSolution 25213425bc38SStefano Zampini @*/ 2522547c9a8eSstefano_zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, PetscBool fully_redundant, const char *prefix, Mat *fetidp_mat, PC *fetidp_pc) 25233425bc38SStefano Zampini { 25243425bc38SStefano Zampini PetscErrorCode ierr; 25253425bc38SStefano Zampini 25263425bc38SStefano Zampini PetscFunctionBegin; 25273425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 25283425bc38SStefano Zampini if (pc->setupcalled) { 2529547c9a8eSstefano_zampini ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,PetscBool,const char*,Mat*,PC*),(pc,fully_redundant,prefix,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 25304247aa23Sstefano_zampini } else SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n"); 25313425bc38SStefano Zampini PetscFunctionReturn(0); 25323425bc38SStefano Zampini } 25330c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2534da1bb401SStefano Zampini /*MC 2535da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 25360c7d97c5SJed Brown 253728509bceSStefano Zampini An implementation of the BDDC preconditioner based on 253828509bceSStefano Zampini 253928509bceSStefano Zampini .vb 254028509bceSStefano Zampini [1] C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 254128509bceSStefano 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 254228509bceSStefano Zampini [3] J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", http://arxiv.org/abs/0712.3977 25430f202f7eSStefano 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 254428509bceSStefano Zampini .ve 254528509bceSStefano Zampini 254628509bceSStefano Zampini The matrix to be preconditioned (Pmat) must be of type MATIS. 254728509bceSStefano Zampini 25480f202f7eSStefano Zampini Currently works with MATIS matrices with local matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers. 254928509bceSStefano Zampini 255028509bceSStefano Zampini It also works with unsymmetric and indefinite problems. 255128509bceSStefano Zampini 2552b6fdb6dfSStefano 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. 2553b6fdb6dfSStefano Zampini 2554c7017625SStefano 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). 255528509bceSStefano Zampini 25560f202f7eSStefano 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() 255730368db7SStefano Zampini Additional information on dofs can be provided by using PCBDDCSetDofsSplitting(), PCBDDCSetDirichletBoundaries(), PCBDDCSetNeumannBoundaries(), and PCBDDCSetPrimalVerticesIS() and their local counterparts. 255828509bceSStefano Zampini 25590f202f7eSStefano Zampini Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace(). Non-singular modes are retained via SVD. 256028509bceSStefano Zampini 25610f202f7eSStefano 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. 25620f202f7eSStefano Zampini User defined change of basis can be passed to PCBDDC by using PCBDDCSetChangeOfBasisMat() 256328509bceSStefano Zampini 25640f202f7eSStefano Zampini The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using a MatPartitioning object. 256528509bceSStefano Zampini 2566df4d28bfSStefano 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. 256728509bceSStefano Zampini 25680f202f7eSStefano 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. 25690f202f7eSStefano Zampini Deluxe scaling is not supported yet for FETI-DP. 25700f202f7eSStefano Zampini 25710f202f7eSStefano Zampini Options Database Keys (some of them, run with -h for a complete list): 25720f202f7eSStefano Zampini 25730f202f7eSStefano Zampini . -pc_bddc_use_vertices <true> - use or not vertices in primal space 25740f202f7eSStefano Zampini . -pc_bddc_use_edges <true> - use or not edges in primal space 25750f202f7eSStefano Zampini . -pc_bddc_use_faces <false> - use or not faces in primal space 25760f202f7eSStefano Zampini . -pc_bddc_symmetric <true> - symmetric computation of primal basis functions. Specify false for unsymmetric problems 25770f202f7eSStefano Zampini . -pc_bddc_use_change_of_basis <false> - use change of basis approach (on edges only) 25780f202f7eSStefano Zampini . -pc_bddc_use_change_on_faces <false> - use change of basis approach on faces if change of basis has been requested 25790f202f7eSStefano Zampini . -pc_bddc_switch_static <false> - switches from M_2 (default) to M_3 operator (see reference article [1]) 258028509bceSStefano Zampini . -pc_bddc_levels <0> - maximum number of levels for multilevel 25810f202f7eSStefano 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) 25825459c157SBarry 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) 25830f202f7eSStefano Zampini . -pc_bddc_use_deluxe_scaling <false> - use deluxe scaling 25840f202f7eSStefano 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) 2585bd2a564bSStefano 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) 258628509bceSStefano Zampini - -pc_bddc_check_level <0> - set verbosity level of debugging output 258728509bceSStefano Zampini 258828509bceSStefano Zampini Options for Dirichlet, Neumann or coarse solver can be set with 258928509bceSStefano Zampini .vb 259028509bceSStefano Zampini -pc_bddc_dirichlet_ 259128509bceSStefano Zampini -pc_bddc_neumann_ 259228509bceSStefano Zampini -pc_bddc_coarse_ 259328509bceSStefano Zampini .ve 25940f202f7eSStefano Zampini e.g -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg. PCBDDC uses by default KPSPREONLY and PCLU. 259528509bceSStefano Zampini 25960f202f7eSStefano Zampini When using a multilevel approach, solvers' options at the N-th level (N > 1) can be specified as 259728509bceSStefano Zampini .vb 2598312be037SStefano Zampini -pc_bddc_dirichlet_lN_ 2599312be037SStefano Zampini -pc_bddc_neumann_lN_ 2600312be037SStefano Zampini -pc_bddc_coarse_lN_ 260128509bceSStefano Zampini .ve 26020f202f7eSStefano Zampini Note that level number ranges from the finest (0) to the coarsest (N). 26030f202f7eSStefano 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. 26040f202f7eSStefano Zampini .vb 26050f202f7eSStefano Zampini -pc_bddc_coarse_pc_bddc_adaptive_threshold 5 -pc_bddc_coarse_l1_pc_bddc_redistribute 3 26060f202f7eSStefano Zampini .ve 26070f202f7eSStefano 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 2608da1bb401SStefano Zampini 2609da1bb401SStefano Zampini Level: intermediate 2610da1bb401SStefano Zampini 2611e94cfbe0SPatrick Sanan Developer Notes: 2612da1bb401SStefano Zampini 2613da1bb401SStefano Zampini Contributed by Stefano Zampini 2614da1bb401SStefano Zampini 2615da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 2616da1bb401SStefano Zampini M*/ 2617b2573a8aSBarry Smith 26188cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 2619da1bb401SStefano Zampini { 2620da1bb401SStefano Zampini PetscErrorCode ierr; 2621da1bb401SStefano Zampini PC_BDDC *pcbddc; 2622da1bb401SStefano Zampini 2623da1bb401SStefano Zampini PetscFunctionBegin; 2624b00a9115SJed Brown ierr = PetscNewLog(pc,&pcbddc);CHKERRQ(ierr); 2625da1bb401SStefano Zampini pc->data = (void*)pcbddc; 2626da1bb401SStefano Zampini 2627da1bb401SStefano Zampini /* create PCIS data structure */ 2628da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 2629da1bb401SStefano Zampini 26309326c5c6Sstefano_zampini /* create local graph structure */ 26319326c5c6Sstefano_zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 26329326c5c6Sstefano_zampini 26339326c5c6Sstefano_zampini /* BDDC nonzero defaults */ 263408a5cf49SStefano Zampini pcbddc->use_local_adj = PETSC_TRUE; 263547d04d0dSStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 263647d04d0dSStefano Zampini pcbddc->use_edges = PETSC_TRUE; 26373301b35fSStefano Zampini pcbddc->symmetric_primal = PETSC_TRUE; 263814f95afaSStefano Zampini pcbddc->vertex_size = 1; 2639c703fcc7SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 264068457ee5SStefano Zampini pcbddc->coarse_size = -1; 264185c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 264247d04d0dSStefano Zampini pcbddc->coarsening_ratio = 8; 264357de7509SStefano Zampini pcbddc->coarse_eqs_per_proc = 1; 264427b6a85dSStefano Zampini pcbddc->benign_compute_correction = PETSC_TRUE; 26451e0482f5SStefano Zampini pcbddc->nedfield = -1; 26461e0482f5SStefano Zampini pcbddc->nedglobal = PETSC_TRUE; 2647be12c134Sstefano_zampini pcbddc->graphmaxcount = PETSC_MAX_INT; 2648b96c3477SStefano Zampini pcbddc->sub_schurs_layers = -1; 2649bd2a564bSStefano Zampini pcbddc->adaptive_threshold[0] = 0.0; 2650bd2a564bSStefano Zampini pcbddc->adaptive_threshold[1] = 0.0; 2651b7eb3628SStefano Zampini 2652da1bb401SStefano Zampini /* function pointers */ 2653da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 265493bd9ae7SStefano Zampini pc->ops->applytranspose = PCApplyTranspose_BDDC; 2655da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 2656da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 2657da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 26586b78500eSPatrick Sanan pc->ops->view = PCView_BDDC; 2659da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 2660da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 2661da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 2662534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 2663534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 26649326c5c6Sstefano_zampini pc->ops->reset = PCReset_BDDC; 2665da1bb401SStefano Zampini 2666da1bb401SStefano Zampini /* composing function */ 2667a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",PCBDDCSetDiscreteGradient_BDDC);CHKERRQ(ierr); 2668a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",PCBDDCSetDivergenceMat_BDDC);CHKERRQ(ierr); 2669906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",PCBDDCSetChangeOfBasisMat_BDDC);CHKERRQ(ierr); 2670674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 267130368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",PCBDDCSetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 2672bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 26732b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr); 2674b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr); 26752b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr); 2676bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 267782ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2678bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 267982ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2680bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 268182ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2682bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 268382ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2684bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 268563602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",PCBDDCSetDofsSplittingLocal_BDDC);CHKERRQ(ierr); 2686bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 2687bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 2688bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 2689bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 2690a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",PCPreSolveChangeRHS_BDDC);CHKERRQ(ierr); 2691ab8c8b98SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_BDDC);CHKERRQ(ierr); 2692da1bb401SStefano Zampini PetscFunctionReturn(0); 2693da1bb401SStefano Zampini } 269443371fb9SStefano Zampini 269543371fb9SStefano Zampini /*@C 269643371fb9SStefano Zampini PCBDDCInitializePackage - This function initializes everything in the PCBDDC package. It is called 269743371fb9SStefano Zampini from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PCCreate_BDDC() 269843371fb9SStefano Zampini when using static libraries. 269943371fb9SStefano Zampini 270043371fb9SStefano Zampini Level: developer 270143371fb9SStefano Zampini 270243371fb9SStefano Zampini .keywords: PC, PCBDDC, initialize, package 270343371fb9SStefano Zampini .seealso: PetscInitialize() 270443371fb9SStefano Zampini @*/ 270543371fb9SStefano Zampini PetscErrorCode PCBDDCInitializePackage(void) 270643371fb9SStefano Zampini { 270743371fb9SStefano Zampini PetscErrorCode ierr; 270843371fb9SStefano Zampini int i; 270943371fb9SStefano Zampini 271043371fb9SStefano Zampini PetscFunctionBegin; 271143371fb9SStefano Zampini if (PCBDDCPackageInitialized) PetscFunctionReturn(0); 271243371fb9SStefano Zampini PCBDDCPackageInitialized = PETSC_TRUE; 271343371fb9SStefano Zampini ierr = PetscRegisterFinalize(PCBDDCFinalizePackage);CHKERRQ(ierr); 271443371fb9SStefano Zampini 271543371fb9SStefano Zampini /* general events */ 271643371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCTopo",PC_CLASSID,&PC_BDDC_Topology[0]);CHKERRQ(ierr); 271743371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCLKSP",PC_CLASSID,&PC_BDDC_LocalSolvers[0]);CHKERRQ(ierr); 271843371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCLWor",PC_CLASSID,&PC_BDDC_LocalWork[0]);CHKERRQ(ierr); 271943371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCorr",PC_CLASSID,&PC_BDDC_CorrectionSetUp[0]);CHKERRQ(ierr); 272043371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCSet",PC_CLASSID,&PC_BDDC_CoarseSetUp[0]);CHKERRQ(ierr); 272143371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCKSP",PC_CLASSID,&PC_BDDC_CoarseSolver[0]);CHKERRQ(ierr); 272243371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCAdap",PC_CLASSID,&PC_BDDC_AdaptiveSetUp[0]);CHKERRQ(ierr); 272343371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCScal",PC_CLASSID,&PC_BDDC_Scaling[0]);CHKERRQ(ierr); 272443371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCSchr",PC_CLASSID,&PC_BDDC_Schurs[0]);CHKERRQ(ierr); 272543371fb9SStefano Zampini for (i=1;i<PETSC_PCBDDC_MAXLEVELS;i++) { 272643371fb9SStefano Zampini char ename[32]; 272743371fb9SStefano Zampini 272843371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCTopo l%02d",i);CHKERRQ(ierr); 272943371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Topology[i]);CHKERRQ(ierr); 273043371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCLKSP l%02d",i);CHKERRQ(ierr); 273143371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_LocalSolvers[i]);CHKERRQ(ierr); 273243371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCLWor l%02d",i);CHKERRQ(ierr); 273343371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_LocalWork[i]);CHKERRQ(ierr); 273443371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCorr l%02d",i);CHKERRQ(ierr); 273543371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CorrectionSetUp[i]);CHKERRQ(ierr); 273643371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCSet l%02d",i);CHKERRQ(ierr); 273743371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CoarseSetUp[i]);CHKERRQ(ierr); 273843371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCKSP l%02d",i);CHKERRQ(ierr); 273943371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CoarseSolver[i]);CHKERRQ(ierr); 274043371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCAdap l%02d",i);CHKERRQ(ierr); 274143371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_AdaptiveSetUp[i]);CHKERRQ(ierr); 274243371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCScal l%02d",i);CHKERRQ(ierr); 274343371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Scaling[i]);CHKERRQ(ierr); 274443371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCSchr l%02d",i);CHKERRQ(ierr); 274543371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Schurs[i]);CHKERRQ(ierr); 274643371fb9SStefano Zampini } 274743371fb9SStefano Zampini PetscFunctionReturn(0); 274843371fb9SStefano Zampini } 274943371fb9SStefano Zampini 275043371fb9SStefano Zampini /*@C 275143371fb9SStefano Zampini PCBDDCFinalizePackage - This function frees everything from the PCBDDC package. It is 275243371fb9SStefano Zampini called from PetscFinalize() automatically. 275343371fb9SStefano Zampini 275443371fb9SStefano Zampini Level: developer 275543371fb9SStefano Zampini 275643371fb9SStefano Zampini .keywords: Petsc, destroy, package 275743371fb9SStefano Zampini .seealso: PetscFinalize() 275843371fb9SStefano Zampini @*/ 275943371fb9SStefano Zampini PetscErrorCode PCBDDCFinalizePackage(void) 276043371fb9SStefano Zampini { 276143371fb9SStefano Zampini PetscFunctionBegin; 276243371fb9SStefano Zampini PCBDDCPackageInitialized = PETSC_FALSE; 276343371fb9SStefano Zampini PetscFunctionReturn(0); 276443371fb9SStefano Zampini } 2765