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]; 47*8ead10e4SStefano Zampini PetscLogEvent PC_BDDC_ApproxSetUp[PETSC_PCBDDC_MAXLEVELS]; 48*8ead10e4SStefano Zampini PetscLogEvent PC_BDDC_ApproxApply[PETSC_PCBDDC_MAXLEVELS]; 4943371fb9SStefano Zampini PetscLogEvent PC_BDDC_CoarseSetUp[PETSC_PCBDDC_MAXLEVELS]; 5043371fb9SStefano Zampini PetscLogEvent PC_BDDC_CoarseSolver[PETSC_PCBDDC_MAXLEVELS]; 5143371fb9SStefano Zampini PetscLogEvent PC_BDDC_AdaptiveSetUp[PETSC_PCBDDC_MAXLEVELS]; 5243371fb9SStefano Zampini PetscLogEvent PC_BDDC_Scaling[PETSC_PCBDDC_MAXLEVELS]; 5343371fb9SStefano Zampini PetscLogEvent PC_BDDC_Schurs[PETSC_PCBDDC_MAXLEVELS]; 5443371fb9SStefano Zampini 550369aaf7SStefano Zampini PetscErrorCode PCApply_BDDC(PC,Vec,Vec); 560369aaf7SStefano Zampini 574416b707SBarry Smith PetscErrorCode PCSetFromOptions_BDDC(PetscOptionItems *PetscOptionsObject,PC pc) 580c7d97c5SJed Brown { 590c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 60e569e4e1SStefano Zampini PetscInt nt,i; 610c7d97c5SJed Brown PetscErrorCode ierr; 620c7d97c5SJed Brown 630c7d97c5SJed Brown PetscFunctionBegin; 64e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"BDDC options");CHKERRQ(ierr); 658eeda7d8SStefano Zampini /* Verbose debugging */ 66a13144ffSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_check_level","Verbose output for PCBDDC (intended for debug)","none",pcbddc->dbg_flag,&pcbddc->dbg_flag,NULL);CHKERRQ(ierr); 67a13144ffSStefano Zampini /* Approximate solvers */ 68c7017625SStefano 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); 69c7017625SStefano 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); 70c7017625SStefano 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); 71c7017625SStefano 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); 726b78500eSPatrick Sanan /* Primal space customization */ 7308a5cf49SStefano 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); 74be12c134Sstefano_zampini ierr = PetscOptionsInt("-pc_bddc_graph_maxcount","Maximum number of shared subdomains for a connected component","none",pcbddc->graphmaxcount,&pcbddc->graphmaxcount,NULL);CHKERRQ(ierr); 751c7a958bSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_corner_selection","Activates face-based corner selection","none",pcbddc->corner_selection,&pcbddc->corner_selection,NULL);CHKERRQ(ierr); 768eeda7d8SStefano 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); 778eeda7d8SStefano 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); 788eeda7d8SStefano 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); 7914f95afaSStefano 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); 806661aa1dSStefano 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); 8114f95afaSStefano 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); 828eeda7d8SStefano Zampini /* Change of basis */ 83b9b85e73SStefano 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); 84b9b85e73SStefano 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); 85674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 86674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 87674ae819SStefano Zampini } 888eeda7d8SStefano Zampini /* Switch between M_2 (default) and M_3 preconditioners (as defined by C. Dohrmann in the ref. article) */ 898eeda7d8SStefano 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); 90e569e4e1SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_coarse_eqs_per_proc","Target number of equations per process for coarse problem redistribution (significant only at the coarsest level)","none",pcbddc->coarse_eqs_per_proc,&pcbddc->coarse_eqs_per_proc,NULL);CHKERRQ(ierr); 91e569e4e1SStefano Zampini i = pcbddc->coarsening_ratio; 92e569e4e1SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","PCBDDCSetCoarseningRatio",i,&i,NULL);CHKERRQ(ierr); 93e569e4e1SStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc,i);CHKERRQ(ierr); 94e569e4e1SStefano Zampini i = pcbddc->max_levels; 95e569e4e1SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_levels","Set maximum number of levels for multilevel","PCBDDCSetLevels",i,&i,NULL);CHKERRQ(ierr); 96e569e4e1SStefano Zampini ierr = PCBDDCSetLevels(pc,i);CHKERRQ(ierr); 97e569e4e1SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_coarse_eqs_limit","Set maximum number of equations on coarsest grid to aim for","none",pcbddc->coarse_eqs_limit,&pcbddc->coarse_eqs_limit,NULL);CHKERRQ(ierr); 98323d395dSStefano 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); 99674ae819SStefano 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); 100b96c3477SStefano 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); 101b96c3477SStefano 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); 102b96c3477SStefano 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); 103683d3df6SStefano 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); 104bf3a8328SStefano 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); 105839e9adbSstefano_zampini ierr = PetscOptionsBool("-pc_bddc_deluxe_singlemat","Collapse deluxe operators","none",pcbddc->deluxe_singlemat,&pcbddc->deluxe_singlemat,NULL);CHKERRQ(ierr); 106bf3a8328SStefano 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); 107bd2a564bSStefano Zampini nt = 2; 108bd2a564bSStefano Zampini ierr = PetscOptionsRealArray("-pc_bddc_adaptive_threshold","Thresholds to be used for adaptive selection of constraints","none",pcbddc->adaptive_threshold,&nt,NULL);CHKERRQ(ierr); 109bd2a564bSStefano Zampini if (nt == 1) pcbddc->adaptive_threshold[1] = pcbddc->adaptive_threshold[0]; 11008122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmin","Minimum number of constraints per connected components","none",pcbddc->adaptive_nmin,&pcbddc->adaptive_nmin,NULL);CHKERRQ(ierr); 11108122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmax","Maximum number of constraints per connected components","none",pcbddc->adaptive_nmax,&pcbddc->adaptive_nmax,NULL);CHKERRQ(ierr); 1123301b35fSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_symmetric","Symmetric computation of primal basis functions","none",pcbddc->symmetric_primal,&pcbddc->symmetric_primal,NULL);CHKERRQ(ierr); 113b0c7d250SStefano 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); 114b3afcdbeSStefano 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); 115e9627c49SStefano 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); 11627b6a85dSStefano 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); 117a198735bSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nonetflux","Automatic computation of no-net-flux quadrature weights","none",pcbddc->compute_nonetflux,&pcbddc->compute_nonetflux,NULL);CHKERRQ(ierr); 1184f1b2e48SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_detect_disconnected","Detects disconnected subdomains","none",pcbddc->detect_disconnected,&pcbddc->detect_disconnected,NULL);CHKERRQ(ierr); 1198361f951SStefano 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); 12070c64980SStefano 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); 1210c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 1220c7d97c5SJed Brown PetscFunctionReturn(0); 1230c7d97c5SJed Brown } 1246b78500eSPatrick Sanan 1256b78500eSPatrick Sanan static PetscErrorCode PCView_BDDC(PC pc,PetscViewer viewer) 1266b78500eSPatrick Sanan { 1276b78500eSPatrick Sanan PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 128e9627c49SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1296b78500eSPatrick Sanan PetscErrorCode ierr; 13071783a16SStefano Zampini PetscBool isascii; 131e9627c49SStefano Zampini PetscSubcomm subcomm; 132e9627c49SStefano Zampini PetscViewer subviewer; 1336b78500eSPatrick Sanan 1346b78500eSPatrick Sanan PetscFunctionBegin; 1356b78500eSPatrick Sanan ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1366b78500eSPatrick Sanan /* ASCII viewer */ 1376b78500eSPatrick Sanan if (isascii) { 1384b2aedd3SStefano Zampini PetscMPIInt color,rank,size; 139fbad9177SStefano Zampini PetscInt64 loc[7],gsum[6],gmax[6],gmin[6],totbenign; 140e9627c49SStefano Zampini PetscScalar interface_size; 141e9627c49SStefano Zampini PetscReal ratio1=0.,ratio2=0.; 142e9627c49SStefano Zampini Vec counter; 1436b78500eSPatrick Sanan 144b74ba07aSstefano_zampini if (!pc->setupcalled) { 145b74ba07aSstefano_zampini ierr = PetscViewerASCIIPrintf(viewer," Partial information available: preconditioner has not been setup yet\n");CHKERRQ(ierr); 146b74ba07aSstefano_zampini } 147efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use verbose output: %D\n",pcbddc->dbg_flag);CHKERRQ(ierr); 1486f0c0a6aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use user-defined CSR: %d\n",!!pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 1496f0c0a6aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use local mat graph: %d\n",pcbddc->use_local_adj && !pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 150e9627c49SStefano Zampini if (pcbddc->mat_graph->twodim) { 151efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Connectivity graph topological dimension: 2\n");CHKERRQ(ierr); 152e9627c49SStefano Zampini } else { 153efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Connectivity graph topological dimension: 3\n");CHKERRQ(ierr); 154e9627c49SStefano Zampini } 155aefa1729SStefano Zampini if (pcbddc->graphmaxcount != PETSC_MAX_INT) { 156efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Graph max count: %D\n",pcbddc->graphmaxcount);CHKERRQ(ierr); 157aefa1729SStefano Zampini } 15850e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use vertices: %d (vertex size %D)\n",pcbddc->use_vertices,pcbddc->vertex_size);CHKERRQ(ierr); 159efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use edges: %d\n",pcbddc->use_edges);CHKERRQ(ierr); 160efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use faces: %d\n",pcbddc->use_faces);CHKERRQ(ierr); 161efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use true near null space: %d\n",pcbddc->use_nnsp_true);CHKERRQ(ierr); 162efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use QR for single constraints on cc: %d\n",pcbddc->use_qr_single);CHKERRQ(ierr); 163efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use change of basis on local edge nodes: %d\n",pcbddc->use_change_of_basis);CHKERRQ(ierr); 164efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use change of basis on local face nodes: %d\n",pcbddc->use_change_on_faces);CHKERRQ(ierr); 165efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," User defined change of basis matrix: %d\n",!!pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 166efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Has change of basis matrix: %d\n",!!pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 167efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eliminate dirichlet boundary dofs: %d\n",pcbddc->eliminate_dirdofs);CHKERRQ(ierr); 168efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Switch on static condensation ops around the interface preconditioner: %d\n",pcbddc->switch_static);CHKERRQ(ierr); 169efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use exact dirichlet trick: %d\n",pcbddc->use_exact_dirichlet_trick);CHKERRQ(ierr); 17050e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Multilevel max levels: %D\n",pcbddc->max_levels);CHKERRQ(ierr); 17150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Multilevel coarsening ratio: %D\n",pcbddc->coarsening_ratio);CHKERRQ(ierr); 172efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use estimated eigs for coarse problem: %d\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 173efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe scaling: %d\n",pcbddc->use_deluxe_scaling);CHKERRQ(ierr); 174efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe zerorows: %d\n",pcbddc->deluxe_zerorows);CHKERRQ(ierr); 175efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe singlemat: %d\n",pcbddc->deluxe_singlemat);CHKERRQ(ierr); 176efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Rebuild interface graph for Schur principal minors: %d\n",pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 17750e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Number of dofs' layers for the computation of principal minors: %D\n",pcbddc->sub_schurs_layers);CHKERRQ(ierr); 178efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use user CSR graph to compute successive layers: %d\n",pcbddc->sub_schurs_use_useradj);CHKERRQ(ierr); 179bd2a564bSStefano Zampini if (pcbddc->adaptive_threshold[1] != pcbddc->adaptive_threshold[0]) { 180bd2a564bSStefano 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); 181bd2a564bSStefano Zampini } else { 182bd2a564bSStefano 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); 183bd2a564bSStefano Zampini } 18450e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Min constraints / connected component: %D\n",pcbddc->adaptive_nmin);CHKERRQ(ierr); 18550e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Max constraints / connected component: %D\n",pcbddc->adaptive_nmax);CHKERRQ(ierr); 186efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Invert exact Schur complement for adaptive selection: %d\n",pcbddc->sub_schurs_exact_schur);CHKERRQ(ierr); 187efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Symmetric computation of primal basis functions: %d\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 18850e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Num. Procs. to map coarse adjacency list: %D\n",pcbddc->coarse_adj_red);CHKERRQ(ierr); 18950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Coarse eqs per proc (significant at the coarsest level): %D\n",pcbddc->coarse_eqs_per_proc);CHKERRQ(ierr); 1908361f951SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Detect disconnected: %d (filter %d)\n",pcbddc->detect_disconnected,pcbddc->detect_disconnected_filter);CHKERRQ(ierr); 191efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Benign subspace trick: %d (change explicit %d)\n",pcbddc->benign_saddle_point,pcbddc->benign_change_explicit);CHKERRQ(ierr); 192efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Benign subspace trick is active: %d\n",pcbddc->benign_have_null);CHKERRQ(ierr); 19315579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Algebraic computation of no-net-flux: %d\n",pcbddc->compute_nonetflux);CHKERRQ(ierr); 194b74ba07aSstefano_zampini if (!pc->setupcalled) PetscFunctionReturn(0); 1956b78500eSPatrick Sanan 196fbad9177SStefano Zampini /* compute interface size */ 197e9627c49SStefano Zampini ierr = VecSet(pcis->vec1_B,1.0);CHKERRQ(ierr); 198e9627c49SStefano Zampini ierr = MatCreateVecs(pc->pmat,&counter,0);CHKERRQ(ierr); 199e9627c49SStefano Zampini ierr = VecSet(counter,0.0);CHKERRQ(ierr); 200e9627c49SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 201e9627c49SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 202e9627c49SStefano Zampini ierr = VecSum(counter,&interface_size);CHKERRQ(ierr); 203e9627c49SStefano Zampini ierr = VecDestroy(&counter);CHKERRQ(ierr); 204fbad9177SStefano Zampini 205fbad9177SStefano Zampini /* compute some statistics on the domain decomposition */ 206e9627c49SStefano Zampini gsum[0] = 1; 207fbad9177SStefano Zampini gsum[1] = gsum[2] = gsum[3] = gsum[4] = gsum[5] = 0; 208e9627c49SStefano Zampini loc[0] = !!pcis->n; 209e9627c49SStefano Zampini loc[1] = pcis->n - pcis->n_B; 210e9627c49SStefano Zampini loc[2] = pcis->n_B; 211e9627c49SStefano Zampini loc[3] = pcbddc->local_primal_size; 212345ecf6cSStefano Zampini loc[4] = pcis->n; 213fbad9177SStefano Zampini loc[5] = pcbddc->n_local_subs > 0 ? pcbddc->n_local_subs : (pcis->n ? 1 : 0); 214fbad9177SStefano Zampini loc[6] = pcbddc->benign_n; 215fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gsum,6,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 216fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = -1; 217fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gmax,6,MPIU_INT64,MPI_MAX,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 218fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = PETSC_MAX_INT; 219fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gmin,6,MPIU_INT64,MPI_MIN,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 220fbad9177SStefano Zampini ierr = MPI_Reduce(&loc[6],&totbenign,1,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 221e9627c49SStefano Zampini if (pcbddc->coarse_size) { 222e9627c49SStefano Zampini ratio1 = pc->pmat->rmap->N/(1.*pcbddc->coarse_size); 223e9627c49SStefano Zampini ratio2 = PetscRealPart(interface_size)/pcbddc->coarse_size; 224e9627c49SStefano Zampini } 225efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"********************************** STATISTICS AT LEVEL %d **********************************\n",pcbddc->current_level);CHKERRQ(ierr); 22650e0721cSStefano 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); 22750e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Coarsening ratios: all/coarse %D interface/coarse %D\n",(PetscInt)ratio1,(PetscInt)ratio2);CHKERRQ(ierr); 22850e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Active processes : %D\n",(PetscInt)gsum[0]);CHKERRQ(ierr); 22950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Total subdomains : %D\n",(PetscInt)gsum[5]);CHKERRQ(ierr); 230345ecf6cSStefano Zampini if (pcbddc->benign_have_null) { 23150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Benign subs : %D\n",(PetscInt)totbenign);CHKERRQ(ierr); 232345ecf6cSStefano Zampini } 23350e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Dofs type :\tMIN\tMAX\tMEAN\n");CHKERRQ(ierr); 23450e0721cSStefano 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); 23550e0721cSStefano 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); 23650e0721cSStefano 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); 23750e0721cSStefano 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); 23850e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Local subs :\t%D\t%D\n" ,(PetscInt)gmin[5],(PetscInt)gmax[5]);CHKERRQ(ierr); 23915579a77SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 24015579a77SStefano Zampini 24115579a77SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 24215579a77SStefano Zampini 24315579a77SStefano Zampini /* local solvers */ 24415579a77SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscObjectComm((PetscObject)pcbddc->ksp_D),&subviewer);CHKERRQ(ierr); 24515579a77SStefano Zampini if (!rank) { 24615579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Interior solver (rank 0)\n");CHKERRQ(ierr); 24715579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 24815579a77SStefano Zampini ierr = KSPView(pcbddc->ksp_D,subviewer);CHKERRQ(ierr); 24915579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 25015579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Correction solver (rank 0)\n");CHKERRQ(ierr); 25115579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 25215579a77SStefano Zampini ierr = KSPView(pcbddc->ksp_R,subviewer);CHKERRQ(ierr); 25315579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 25415579a77SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 25515579a77SStefano Zampini } 25615579a77SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscObjectComm((PetscObject)pcbddc->ksp_D),&subviewer);CHKERRQ(ierr); 25727b6a85dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 258e9627c49SStefano Zampini 259fbad9177SStefano Zampini /* the coarse problem can be handled by a different communicator */ 260e9627c49SStefano Zampini if (pcbddc->coarse_ksp) color = 1; 261e9627c49SStefano Zampini else color = 0; 2624b2aedd3SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 263e9627c49SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)pc),&subcomm);CHKERRQ(ierr); 2644b2aedd3SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,PetscMin(size,2));CHKERRQ(ierr); 265e9627c49SStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 266e9627c49SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 267e9627c49SStefano Zampini if (color == 1) { 26815579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Coarse solver\n");CHKERRQ(ierr); 26915579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 270e9627c49SStefano Zampini ierr = KSPView(pcbddc->coarse_ksp,subviewer);CHKERRQ(ierr); 27115579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 272e9627c49SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 273e9627c49SStefano Zampini } 274e9627c49SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 275e9627c49SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 276e9627c49SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 277e9627c49SStefano Zampini } 2786b78500eSPatrick Sanan PetscFunctionReturn(0); 2796b78500eSPatrick Sanan } 280a13144ffSStefano Zampini 2811e0482f5SStefano Zampini static PetscErrorCode PCBDDCSetDiscreteGradient_BDDC(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 282a13144ffSStefano Zampini { 283a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 284a13144ffSStefano Zampini PetscErrorCode ierr; 285a13144ffSStefano Zampini 286a13144ffSStefano Zampini PetscFunctionBegin; 287a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr); 288a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 289a13144ffSStefano Zampini pcbddc->discretegradient = G; 290a13144ffSStefano Zampini pcbddc->nedorder = order > 0 ? order : -order; 291495a2a07SStefano Zampini pcbddc->nedfield = field; 2921e0482f5SStefano Zampini pcbddc->nedglobal = global; 2931e0482f5SStefano Zampini pcbddc->conforming = conforming; 294a13144ffSStefano Zampini PetscFunctionReturn(0); 295a13144ffSStefano Zampini } 296a13144ffSStefano Zampini 297a13144ffSStefano Zampini /*@ 298a13144ffSStefano Zampini PCBDDCSetDiscreteGradient - Sets the discrete gradient 299a13144ffSStefano Zampini 300a13144ffSStefano Zampini Collective on PC 301a13144ffSStefano Zampini 302a13144ffSStefano Zampini Input Parameters: 303a13144ffSStefano Zampini + pc - the preconditioning context 304a13144ffSStefano Zampini . G - the discrete gradient matrix (should be in AIJ format) 305a13144ffSStefano Zampini . order - the order of the Nedelec space (1 for the lowest order) 306495a2a07SStefano Zampini . field - the field id of the Nedelec dofs (not used if the fields have not been specified) 3071e0482f5SStefano Zampini . global - the type of global ordering for the rows of G 308a13144ffSStefano Zampini - conforming - whether the mesh is conforming or not 309a13144ffSStefano Zampini 310a13144ffSStefano Zampini Level: advanced 311a13144ffSStefano Zampini 31295452b02SPatrick Sanan Notes: 31395452b02SPatrick Sanan The discrete gradient matrix G is used to analyze the subdomain edges, and it should not contain any zero entry. 314495a2a07SStefano Zampini For variable order spaces, the order should be set to zero. 3151e0482f5SStefano Zampini If global is true, the rows of G should be given in global ordering for the whole dofs; 3161e0482f5SStefano Zampini if false, the ordering should be global for the Nedelec field. 3171e0482f5SStefano 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 3181e0482f5SStefano Zampini and geid the one for the Nedelec field. 319a13144ffSStefano Zampini 320495a2a07SStefano Zampini .seealso: PCBDDC,PCBDDCSetDofsSplitting(),PCBDDCSetDofsSplittingLocal() 321a13144ffSStefano Zampini @*/ 3221e0482f5SStefano Zampini PetscErrorCode PCBDDCSetDiscreteGradient(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 323a13144ffSStefano Zampini { 324a13144ffSStefano Zampini PetscErrorCode ierr; 325a13144ffSStefano Zampini 326a13144ffSStefano Zampini PetscFunctionBegin; 327a13144ffSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 328a13144ffSStefano Zampini PetscValidHeaderSpecific(G,MAT_CLASSID,2); 329a13144ffSStefano Zampini PetscValidLogicalCollectiveInt(pc,order,3); 3301e0482f5SStefano Zampini PetscValidLogicalCollectiveInt(pc,field,4); 3311e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,global,5); 3321e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,conforming,6); 3331e0482f5SStefano Zampini PetscCheckSameComm(pc,1,G,2); 3341e0482f5SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDiscreteGradient_C",(PC,Mat,PetscInt,PetscInt,PetscBool,PetscBool),(pc,G,order,field,global,conforming));CHKERRQ(ierr); 335a13144ffSStefano Zampini PetscFunctionReturn(0); 336a13144ffSStefano Zampini } 337a13144ffSStefano Zampini 3388ae0ca82SStefano Zampini static PetscErrorCode PCBDDCSetDivergenceMat_BDDC(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 339a198735bSStefano Zampini { 340a198735bSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 341a198735bSStefano Zampini PetscErrorCode ierr; 3426b78500eSPatrick Sanan 343a198735bSStefano Zampini PetscFunctionBegin; 344a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)divudotp);CHKERRQ(ierr); 345a198735bSStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 346a198735bSStefano Zampini pcbddc->divudotp = divudotp; 3478ae0ca82SStefano Zampini pcbddc->divudotp_trans = trans; 348a198735bSStefano Zampini pcbddc->compute_nonetflux = PETSC_TRUE; 349a198735bSStefano Zampini if (vl2l) { 350a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2l);CHKERRQ(ierr); 351fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 352a198735bSStefano Zampini pcbddc->divudotp_vl2l = vl2l; 353a198735bSStefano Zampini } 354a198735bSStefano Zampini PetscFunctionReturn(0); 355a198735bSStefano Zampini } 3563d996552SStefano Zampini 357a198735bSStefano Zampini /*@ 358a198735bSStefano Zampini PCBDDCSetDivergenceMat - Sets the linear operator representing \int_\Omega \div {\bf u} \cdot p dx 359a198735bSStefano Zampini 360a198735bSStefano Zampini Collective on PC 361a198735bSStefano Zampini 362a198735bSStefano Zampini Input Parameters: 363a198735bSStefano Zampini + pc - the preconditioning context 364a198735bSStefano Zampini . divudotp - the matrix (must be of type MATIS) 3658ae0ca82SStefano Zampini . trans - if trans if false (resp. true), then pressures are in the test (trial) space and velocities are in the trial (test) space. 36605a3bf82SStefano 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 367a198735bSStefano Zampini 368a198735bSStefano Zampini Level: advanced 369a198735bSStefano Zampini 37095452b02SPatrick Sanan Notes: 37195452b02SPatrick Sanan This auxiliary matrix is used to compute quadrature weights representing the net-flux across subdomain boundaries 37205a3bf82SStefano Zampini If vl2l is NULL, the local ordering for velocities in divudotp should match that of the preconditioning matrix 373a198735bSStefano Zampini 374a198735bSStefano Zampini .seealso: PCBDDC 375a198735bSStefano Zampini @*/ 3768ae0ca82SStefano Zampini PetscErrorCode PCBDDCSetDivergenceMat(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 377a198735bSStefano Zampini { 378a198735bSStefano Zampini PetscBool ismatis; 379a198735bSStefano Zampini PetscErrorCode ierr; 380a198735bSStefano Zampini 381a198735bSStefano Zampini PetscFunctionBegin; 382a198735bSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 383a198735bSStefano Zampini PetscValidHeaderSpecific(divudotp,MAT_CLASSID,2); 384a198735bSStefano Zampini PetscCheckSameComm(pc,1,divudotp,2); 3858ae0ca82SStefano Zampini PetscValidLogicalCollectiveBool(pc,trans,3); 3861b24a7afSStefano Zampini if (vl2l) PetscValidHeaderSpecific(vl2l,IS_CLASSID,4); 387a198735bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)divudotp,MATIS,&ismatis);CHKERRQ(ierr); 388a198735bSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Divergence matrix needs to be of type MATIS"); 3898ae0ca82SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDivergenceMat_C",(PC,Mat,PetscBool,IS),(pc,divudotp,trans,vl2l));CHKERRQ(ierr); 390a198735bSStefano Zampini PetscFunctionReturn(0); 391a198735bSStefano Zampini } 3922d505d7fSStefano Zampini 3931dd7afcfSStefano Zampini static PetscErrorCode PCBDDCSetChangeOfBasisMat_BDDC(PC pc, Mat change, PetscBool interior) 394b9b85e73SStefano Zampini { 395b9b85e73SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 396b9b85e73SStefano Zampini PetscErrorCode ierr; 397b9b85e73SStefano Zampini 398b9b85e73SStefano Zampini PetscFunctionBegin; 399b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)change);CHKERRQ(ierr); 40056282151SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 401b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = change; 4021dd7afcfSStefano Zampini pcbddc->change_interior = interior; 403b9b85e73SStefano Zampini PetscFunctionReturn(0); 404b9b85e73SStefano Zampini } 405b9b85e73SStefano Zampini /*@ 406906d46d4SStefano Zampini PCBDDCSetChangeOfBasisMat - Set user defined change of basis for dofs 407b9b85e73SStefano Zampini 408b9b85e73SStefano Zampini Collective on PC 409b9b85e73SStefano Zampini 410b9b85e73SStefano Zampini Input Parameters: 411b9b85e73SStefano Zampini + pc - the preconditioning context 4121dd7afcfSStefano Zampini . change - the change of basis matrix 4131dd7afcfSStefano Zampini - interior - whether or not the change of basis modifies interior dofs 414b9b85e73SStefano Zampini 415b9b85e73SStefano Zampini Level: intermediate 416b9b85e73SStefano Zampini 417b9b85e73SStefano Zampini Notes: 418b9b85e73SStefano Zampini 419b9b85e73SStefano Zampini .seealso: PCBDDC 420b9b85e73SStefano Zampini @*/ 4211dd7afcfSStefano Zampini PetscErrorCode PCBDDCSetChangeOfBasisMat(PC pc, Mat change, PetscBool interior) 422b9b85e73SStefano Zampini { 423b9b85e73SStefano Zampini PetscErrorCode ierr; 424b9b85e73SStefano Zampini 425b9b85e73SStefano Zampini PetscFunctionBegin; 426b9b85e73SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 427b9b85e73SStefano Zampini PetscValidHeaderSpecific(change,MAT_CLASSID,2); 428906d46d4SStefano Zampini PetscCheckSameComm(pc,1,change,2); 429906d46d4SStefano Zampini if (pc->mat) { 430906d46d4SStefano Zampini PetscInt rows_c,cols_c,rows,cols; 431906d46d4SStefano Zampini ierr = MatGetSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 432906d46d4SStefano Zampini ierr = MatGetSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 433e0fe2d75SToby 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); 434e0fe2d75SToby 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); 435906d46d4SStefano Zampini ierr = MatGetLocalSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 436906d46d4SStefano Zampini ierr = MatGetLocalSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 437e0fe2d75SToby 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); 438e0fe2d75SToby 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); 439906d46d4SStefano Zampini } 4401dd7afcfSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetChangeOfBasisMat_C",(PC,Mat,PetscBool),(pc,change,interior));CHKERRQ(ierr); 441b9b85e73SStefano Zampini PetscFunctionReturn(0); 442b9b85e73SStefano Zampini } 4432d505d7fSStefano Zampini 44430368db7SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesIS_BDDC(PC pc, IS PrimalVertices) 44530368db7SStefano Zampini { 44630368db7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 44756282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 44830368db7SStefano Zampini PetscErrorCode ierr; 44930368db7SStefano Zampini 45030368db7SStefano Zampini PetscFunctionBegin; 45156282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 45256282151SStefano Zampini if (pcbddc->user_primal_vertices) { 45356282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices,&isequal);CHKERRQ(ierr); 45456282151SStefano Zampini } 45530368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 45630368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 45730368db7SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 45856282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 45930368db7SStefano Zampini PetscFunctionReturn(0); 46030368db7SStefano Zampini } 461ab8c8b98SStefano Zampini 46230368db7SStefano Zampini /*@ 46330368db7SStefano Zampini PCBDDCSetPrimalVerticesIS - Set additional user defined primal vertices in PCBDDC 46430368db7SStefano Zampini 46530368db7SStefano Zampini Collective 46630368db7SStefano Zampini 46730368db7SStefano Zampini Input Parameters: 46830368db7SStefano Zampini + pc - the preconditioning context 46930368db7SStefano Zampini - PrimalVertices - index set of primal vertices in global numbering (can be empty) 47030368db7SStefano Zampini 47130368db7SStefano Zampini Level: intermediate 47230368db7SStefano Zampini 47330368db7SStefano Zampini Notes: 47430368db7SStefano Zampini Any process can list any global node 47530368db7SStefano Zampini 4763100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCGetPrimalVerticesIS(), PCBDDCSetPrimalVerticesLocalIS(), PCBDDCGetPrimalVerticesLocalIS() 47730368db7SStefano Zampini @*/ 47830368db7SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesIS(PC pc, IS PrimalVertices) 47930368db7SStefano Zampini { 48030368db7SStefano Zampini PetscErrorCode ierr; 48130368db7SStefano Zampini 48230368db7SStefano Zampini PetscFunctionBegin; 48330368db7SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 48430368db7SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 48530368db7SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 48630368db7SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 48730368db7SStefano Zampini PetscFunctionReturn(0); 48830368db7SStefano Zampini } 4892d505d7fSStefano Zampini 4903100ebe3SStefano Zampini static PetscErrorCode PCBDDCGetPrimalVerticesIS_BDDC(PC pc, IS *is) 4913100ebe3SStefano Zampini { 4923100ebe3SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4933100ebe3SStefano Zampini 4943100ebe3SStefano Zampini PetscFunctionBegin; 4953100ebe3SStefano Zampini *is = pcbddc->user_primal_vertices; 4963100ebe3SStefano Zampini PetscFunctionReturn(0); 4973100ebe3SStefano Zampini } 4983100ebe3SStefano Zampini 4993100ebe3SStefano Zampini /*@ 5003100ebe3SStefano Zampini PCBDDCGetPrimalVerticesIS - Get user defined primal vertices set with PCBDDCSetPrimalVerticesIS() 5013100ebe3SStefano Zampini 5023100ebe3SStefano Zampini Collective 5033100ebe3SStefano Zampini 5043100ebe3SStefano Zampini Input Parameters: 5053100ebe3SStefano Zampini . pc - the preconditioning context 5063100ebe3SStefano Zampini 5073100ebe3SStefano Zampini Output Parameters: 5083100ebe3SStefano Zampini . is - index set of primal vertices in global numbering (NULL if not set) 5093100ebe3SStefano Zampini 5103100ebe3SStefano Zampini Level: intermediate 5113100ebe3SStefano Zampini 5123100ebe3SStefano Zampini Notes: 5133100ebe3SStefano Zampini 5143100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCSetPrimalVerticesIS(), PCBDDCSetPrimalVerticesLocalIS(), PCBDDCGetPrimalVerticesLocalIS() 5153100ebe3SStefano Zampini @*/ 5163100ebe3SStefano Zampini PetscErrorCode PCBDDCGetPrimalVerticesIS(PC pc, IS *is) 5173100ebe3SStefano Zampini { 5183100ebe3SStefano Zampini PetscErrorCode ierr; 5193100ebe3SStefano Zampini 5203100ebe3SStefano Zampini PetscFunctionBegin; 5213100ebe3SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5223100ebe3SStefano Zampini PetscValidPointer(is,2); 5233100ebe3SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetPrimalVerticesIS_C",(PC,IS*),(pc,is));CHKERRQ(ierr); 5243100ebe3SStefano Zampini PetscFunctionReturn(0); 5253100ebe3SStefano Zampini } 5263100ebe3SStefano Zampini 527674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 528674ae819SStefano Zampini { 529674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 53056282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 531674ae819SStefano Zampini PetscErrorCode ierr; 5321e6b0712SBarry Smith 533674ae819SStefano Zampini PetscFunctionBegin; 53456282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 53556282151SStefano Zampini if (pcbddc->user_primal_vertices_local) { 53656282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices_local,&isequal);CHKERRQ(ierr); 53756282151SStefano Zampini } 538674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 53930368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 54030368db7SStefano Zampini pcbddc->user_primal_vertices_local = PrimalVertices; 54156282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 542674ae819SStefano Zampini PetscFunctionReturn(0); 543674ae819SStefano Zampini } 5443100ebe3SStefano Zampini 545674ae819SStefano Zampini /*@ 54628509bceSStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC 547674ae819SStefano Zampini 54817eb1463SStefano Zampini Collective 549674ae819SStefano Zampini 550674ae819SStefano Zampini Input Parameters: 551674ae819SStefano Zampini + pc - the preconditioning context 55217eb1463SStefano Zampini - PrimalVertices - index set of primal vertices in local numbering (can be empty) 553674ae819SStefano Zampini 554674ae819SStefano Zampini Level: intermediate 555674ae819SStefano Zampini 556674ae819SStefano Zampini Notes: 557674ae819SStefano Zampini 5583100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCSetPrimalVerticesIS(), PCBDDCGetPrimalVerticesIS(), PCBDDCGetPrimalVerticesLocalIS() 559674ae819SStefano Zampini @*/ 560674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 561674ae819SStefano Zampini { 562674ae819SStefano Zampini PetscErrorCode ierr; 563674ae819SStefano Zampini 564674ae819SStefano Zampini PetscFunctionBegin; 565674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 566674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 56717eb1463SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 568674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 569674ae819SStefano Zampini PetscFunctionReturn(0); 570674ae819SStefano Zampini } 5712d505d7fSStefano Zampini 5723100ebe3SStefano Zampini static PetscErrorCode PCBDDCGetPrimalVerticesLocalIS_BDDC(PC pc, IS *is) 5733100ebe3SStefano Zampini { 5743100ebe3SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5753100ebe3SStefano Zampini 5763100ebe3SStefano Zampini PetscFunctionBegin; 5773100ebe3SStefano Zampini *is = pcbddc->user_primal_vertices_local; 5783100ebe3SStefano Zampini PetscFunctionReturn(0); 5793100ebe3SStefano Zampini } 5803100ebe3SStefano Zampini 5813100ebe3SStefano Zampini /*@ 5823100ebe3SStefano Zampini PCBDDCGetPrimalVerticesLocalIS - Get user defined primal vertices set with PCBDDCSetPrimalVerticesLocalIS() 5833100ebe3SStefano Zampini 5843100ebe3SStefano Zampini Collective 5853100ebe3SStefano Zampini 5863100ebe3SStefano Zampini Input Parameters: 5873100ebe3SStefano Zampini . pc - the preconditioning context 5883100ebe3SStefano Zampini 5893100ebe3SStefano Zampini Output Parameters: 5903100ebe3SStefano Zampini . is - index set of primal vertices in local numbering (NULL if not set) 5913100ebe3SStefano Zampini 5923100ebe3SStefano Zampini Level: intermediate 5933100ebe3SStefano Zampini 5943100ebe3SStefano Zampini Notes: 5953100ebe3SStefano Zampini 5963100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCSetPrimalVerticesIS(), PCBDDCGetPrimalVerticesIS(), PCBDDCSetPrimalVerticesLocalIS() 5973100ebe3SStefano Zampini @*/ 5983100ebe3SStefano Zampini PetscErrorCode PCBDDCGetPrimalVerticesLocalIS(PC pc, IS *is) 5993100ebe3SStefano Zampini { 6003100ebe3SStefano Zampini PetscErrorCode ierr; 6013100ebe3SStefano Zampini 6023100ebe3SStefano Zampini PetscFunctionBegin; 6033100ebe3SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6043100ebe3SStefano Zampini PetscValidPointer(is,2); 6053100ebe3SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetPrimalVerticesLocalIS_C",(PC,IS*),(pc,is));CHKERRQ(ierr); 6063100ebe3SStefano Zampini PetscFunctionReturn(0); 6073100ebe3SStefano Zampini } 6083100ebe3SStefano Zampini 6094fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 6104fad6a16SStefano Zampini { 6114fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6124fad6a16SStefano Zampini 6134fad6a16SStefano Zampini PetscFunctionBegin; 6144fad6a16SStefano Zampini pcbddc->coarsening_ratio = k; 6154fad6a16SStefano Zampini PetscFunctionReturn(0); 6164fad6a16SStefano Zampini } 6171e6b0712SBarry Smith 6184fad6a16SStefano Zampini /*@ 61928509bceSStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel 6204fad6a16SStefano Zampini 6214fad6a16SStefano Zampini Logically collective on PC 6224fad6a16SStefano Zampini 6234fad6a16SStefano Zampini Input Parameters: 6244fad6a16SStefano Zampini + pc - the preconditioning context 62528509bceSStefano Zampini - k - coarsening ratio (H/h at the coarser level) 6264fad6a16SStefano Zampini 6270f202f7eSStefano Zampini Options Database Keys: 6280f202f7eSStefano Zampini . -pc_bddc_coarsening_ratio 6294fad6a16SStefano Zampini 6304fad6a16SStefano Zampini Level: intermediate 6314fad6a16SStefano Zampini 6324fad6a16SStefano Zampini Notes: 6330f202f7eSStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level 6344fad6a16SStefano Zampini 6350f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetLevels() 6364fad6a16SStefano Zampini @*/ 6374fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 6384fad6a16SStefano Zampini { 6394fad6a16SStefano Zampini PetscErrorCode ierr; 6404fad6a16SStefano Zampini 6414fad6a16SStefano Zampini PetscFunctionBegin; 6424fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6432b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,k,2); 6444fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 6454fad6a16SStefano Zampini PetscFunctionReturn(0); 6464fad6a16SStefano Zampini } 6472b510759SStefano Zampini 648b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */ 649b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg) 650b8ffe317SStefano Zampini { 651b8ffe317SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 652b8ffe317SStefano Zampini 653b8ffe317SStefano Zampini PetscFunctionBegin; 65485c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = flg; 655b8ffe317SStefano Zampini PetscFunctionReturn(0); 656b8ffe317SStefano Zampini } 657b8ffe317SStefano Zampini 658b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg) 6592b510759SStefano Zampini { 6602b510759SStefano Zampini PetscErrorCode ierr; 6612b510759SStefano Zampini 6622b510759SStefano Zampini PetscFunctionBegin; 6632b510759SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 664b8ffe317SStefano Zampini PetscValidLogicalCollectiveBool(pc,flg,2); 665b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr); 6662b510759SStefano Zampini PetscFunctionReturn(0); 6672b510759SStefano Zampini } 6681e6b0712SBarry Smith 6692b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level) 6704fad6a16SStefano Zampini { 6714fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6724fad6a16SStefano Zampini 6734fad6a16SStefano Zampini PetscFunctionBegin; 6742b510759SStefano Zampini pcbddc->current_level = level; 6754fad6a16SStefano Zampini PetscFunctionReturn(0); 6764fad6a16SStefano Zampini } 6771e6b0712SBarry Smith 678b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 679b8ffe317SStefano Zampini { 680b8ffe317SStefano Zampini PetscErrorCode ierr; 681b8ffe317SStefano Zampini 682b8ffe317SStefano Zampini PetscFunctionBegin; 683b8ffe317SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 684b8ffe317SStefano Zampini PetscValidLogicalCollectiveInt(pc,level,2); 685b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr); 686b8ffe317SStefano Zampini PetscFunctionReturn(0); 687b8ffe317SStefano Zampini } 688b8ffe317SStefano Zampini 6892b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels) 6902b510759SStefano Zampini { 6912b510759SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6922b510759SStefano Zampini 6932b510759SStefano Zampini PetscFunctionBegin; 6946080607fSStefano Zampini if (levels > PETSC_PCBDDC_MAXLEVELS-1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Maximum number of additional levels for BDDC is %d",PETSC_PCBDDC_MAXLEVELS-1); 6952b510759SStefano Zampini pcbddc->max_levels = levels; 6962b510759SStefano Zampini PetscFunctionReturn(0); 6972b510759SStefano Zampini } 6982b510759SStefano Zampini 6994fad6a16SStefano Zampini /*@ 70037ebbdf7SStefano Zampini PCBDDCSetLevels - Sets the maximum number of additional levels allowed for multilevel BDDC 7014fad6a16SStefano Zampini 7024fad6a16SStefano Zampini Logically collective on PC 7034fad6a16SStefano Zampini 7044fad6a16SStefano Zampini Input Parameters: 7054fad6a16SStefano Zampini + pc - the preconditioning context 70637ebbdf7SStefano Zampini - levels - the maximum number of levels 7074fad6a16SStefano Zampini 7080f202f7eSStefano Zampini Options Database Keys: 7090f202f7eSStefano Zampini . -pc_bddc_levels 7104fad6a16SStefano Zampini 7114fad6a16SStefano Zampini Level: intermediate 7124fad6a16SStefano Zampini 7134fad6a16SStefano Zampini Notes: 71437ebbdf7SStefano Zampini The default value is 0, that gives the classical two-levels BDDC 7154fad6a16SStefano Zampini 7160f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetCoarseningRatio() 7174fad6a16SStefano Zampini @*/ 7182b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels) 7194fad6a16SStefano Zampini { 7204fad6a16SStefano Zampini PetscErrorCode ierr; 7214fad6a16SStefano Zampini 7224fad6a16SStefano Zampini PetscFunctionBegin; 7234fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 7242b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,levels,2); 7252b510759SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr); 7264fad6a16SStefano Zampini PetscFunctionReturn(0); 7274fad6a16SStefano Zampini } 7281e6b0712SBarry Smith 7293b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 7303b03a366Sstefano_zampini { 7313b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 73256282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 7333b03a366Sstefano_zampini PetscErrorCode ierr; 7343b03a366Sstefano_zampini 7353b03a366Sstefano_zampini PetscFunctionBegin; 73656282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 73756282151SStefano Zampini if (pcbddc->DirichletBoundaries) { 73856282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundaries,&isequal);CHKERRQ(ierr); 73956282151SStefano Zampini } 740785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 741785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 7423b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 74336e030ebSStefano Zampini pcbddc->DirichletBoundaries = DirichletBoundaries; 74456282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7453b03a366Sstefano_zampini PetscFunctionReturn(0); 7463b03a366Sstefano_zampini } 7471e6b0712SBarry Smith 7483b03a366Sstefano_zampini /*@ 74928509bceSStefano Zampini PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem. 7503b03a366Sstefano_zampini 751785d1243SStefano Zampini Collective 7523b03a366Sstefano_zampini 7533b03a366Sstefano_zampini Input Parameters: 7543b03a366Sstefano_zampini + pc - the preconditioning context 755785d1243SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries 7563b03a366Sstefano_zampini 7573b03a366Sstefano_zampini Level: intermediate 7583b03a366Sstefano_zampini 7590f202f7eSStefano Zampini Notes: 7600f202f7eSStefano Zampini Provide the information if you used MatZeroRows/Columns routines. Any process can list any global node 7613b03a366Sstefano_zampini 7620f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundariesLocal(), MatZeroRows(), MatZeroRowsColumns() 7633b03a366Sstefano_zampini @*/ 7643b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 7653b03a366Sstefano_zampini { 7663b03a366Sstefano_zampini PetscErrorCode ierr; 7673b03a366Sstefano_zampini 7683b03a366Sstefano_zampini PetscFunctionBegin; 7693b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 770674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 771785d1243SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 7723b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 7733b03a366Sstefano_zampini PetscFunctionReturn(0); 7743b03a366Sstefano_zampini } 7751e6b0712SBarry Smith 77682ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries) 7773b03a366Sstefano_zampini { 7783b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 77956282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 7803b03a366Sstefano_zampini PetscErrorCode ierr; 7813b03a366Sstefano_zampini 7823b03a366Sstefano_zampini PetscFunctionBegin; 78356282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 78456282151SStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 78556282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundariesLocal,&isequal);CHKERRQ(ierr); 78656282151SStefano Zampini } 787785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 788785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 7893b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 790785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = DirichletBoundaries; 79156282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7923b03a366Sstefano_zampini PetscFunctionReturn(0); 7933b03a366Sstefano_zampini } 7943b03a366Sstefano_zampini 7953b03a366Sstefano_zampini /*@ 79682ba6b80SStefano Zampini PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering. 7973b03a366Sstefano_zampini 798785d1243SStefano Zampini Collective 7993b03a366Sstefano_zampini 8003b03a366Sstefano_zampini Input Parameters: 8013b03a366Sstefano_zampini + pc - the preconditioning context 80282ba6b80SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering) 8033b03a366Sstefano_zampini 8043b03a366Sstefano_zampini Level: intermediate 8053b03a366Sstefano_zampini 8063b03a366Sstefano_zampini Notes: 8073b03a366Sstefano_zampini 8080f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundaries(), MatZeroRows(), MatZeroRowsColumns() 8093b03a366Sstefano_zampini @*/ 81082ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries) 8113b03a366Sstefano_zampini { 8123b03a366Sstefano_zampini PetscErrorCode ierr; 8133b03a366Sstefano_zampini 8143b03a366Sstefano_zampini PetscFunctionBegin; 8153b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 8163b03a366Sstefano_zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 81782ba6b80SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 81882ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 8193b03a366Sstefano_zampini PetscFunctionReturn(0); 8203b03a366Sstefano_zampini } 8213b03a366Sstefano_zampini 82253cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 8230c7d97c5SJed Brown { 8240c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 82556282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 82653cdbc3dSStefano Zampini PetscErrorCode ierr; 8270c7d97c5SJed Brown 8280c7d97c5SJed Brown PetscFunctionBegin; 82956282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 83056282151SStefano Zampini if (pcbddc->NeumannBoundaries) { 83156282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundaries,&isequal);CHKERRQ(ierr); 83256282151SStefano Zampini } 833785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 834785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 83553cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 83636e030ebSStefano Zampini pcbddc->NeumannBoundaries = NeumannBoundaries; 83756282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 8380c7d97c5SJed Brown PetscFunctionReturn(0); 8390c7d97c5SJed Brown } 8401e6b0712SBarry Smith 84157527edcSJed Brown /*@ 84228509bceSStefano Zampini PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem. 84357527edcSJed Brown 844785d1243SStefano Zampini Collective 84557527edcSJed Brown 84657527edcSJed Brown Input Parameters: 84757527edcSJed Brown + pc - the preconditioning context 848785d1243SStefano Zampini - NeumannBoundaries - parallel IS defining the Neumann boundaries 84957527edcSJed Brown 85057527edcSJed Brown Level: intermediate 85157527edcSJed Brown 8520f202f7eSStefano Zampini Notes: 8530f202f7eSStefano Zampini Any process can list any global node 85457527edcSJed Brown 8550f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundariesLocal() 85657527edcSJed Brown @*/ 85753cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 8580c7d97c5SJed Brown { 8590c7d97c5SJed Brown PetscErrorCode ierr; 8600c7d97c5SJed Brown 8610c7d97c5SJed Brown PetscFunctionBegin; 8620c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 863674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 864785d1243SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 86553cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 86653cdbc3dSStefano Zampini PetscFunctionReturn(0); 86753cdbc3dSStefano Zampini } 8681e6b0712SBarry Smith 86982ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries) 8700c7d97c5SJed Brown { 8710c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 87256282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 8730c7d97c5SJed Brown PetscErrorCode ierr; 8740c7d97c5SJed Brown 8750c7d97c5SJed Brown PetscFunctionBegin; 87656282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 87756282151SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 87856282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundariesLocal,&isequal);CHKERRQ(ierr); 87956282151SStefano Zampini } 880785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 881785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 8820c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 883785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = NeumannBoundaries; 88456282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 8850c7d97c5SJed Brown PetscFunctionReturn(0); 8860c7d97c5SJed Brown } 8870c7d97c5SJed Brown 8880c7d97c5SJed Brown /*@ 88982ba6b80SStefano Zampini PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering. 8900c7d97c5SJed Brown 891785d1243SStefano Zampini Collective 8920c7d97c5SJed Brown 8930c7d97c5SJed Brown Input Parameters: 8940c7d97c5SJed Brown + pc - the preconditioning context 89582ba6b80SStefano Zampini - NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering) 8960c7d97c5SJed Brown 8970c7d97c5SJed Brown Level: intermediate 8980c7d97c5SJed Brown 8990c7d97c5SJed Brown Notes: 9000c7d97c5SJed Brown 9010f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundaries() 9020c7d97c5SJed Brown @*/ 90382ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries) 9040c7d97c5SJed Brown { 9050c7d97c5SJed Brown PetscErrorCode ierr; 9060c7d97c5SJed Brown 9070c7d97c5SJed Brown PetscFunctionBegin; 9080c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 9090c7d97c5SJed Brown PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 91082ba6b80SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 91182ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 91253cdbc3dSStefano Zampini PetscFunctionReturn(0); 91353cdbc3dSStefano Zampini } 91453cdbc3dSStefano Zampini 915da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 916da1bb401SStefano Zampini { 917da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 918da1bb401SStefano Zampini 919da1bb401SStefano Zampini PetscFunctionBegin; 920da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 921da1bb401SStefano Zampini PetscFunctionReturn(0); 922da1bb401SStefano Zampini } 9231e6b0712SBarry Smith 924da1bb401SStefano Zampini /*@ 925785d1243SStefano Zampini PCBDDCGetDirichletBoundaries - Get parallel IS for Dirichlet boundaries 926da1bb401SStefano Zampini 927785d1243SStefano Zampini Collective 928785d1243SStefano Zampini 929785d1243SStefano Zampini Input Parameters: 930785d1243SStefano Zampini . pc - the preconditioning context 931785d1243SStefano Zampini 932785d1243SStefano Zampini Output Parameters: 933785d1243SStefano Zampini . DirichletBoundaries - index set defining the Dirichlet boundaries 934785d1243SStefano Zampini 935785d1243SStefano Zampini Level: intermediate 936785d1243SStefano Zampini 9370f202f7eSStefano Zampini Notes: 9380f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetDirichletBoundaries 939785d1243SStefano Zampini 940785d1243SStefano Zampini .seealso: PCBDDC 941785d1243SStefano Zampini @*/ 942785d1243SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 943785d1243SStefano Zampini { 944785d1243SStefano Zampini PetscErrorCode ierr; 945785d1243SStefano Zampini 946785d1243SStefano Zampini PetscFunctionBegin; 947785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 948785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 949785d1243SStefano Zampini PetscFunctionReturn(0); 950785d1243SStefano Zampini } 951785d1243SStefano Zampini 952785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries) 953785d1243SStefano Zampini { 954785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 955785d1243SStefano Zampini 956785d1243SStefano Zampini PetscFunctionBegin; 957785d1243SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundariesLocal; 958785d1243SStefano Zampini PetscFunctionReturn(0); 959785d1243SStefano Zampini } 960785d1243SStefano Zampini 961da1bb401SStefano Zampini /*@ 96282ba6b80SStefano Zampini PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering) 963da1bb401SStefano Zampini 964785d1243SStefano Zampini Collective 965da1bb401SStefano Zampini 966da1bb401SStefano Zampini Input Parameters: 96728509bceSStefano Zampini . pc - the preconditioning context 968da1bb401SStefano Zampini 969da1bb401SStefano Zampini Output Parameters: 97028509bceSStefano Zampini . DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 971da1bb401SStefano Zampini 972da1bb401SStefano Zampini Level: intermediate 973da1bb401SStefano Zampini 974da1bb401SStefano Zampini Notes: 9750f202f7eSStefano 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). 9760f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 977da1bb401SStefano Zampini 978da1bb401SStefano Zampini .seealso: PCBDDC 979da1bb401SStefano Zampini @*/ 98082ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries) 981da1bb401SStefano Zampini { 982da1bb401SStefano Zampini PetscErrorCode ierr; 983da1bb401SStefano Zampini 984da1bb401SStefano Zampini PetscFunctionBegin; 985da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 98682ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 987da1bb401SStefano Zampini PetscFunctionReturn(0); 988da1bb401SStefano Zampini } 9891e6b0712SBarry Smith 99053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 99153cdbc3dSStefano Zampini { 99253cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 99353cdbc3dSStefano Zampini 99453cdbc3dSStefano Zampini PetscFunctionBegin; 99553cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 99653cdbc3dSStefano Zampini PetscFunctionReturn(0); 99753cdbc3dSStefano Zampini } 9981e6b0712SBarry Smith 99953cdbc3dSStefano Zampini /*@ 1000785d1243SStefano Zampini PCBDDCGetNeumannBoundaries - Get parallel IS for Neumann boundaries 100153cdbc3dSStefano Zampini 1002785d1243SStefano Zampini Collective 1003785d1243SStefano Zampini 1004785d1243SStefano Zampini Input Parameters: 1005785d1243SStefano Zampini . pc - the preconditioning context 1006785d1243SStefano Zampini 1007785d1243SStefano Zampini Output Parameters: 1008785d1243SStefano Zampini . NeumannBoundaries - index set defining the Neumann boundaries 1009785d1243SStefano Zampini 1010785d1243SStefano Zampini Level: intermediate 1011785d1243SStefano Zampini 10120f202f7eSStefano Zampini Notes: 10130f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetNeumannBoundaries 1014785d1243SStefano Zampini 1015785d1243SStefano Zampini .seealso: PCBDDC 1016785d1243SStefano Zampini @*/ 1017785d1243SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 1018785d1243SStefano Zampini { 1019785d1243SStefano Zampini PetscErrorCode ierr; 1020785d1243SStefano Zampini 1021785d1243SStefano Zampini PetscFunctionBegin; 1022785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1023785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 1024785d1243SStefano Zampini PetscFunctionReturn(0); 1025785d1243SStefano Zampini } 1026785d1243SStefano Zampini 1027785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries) 1028785d1243SStefano Zampini { 1029785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1030785d1243SStefano Zampini 1031785d1243SStefano Zampini PetscFunctionBegin; 1032785d1243SStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundariesLocal; 1033785d1243SStefano Zampini PetscFunctionReturn(0); 1034785d1243SStefano Zampini } 1035785d1243SStefano Zampini 103653cdbc3dSStefano Zampini /*@ 103782ba6b80SStefano Zampini PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering) 103853cdbc3dSStefano Zampini 1039785d1243SStefano Zampini Collective 104053cdbc3dSStefano Zampini 104153cdbc3dSStefano Zampini Input Parameters: 104228509bceSStefano Zampini . pc - the preconditioning context 104353cdbc3dSStefano Zampini 104453cdbc3dSStefano Zampini Output Parameters: 104528509bceSStefano Zampini . NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 104653cdbc3dSStefano Zampini 104753cdbc3dSStefano Zampini Level: intermediate 104853cdbc3dSStefano Zampini 104953cdbc3dSStefano Zampini Notes: 10500f202f7eSStefano 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). 10510f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 105253cdbc3dSStefano Zampini 105353cdbc3dSStefano Zampini .seealso: PCBDDC 105453cdbc3dSStefano Zampini @*/ 105582ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries) 105653cdbc3dSStefano Zampini { 105753cdbc3dSStefano Zampini PetscErrorCode ierr; 105853cdbc3dSStefano Zampini 105953cdbc3dSStefano Zampini PetscFunctionBegin; 106053cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 106182ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 10620c7d97c5SJed Brown PetscFunctionReturn(0); 10630c7d97c5SJed Brown } 10641e6b0712SBarry Smith 10651a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 106636e030ebSStefano Zampini { 106736e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1068da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 106956282151SStefano Zampini PetscBool same_data = PETSC_FALSE; 1070da1bb401SStefano Zampini PetscErrorCode ierr; 107136e030ebSStefano Zampini 107236e030ebSStefano Zampini PetscFunctionBegin; 10738687889aSStefano Zampini if (!nvtxs) { 107404194a47SStefano Zampini if (copymode == PETSC_OWN_POINTER) { 107504194a47SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 107604194a47SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 107704194a47SStefano Zampini } 10788687889aSStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 10798687889aSStefano Zampini PetscFunctionReturn(0); 10808687889aSStefano Zampini } 108166da6bd7Sstefano_zampini if (mat_graph->nvtxs == nvtxs && mat_graph->freecsr) { /* we own the data */ 108256282151SStefano Zampini if (mat_graph->xadj == xadj && mat_graph->adjncy == adjncy) same_data = PETSC_TRUE; 108356282151SStefano Zampini if (!same_data && mat_graph->xadj[nvtxs] == xadj[nvtxs]) { 1084580bdb30SBarry Smith ierr = PetscArraycmp(xadj,mat_graph->xadj,nvtxs+1,&same_data);CHKERRQ(ierr); 10852d505d7fSStefano Zampini if (same_data) { 1086580bdb30SBarry Smith ierr = PetscArraycmp(adjncy,mat_graph->adjncy,xadj[nvtxs],&same_data);CHKERRQ(ierr); 10872d505d7fSStefano Zampini } 108856282151SStefano Zampini } 108956282151SStefano Zampini } 109056282151SStefano Zampini if (!same_data) { 1091674ae819SStefano Zampini /* free old CSR */ 1092674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 1093674ae819SStefano Zampini /* get CSR into graph structure */ 1094da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 1095854ce69bSBarry Smith ierr = PetscMalloc1(nvtxs+1,&mat_graph->xadj);CHKERRQ(ierr); 1096785e854fSJed Brown ierr = PetscMalloc1(xadj[nvtxs],&mat_graph->adjncy);CHKERRQ(ierr); 1097580bdb30SBarry Smith ierr = PetscArraycpy(mat_graph->xadj,xadj,nvtxs+1);CHKERRQ(ierr); 1098580bdb30SBarry Smith ierr = PetscArraycpy(mat_graph->adjncy,adjncy,xadj[nvtxs]);CHKERRQ(ierr); 1099a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 1100da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 11011a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 11021a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 1103a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 1104a1dbd327SStefano Zampini } else if (copymode == PETSC_USE_POINTER) { 1105a1dbd327SStefano Zampini mat_graph->xadj = (PetscInt*)xadj; 1106a1dbd327SStefano Zampini mat_graph->adjncy = (PetscInt*)adjncy; 1107a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_FALSE; 1108e0fe2d75SToby Isaac } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %D",copymode); 1109575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 111056282151SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 111156282151SStefano Zampini } 111236e030ebSStefano Zampini PetscFunctionReturn(0); 111336e030ebSStefano Zampini } 11141e6b0712SBarry Smith 111536e030ebSStefano Zampini /*@ 111654fffbccSStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local degrees of freedom. 111736e030ebSStefano Zampini 111836e030ebSStefano Zampini Not collective 111936e030ebSStefano Zampini 112036e030ebSStefano Zampini Input Parameters: 112154fffbccSStefano Zampini + pc - the preconditioning context. 112254fffbccSStefano Zampini . nvtxs - number of local vertices of the graph (i.e., the number of local dofs). 112354fffbccSStefano Zampini . xadj, adjncy - the connectivity of the dofs in CSR format. 112454fffbccSStefano Zampini - copymode - supported modes are PETSC_COPY_VALUES, PETSC_USE_POINTER or PETSC_OWN_POINTER. 112536e030ebSStefano Zampini 112636e030ebSStefano Zampini Level: intermediate 112736e030ebSStefano Zampini 112895452b02SPatrick Sanan Notes: 112995452b02SPatrick Sanan A dof is considered connected with all local dofs if xadj[dof+1]-xadj[dof] == 1 and adjncy[xadj[dof]] is negative. 113036e030ebSStefano Zampini 113128509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode 113236e030ebSStefano Zampini @*/ 11331a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 113436e030ebSStefano Zampini { 1135575ad6abSStefano Zampini void (*f)(void) = 0; 113636e030ebSStefano Zampini PetscErrorCode ierr; 113736e030ebSStefano Zampini 113836e030ebSStefano Zampini PetscFunctionBegin; 113936e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 11408687889aSStefano Zampini if (nvtxs) { 1141674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 11421633d1f0SStefano Zampini if (xadj[nvtxs]) PetscValidIntPointer(adjncy,4); 11438687889aSStefano Zampini } 11441a83f524SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 1145575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 1146575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 1147575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 1148575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 1149575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 1150da1bb401SStefano Zampini } 115136e030ebSStefano Zampini PetscFunctionReturn(0); 115236e030ebSStefano Zampini } 11531e6b0712SBarry Smith 115463602bcaSStefano Zampini static PetscErrorCode PCBDDCSetDofsSplittingLocal_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 115563602bcaSStefano Zampini { 115663602bcaSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 115763602bcaSStefano Zampini PetscInt i; 115856282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 115963602bcaSStefano Zampini PetscErrorCode ierr; 116063602bcaSStefano Zampini 116163602bcaSStefano Zampini PetscFunctionBegin; 116256282151SStefano Zampini if (pcbddc->n_ISForDofsLocal == n_is) { 116356282151SStefano Zampini for (i=0;i<n_is;i++) { 116456282151SStefano Zampini PetscBool isequalt; 116556282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofsLocal[i],&isequalt);CHKERRQ(ierr); 116656282151SStefano Zampini if (!isequalt) break; 116756282151SStefano Zampini } 116856282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 116956282151SStefano Zampini } 117056282151SStefano Zampini for (i=0;i<n_is;i++) { 117156282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 117256282151SStefano Zampini } 117363602bcaSStefano Zampini /* Destroy ISes if they were already set */ 117463602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 117563602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 117663602bcaSStefano Zampini } 117763602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 117863602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 117963602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 118063602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 118163602bcaSStefano Zampini } 118263602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 118363602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 118463602bcaSStefano Zampini /* allocate space then set */ 1185d02579f5SStefano Zampini if (n_is) { 1186d02579f5SStefano Zampini ierr = PetscMalloc1(n_is,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1187d02579f5SStefano Zampini } 118863602bcaSStefano Zampini for (i=0;i<n_is;i++) { 118963602bcaSStefano Zampini pcbddc->ISForDofsLocal[i] = ISForDofs[i]; 119063602bcaSStefano Zampini } 119163602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = n_is; 119263602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 119356282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 119463602bcaSStefano Zampini PetscFunctionReturn(0); 119563602bcaSStefano Zampini } 119663602bcaSStefano Zampini 119763602bcaSStefano Zampini /*@ 119863602bcaSStefano Zampini PCBDDCSetDofsSplittingLocal - Set index sets defining fields of the local subdomain matrix 119963602bcaSStefano Zampini 120063602bcaSStefano Zampini Collective 120163602bcaSStefano Zampini 120263602bcaSStefano Zampini Input Parameters: 120363602bcaSStefano Zampini + pc - the preconditioning context 12040f202f7eSStefano Zampini . n_is - number of index sets defining the fields 12050f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in local ordering 120663602bcaSStefano Zampini 120763602bcaSStefano Zampini Level: intermediate 120863602bcaSStefano Zampini 12090f202f7eSStefano Zampini Notes: 12100f202f7eSStefano Zampini n_is should be the same among processes. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 121163602bcaSStefano Zampini 121263602bcaSStefano Zampini .seealso: PCBDDC 121363602bcaSStefano Zampini @*/ 121463602bcaSStefano Zampini PetscErrorCode PCBDDCSetDofsSplittingLocal(PC pc,PetscInt n_is, IS ISForDofs[]) 121563602bcaSStefano Zampini { 121663602bcaSStefano Zampini PetscInt i; 121763602bcaSStefano Zampini PetscErrorCode ierr; 121863602bcaSStefano Zampini 121963602bcaSStefano Zampini PetscFunctionBegin; 122063602bcaSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 122163602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 122263602bcaSStefano Zampini for (i=0;i<n_is;i++) { 122363602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 122463602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 122563602bcaSStefano Zampini } 1226e71e7a71SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplittingLocal_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 122763602bcaSStefano Zampini PetscFunctionReturn(0); 122863602bcaSStefano Zampini } 122963602bcaSStefano Zampini 12309c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 12319c0446d6SStefano Zampini { 12329c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 12339c0446d6SStefano Zampini PetscInt i; 123456282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 12359c0446d6SStefano Zampini PetscErrorCode ierr; 12369c0446d6SStefano Zampini 12379c0446d6SStefano Zampini PetscFunctionBegin; 123856282151SStefano Zampini if (pcbddc->n_ISForDofs == n_is) { 123956282151SStefano Zampini for (i=0;i<n_is;i++) { 124056282151SStefano Zampini PetscBool isequalt; 124156282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofs[i],&isequalt);CHKERRQ(ierr); 124256282151SStefano Zampini if (!isequalt) break; 124356282151SStefano Zampini } 124456282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 124556282151SStefano Zampini } 124656282151SStefano Zampini for (i=0;i<n_is;i++) { 124756282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 124856282151SStefano Zampini } 1249da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 12509c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 12519c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 12529c0446d6SStefano Zampini } 1253d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 125463602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 125563602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 125663602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 125763602bcaSStefano Zampini } 125863602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 125963602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 1260da1bb401SStefano Zampini /* allocate space then set */ 1261d02579f5SStefano Zampini if (n_is) { 1262785e854fSJed Brown ierr = PetscMalloc1(n_is,&pcbddc->ISForDofs);CHKERRQ(ierr); 1263d02579f5SStefano Zampini } 12649c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 1265da1bb401SStefano Zampini pcbddc->ISForDofs[i] = ISForDofs[i]; 12669c0446d6SStefano Zampini } 12679c0446d6SStefano Zampini pcbddc->n_ISForDofs = n_is; 126863602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 126956282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 12709c0446d6SStefano Zampini PetscFunctionReturn(0); 12719c0446d6SStefano Zampini } 12721e6b0712SBarry Smith 12739c0446d6SStefano Zampini /*@ 127463602bcaSStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of the global matrix 12759c0446d6SStefano Zampini 127663602bcaSStefano Zampini Collective 12779c0446d6SStefano Zampini 12789c0446d6SStefano Zampini Input Parameters: 12799c0446d6SStefano Zampini + pc - the preconditioning context 12800f202f7eSStefano Zampini . n_is - number of index sets defining the fields 12810f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in global ordering 12829c0446d6SStefano Zampini 12839c0446d6SStefano Zampini Level: intermediate 12849c0446d6SStefano Zampini 12850f202f7eSStefano Zampini Notes: 12860f202f7eSStefano Zampini Any process can list any global node. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 12879c0446d6SStefano Zampini 12889c0446d6SStefano Zampini .seealso: PCBDDC 12899c0446d6SStefano Zampini @*/ 12909c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 12919c0446d6SStefano Zampini { 12922b510759SStefano Zampini PetscInt i; 12939c0446d6SStefano Zampini PetscErrorCode ierr; 12949c0446d6SStefano Zampini 12959c0446d6SStefano Zampini PetscFunctionBegin; 12969c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 129763602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 12982b510759SStefano Zampini for (i=0;i<n_is;i++) { 129963602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 1300a011d5a7Sstefano_zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 13012b510759SStefano Zampini } 13029c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 13039c0446d6SStefano Zampini PetscFunctionReturn(0); 13049c0446d6SStefano Zampini } 1305906d46d4SStefano Zampini 1306534831adSStefano Zampini /* 1307534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 1308534831adSStefano Zampini guess if a transformation of basis approach has been selected. 13099c0446d6SStefano Zampini 1310534831adSStefano Zampini Input Parameter: 1311534831adSStefano Zampini + pc - the preconditioner contex 1312534831adSStefano Zampini 1313534831adSStefano Zampini Application Interface Routine: PCPreSolve() 1314534831adSStefano Zampini 1315534831adSStefano Zampini Notes: 1316534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 1317534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1318534831adSStefano Zampini */ 1319534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1320534831adSStefano Zampini { 1321534831adSStefano Zampini PetscErrorCode ierr; 1322534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1323534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 13243972b0daSStefano Zampini Vec used_vec; 13254df7a6bfSStefano Zampini PetscBool iscg = PETSC_FALSE, save_rhs = PETSC_TRUE, benign_correction_computed; 1326534831adSStefano Zampini 1327534831adSStefano Zampini PetscFunctionBegin; 13281f4df5f7SStefano Zampini /* if we are working with CG, one dirichlet solve can be avoided during Krylov iterations */ 132985c4d303SStefano Zampini if (ksp) { 13304df7a6bfSStefano Zampini PetscBool isgroppcg, ispipecg, ispipelcg, ispipecgrr; 13314df7a6bfSStefano Zampini 133285c4d303SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr); 133327b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPGROPPCG,&isgroppcg);CHKERRQ(ierr); 133427b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECG,&ispipecg);CHKERRQ(ierr); 13354df7a6bfSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECG,&ispipelcg);CHKERRQ(ierr); 1336f94e96cbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECGRR,&ispipecgrr);CHKERRQ(ierr); 13374df7a6bfSStefano Zampini iscg = (PetscBool)(iscg || isgroppcg || ispipecg || ispipelcg || ispipecgrr); 13383bf6e316SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static || !iscg || pc->mat != pc->pmat) { 133985c4d303SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 134085c4d303SStefano Zampini } 134185c4d303SStefano Zampini } 13423bf6e316SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static || pc->mat != pc->pmat) { 1343fc17d649SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 1344fc17d649SStefano Zampini } 13451f4df5f7SStefano Zampini 134685c4d303SStefano Zampini /* Creates parallel work vectors used in presolve */ 134762a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 134862a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 134962a6ff1dSStefano Zampini } 135062a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 135162a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 135262a6ff1dSStefano Zampini } 13538d00608fSStefano Zampini 135427b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_FALSE; 13553972b0daSStefano Zampini if (x) { 13563972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 13573972b0daSStefano Zampini used_vec = x; 13588d00608fSStefano Zampini } else { /* it can only happen when calling PCBDDCMatFETIDPGetRHS */ 13593972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 13603972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 13613972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 136227b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 1363266e20e9SStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 1364266e20e9SStefano Zampini save_rhs = PETSC_FALSE; 1365266e20e9SStefano Zampini pcbddc->eliminate_dirdofs = PETSC_TRUE; 13663972b0daSStefano Zampini } 13678efcfb23SStefano Zampini 13688efcfb23SStefano Zampini /* hack into ksp data structure since PCPreSolve comes earlier than setting to zero the guess in src/ksp/ksp/interface/itfunc.c */ 13693972b0daSStefano Zampini if (ksp) { 1370a0cb1b98SStefano Zampini /* store the flag for the initial guess since it will be restored back during PCPostSolve_BDDC */ 13718efcfb23SStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 13728efcfb23SStefano Zampini if (!pcbddc->ksp_guess_nonzero) { 13733972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 13743972b0daSStefano Zampini } 13753972b0daSStefano Zampini } 13763308cffdSStefano Zampini 13778d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 13783972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 137970c64980SStefano Zampini if (rhs && pcbddc->eliminate_dirdofs) { 13803975b054SStefano Zampini IS dirIS = NULL; 13813975b054SStefano Zampini 1382a07ea27aSStefano Zampini /* DirichletBoundariesLocal may not be consistent among neighbours; gets a dirichlet dofs IS from graph (may be cached) */ 13833975b054SStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 13843975b054SStefano Zampini if (dirIS) { 1385906d46d4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1386785d1243SStefano Zampini PetscInt dirsize,i,*is_indices; 13872b095fd8SStefano Zampini PetscScalar *array_x; 13882b095fd8SStefano Zampini const PetscScalar *array_diagonal; 1389785d1243SStefano Zampini 13903972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 13913972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 1392e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1393e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1394e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1395e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 139682ba6b80SStefano Zampini ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr); 13973972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 13982b095fd8SStefano Zampini ierr = VecGetArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 13993972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 14002fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 14013972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 14022b095fd8SStefano Zampini ierr = VecRestoreArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 14033972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 1404e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1405e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 14068d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 14071b968477SStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 14088efcfb23SStefano Zampini } 1409a07ea27aSStefano Zampini } 1410b76ba322SStefano Zampini 14118efcfb23SStefano Zampini /* remove the computed solution or the initial guess from the rhs */ 14128d00608fSStefano Zampini if (pcbddc->rhs_change || (ksp && pcbddc->ksp_guess_nonzero) ) { 141327b6a85dSStefano Zampini /* save the original rhs */ 141427b6a85dSStefano Zampini if (save_rhs) { 141527b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 141627b6a85dSStefano Zampini save_rhs = PETSC_FALSE; 14178d00608fSStefano Zampini } 14188d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 14193972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 142027b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,used_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 14213972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 14228efcfb23SStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 142327b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 14247acc28cbSStefano Zampini if (ksp) { 14257acc28cbSStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_FALSE);CHKERRQ(ierr); 14267acc28cbSStefano Zampini } 14273308cffdSStefano Zampini } 14288efcfb23SStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 1429b76ba322SStefano Zampini 1430fc17d649SStefano Zampini /* compute initial vector in benign space if needed 143127b6a85dSStefano Zampini and remove non-benign solution from the rhs */ 143227b6a85dSStefano Zampini benign_correction_computed = PETSC_FALSE; 143308af2428SStefano Zampini if (rhs && pcbddc->benign_compute_correction && (pcbddc->benign_have_null || pcbddc->benign_apply_coarse_only)) { 14341f4df5f7SStefano Zampini /* compute u^*_h using ideas similar to those in Xuemin Tu's PhD thesis (see Section 4.8.1) 14351f4df5f7SStefano Zampini Recursively apply BDDC in the multilevel case */ 14360369aaf7SStefano Zampini if (!pcbddc->benign_vec) { 14370369aaf7SStefano Zampini ierr = VecDuplicate(rhs,&pcbddc->benign_vec);CHKERRQ(ierr); 14380369aaf7SStefano Zampini } 1439c69e9cc1SStefano Zampini /* keep applying coarse solver unless we no longer have benign subdomains */ 1440c69e9cc1SStefano Zampini pcbddc->benign_apply_coarse_only = pcbddc->benign_have_null ? PETSC_TRUE : PETSC_FALSE; 144127b6a85dSStefano Zampini if (!pcbddc->benign_skip_correction) { 14421dd7afcfSStefano Zampini ierr = PCApply_BDDC(pc,rhs,pcbddc->benign_vec);CHKERRQ(ierr); 14433bca92a6SStefano Zampini benign_correction_computed = PETSC_TRUE; 14441f4df5f7SStefano Zampini if (pcbddc->temp_solution_used) { 14451f4df5f7SStefano Zampini ierr = VecAXPY(pcbddc->temp_solution,1.0,pcbddc->benign_vec);CHKERRQ(ierr); 14461f4df5f7SStefano Zampini } 14471f4df5f7SStefano Zampini ierr = VecScale(pcbddc->benign_vec,-1.0);CHKERRQ(ierr); 144827b6a85dSStefano Zampini /* store the original rhs if not done earlier */ 144927b6a85dSStefano Zampini if (save_rhs) { 145027b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 145192e3dcfbSStefano Zampini } 145227b6a85dSStefano Zampini if (pcbddc->rhs_change) { 14530369aaf7SStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,rhs,rhs);CHKERRQ(ierr); 145427b6a85dSStefano Zampini } else { 145527b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 145627b6a85dSStefano Zampini } 14570369aaf7SStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 145827b6a85dSStefano Zampini } 145927b6a85dSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_FALSE; 14604df7a6bfSStefano Zampini } else { 14614df7a6bfSStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 14620369aaf7SStefano Zampini } 14632d4c4fecSStefano Zampini 14642d4c4fecSStefano Zampini /* dbg output */ 1465a198735bSStefano Zampini if (pcbddc->dbg_flag && benign_correction_computed) { 14661f4df5f7SStefano Zampini Vec v; 1467c69e9cc1SStefano Zampini 14681f4df5f7SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&v);CHKERRQ(ierr); 1469c69e9cc1SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 14701f4df5f7SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,v);CHKERRQ(ierr); 1471c69e9cc1SStefano Zampini } else { 1472c69e9cc1SStefano Zampini ierr = VecCopy(rhs,v);CHKERRQ(ierr); 1473c69e9cc1SStefano Zampini } 14741f4df5f7SStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,v,PETSC_TRUE);CHKERRQ(ierr); 1475e0fe2d75SToby Isaac ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"LEVEL %D: is the correction benign?\n",pcbddc->current_level);CHKERRQ(ierr); 1476c69e9cc1SStefano Zampini ierr = PetscScalarView(pcbddc->benign_n,pcbddc->benign_p0,pcbddc->dbg_viewer);CHKERRQ(ierr); 1477c69e9cc1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 14781f4df5f7SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 14791f4df5f7SStefano Zampini } 14800369aaf7SStefano Zampini 14810369aaf7SStefano Zampini /* set initial guess if using PCG */ 14828ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 14830369aaf7SStefano Zampini if (x && pcbddc->use_exact_dirichlet_trick) { 14840369aaf7SStefano Zampini ierr = VecSet(x,0.0);CHKERRQ(ierr); 14851dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 148627b6a85dSStefano Zampini if (benign_correction_computed) { /* we have already saved the changed rhs */ 14878860a134SJunchao Zhang ierr = VecLockReadPop(pcis->vec1_global);CHKERRQ(ierr); 14881dd7afcfSStefano Zampini } else { 14891dd7afcfSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,pcis->vec1_global);CHKERRQ(ierr); 14901dd7afcfSStefano Zampini } 14911dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14921dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14931dd7afcfSStefano Zampini } else { 14940369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14950369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14961dd7afcfSStefano Zampini } 14970369aaf7SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 1498c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 14991dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 15001dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.);CHKERRQ(ierr); 15011dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15021dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15031dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x);CHKERRQ(ierr); 15041dd7afcfSStefano Zampini } else { 15050369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15060369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15071dd7afcfSStefano Zampini } 15080369aaf7SStefano Zampini if (ksp) { 15090369aaf7SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 15100369aaf7SStefano Zampini } 15118ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_TRUE; 1512266e20e9SStefano Zampini } else if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior && benign_correction_computed && pcbddc->use_exact_dirichlet_trick) { 15138860a134SJunchao Zhang ierr = VecLockReadPop(pcis->vec1_global);CHKERRQ(ierr); 15140369aaf7SStefano Zampini } 1515534831adSStefano Zampini PetscFunctionReturn(0); 1516534831adSStefano Zampini } 1517906d46d4SStefano Zampini 1518534831adSStefano Zampini /* 1519534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 1520534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 1521534831adSStefano Zampini 1522534831adSStefano Zampini Input Parameter: 1523534831adSStefano Zampini + pc - the preconditioner contex 1524534831adSStefano Zampini 1525534831adSStefano Zampini Application Interface Routine: PCPostSolve() 1526534831adSStefano Zampini 1527534831adSStefano Zampini Notes: 1528534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 1529534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1530534831adSStefano Zampini */ 1531534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1532534831adSStefano Zampini { 1533534831adSStefano Zampini PetscErrorCode ierr; 1534534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1535534831adSStefano Zampini 1536534831adSStefano Zampini PetscFunctionBegin; 15373972b0daSStefano Zampini /* add solution removed in presolve */ 15386bcfc461SStefano Zampini if (x && pcbddc->rhs_change) { 153927b6a85dSStefano Zampini if (pcbddc->temp_solution_used) { 15403425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 1541af140850Sstefano_zampini } else if (pcbddc->benign_compute_correction && pcbddc->benign_vec) { 154227b6a85dSStefano Zampini ierr = VecAXPY(x,-1.0,pcbddc->benign_vec);CHKERRQ(ierr); 15433425bc38SStefano Zampini } 1544af140850Sstefano_zampini /* restore to original state (not for FETI-DP) */ 1545af140850Sstefano_zampini if (ksp) pcbddc->temp_solution_used = PETSC_FALSE; 154627b6a85dSStefano Zampini } 154727b6a85dSStefano Zampini 1548266e20e9SStefano Zampini /* restore rhs to its original state (not needed for FETI-DP) */ 15498d00608fSStefano Zampini if (rhs && pcbddc->rhs_change) { 155027b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 15518d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 1552af140850Sstefano_zampini } 15538efcfb23SStefano Zampini /* restore ksp guess state */ 15548efcfb23SStefano Zampini if (ksp) { 15558efcfb23SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 15568ae0ca82SStefano Zampini /* reset flag for exact dirichlet trick */ 15578ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 1558af140850Sstefano_zampini } 1559534831adSStefano Zampini PetscFunctionReturn(0); 1560534831adSStefano Zampini } 1561af140850Sstefano_zampini 15620c7d97c5SJed Brown /* 15630c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 15640c7d97c5SJed Brown by setting data structures and options. 15650c7d97c5SJed Brown 15660c7d97c5SJed Brown Input Parameter: 156753cdbc3dSStefano Zampini + pc - the preconditioner context 15680c7d97c5SJed Brown 15690c7d97c5SJed Brown Application Interface Routine: PCSetUp() 15700c7d97c5SJed Brown 15710c7d97c5SJed Brown Notes: 15720c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 15730c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 15740c7d97c5SJed Brown */ 157553cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 15760c7d97c5SJed Brown { 15770c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1578c703fcc7SStefano Zampini PCBDDCSubSchurs sub_schurs; 15795e8657edSStefano Zampini Mat_IS* matis; 158008122e43SStefano Zampini MatNullSpace nearnullspace; 158135509ce9Sstefano_zampini Mat lA; 158235509ce9Sstefano_zampini IS lP,zerodiag = NULL; 158391e8d312SStefano Zampini PetscInt nrows,ncols; 158486bfa4cfSStefano Zampini PetscMPIInt size; 1585c703fcc7SStefano Zampini PetscBool computesubschurs; 15868de1fae6SStefano Zampini PetscBool computeconstraintsmatrix; 15873b03f7bbSStefano Zampini PetscBool new_nearnullspace_provided,ismatis,rl; 1588c703fcc7SStefano Zampini PetscErrorCode ierr; 15890c7d97c5SJed Brown 15900c7d97c5SJed Brown PetscFunctionBegin; 15915e8657edSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATIS,&ismatis);CHKERRQ(ierr); 15926c4ed002SBarry Smith if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner requires matrix of type MATIS"); 159391e8d312SStefano Zampini ierr = MatGetSize(pc->pmat,&nrows,&ncols);CHKERRQ(ierr); 15946c4ed002SBarry Smith if (nrows != ncols) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PCBDDC preconditioner requires a square preconditioning matrix"); 159586bfa4cfSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 159686bfa4cfSStefano Zampini 15975e8657edSStefano Zampini matis = (Mat_IS*)pc->pmat->data; 1598f4ddd8eeSStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other future nonoverlapping preconditioners */ 15993b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 160071582508SStefano Zampini Also, BDDC builds its own KSP for the Dirichlet problem */ 16013b03f7bbSStefano Zampini rl = pcbddc->recompute_topography; 16023b03f7bbSStefano Zampini if (!pc->setupcalled || pc->flag == DIFFERENT_NONZERO_PATTERN) rl = PETSC_TRUE; 16033b03f7bbSStefano Zampini ierr = MPIU_Allreduce(&rl,&pcbddc->recompute_topography,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1604c83e1ba7SStefano Zampini if (pcbddc->recompute_topography) { 1605c83e1ba7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 1606c83e1ba7SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1607c83e1ba7SStefano Zampini } else { 16088de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_FALSE; 1609c83e1ba7SStefano Zampini } 1610b087196eSStefano Zampini 1611b087196eSStefano Zampini /* check parameters' compatibility */ 1612b7ab4a40SStefano Zampini if (!pcbddc->use_deluxe_scaling) pcbddc->deluxe_zerorows = PETSC_FALSE; 1613bd2a564bSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_threshold[0] != 0.0 || pcbddc->adaptive_threshold[1] != 0.0); 161486bfa4cfSStefano Zampini pcbddc->use_deluxe_scaling = (PetscBool)(pcbddc->use_deluxe_scaling && size > 1); 161586bfa4cfSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_selection && size > 1); 1616bf3a8328SStefano Zampini pcbddc->adaptive_userdefined = (PetscBool)(pcbddc->adaptive_selection && pcbddc->adaptive_userdefined); 1617862806e4SStefano Zampini if (pcbddc->adaptive_selection) pcbddc->use_faces = PETSC_TRUE; 1618862806e4SStefano Zampini 16195a95e1ceSStefano Zampini computesubschurs = (PetscBool)(pcbddc->adaptive_selection || pcbddc->use_deluxe_scaling); 162016909a7fSStefano Zampini 162171582508SStefano Zampini /* activate all connected components if the netflux has been requested */ 1622bb05f991SStefano Zampini if (pcbddc->compute_nonetflux) { 1623bb05f991SStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 1624bb05f991SStefano Zampini pcbddc->use_edges = PETSC_TRUE; 1625bb05f991SStefano Zampini pcbddc->use_faces = PETSC_TRUE; 1626bb05f991SStefano Zampini } 1627bb05f991SStefano Zampini 1628f4ddd8eeSStefano Zampini /* Get stdout for dbg */ 162970cf5478SStefano Zampini if (pcbddc->dbg_flag) { 163070cf5478SStefano Zampini if (!pcbddc->dbg_viewer) { 163158a03d70SStefano Zampini pcbddc->dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pc)); 1632f4ddd8eeSStefano Zampini } 1633d9869140SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 163458a03d70SStefano Zampini ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1635f4ddd8eeSStefano Zampini } 1636f4ddd8eeSStefano Zampini 1637c703fcc7SStefano Zampini /* process topology information */ 163843371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Topology[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 163971582508SStefano Zampini if (pcbddc->recompute_topography) { 164071582508SStefano Zampini ierr = PCBDDCComputeLocalTopologyInfo(pc);CHKERRQ(ierr); 1641c703fcc7SStefano Zampini if (pcbddc->discretegradient) { 1642a13144ffSStefano Zampini ierr = PCBDDCNedelecSupport(pc);CHKERRQ(ierr); 1643a13144ffSStefano Zampini } 1644c703fcc7SStefano Zampini } 16454f819b78SStefano Zampini if (pcbddc->corner_selected) pcbddc->use_vertices = PETSC_TRUE; 1646a13144ffSStefano Zampini 1647c703fcc7SStefano Zampini /* change basis if requested by the user */ 16485e8657edSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 16495e8657edSStefano Zampini /* use_change_of_basis flag is used to automatically compute a change of basis from constraints */ 16505e8657edSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 16515e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 16525e8657edSStefano Zampini } else { 1653b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 16545e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 16555e8657edSStefano Zampini pcbddc->local_mat = matis->A; 1656d16cbb6bSStefano Zampini } 1657d16cbb6bSStefano Zampini 16584f1b2e48SStefano Zampini /* 1659c703fcc7SStefano Zampini Compute change of basis on local pressures (aka zerodiag dofs) with the benign trick 16604f1b2e48SStefano Zampini This should come earlier then PCISSetUp for extracting the correct subdomain matrices 16614f1b2e48SStefano Zampini */ 16621dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 1663d16cbb6bSStefano Zampini if (pcbddc->benign_saddle_point) { 16649f47a83aSStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 16659f47a83aSStefano Zampini 166605b28244SStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->use_change_of_basis || !computesubschurs) pcbddc->benign_change_explicit = PETSC_TRUE; 16673b03f7bbSStefano Zampini /* detect local saddle point and change the basis in pcbddc->local_mat */ 16683b03f7bbSStefano Zampini ierr = PCBDDCBenignDetectSaddlePoint(pc,(PetscBool)(!pcbddc->recompute_topography),&zerodiag);CHKERRQ(ierr); 1669a3df083aSStefano Zampini /* pop B0 mat from local mat */ 1670c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 16711dd7afcfSStefano Zampini /* give pcis a hint to not reuse submatrices during PCISCreate */ 16721dd7afcfSStefano Zampini if (pc->flag == SAME_NONZERO_PATTERN && pcis->reusesubmatrices == PETSC_TRUE) { 16731dd7afcfSStefano Zampini if (pcbddc->benign_n && (pcbddc->benign_change_explicit || pcbddc->dbg_flag)) { 16741dd7afcfSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 16751dd7afcfSStefano Zampini } else { 1676a3df083aSStefano Zampini pcis->reusesubmatrices = PETSC_TRUE; 16771dd7afcfSStefano Zampini } 1678a3df083aSStefano Zampini } else { 16799f47a83aSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 1680674ae819SStefano Zampini } 1681a3df083aSStefano Zampini } 168227b6a85dSStefano Zampini 16838037d520SStefano Zampini /* propagate relevant information */ 168406a4e24aSStefano Zampini if (matis->A->symmetric_set) { 168506a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 168606a4e24aSStefano Zampini } 168706a4e24aSStefano Zampini if (matis->A->spd_set) { 168806a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SPD,matis->A->spd);CHKERRQ(ierr); 168906a4e24aSStefano Zampini } 1690e496cd5dSStefano Zampini 16915e8657edSStefano Zampini /* Set up all the "iterative substructuring" common block without computing solvers */ 16925e8657edSStefano Zampini { 16935e8657edSStefano Zampini Mat temp_mat; 16945e8657edSStefano Zampini 16955e8657edSStefano Zampini temp_mat = matis->A; 16965e8657edSStefano Zampini matis->A = pcbddc->local_mat; 1697d9869140SStefano Zampini ierr = PCISSetUp(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 16985e8657edSStefano Zampini pcbddc->local_mat = matis->A; 16995e8657edSStefano Zampini matis->A = temp_mat; 17005e8657edSStefano Zampini } 1701684f6988SStefano Zampini 170281d14e9dSStefano Zampini /* Analyze interface */ 170364ac59b8SStefano Zampini if (!pcbddc->graphanalyzed) { 1704674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 17058de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1706345ecf6cSStefano Zampini if (pcbddc->adaptive_selection && !pcbddc->use_deluxe_scaling && !pcbddc->mat_graph->twodim) { 17074247aa23Sstefano_zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot compute the adaptive primal space for a problem with 3D edges without deluxe scaling"); 1708345ecf6cSStefano Zampini } 1709a198735bSStefano Zampini if (pcbddc->compute_nonetflux) { 1710669cc0f4SStefano Zampini MatNullSpace nnfnnsp; 1711669cc0f4SStefano Zampini 171221ef3d20SStefano Zampini if (!pcbddc->divudotp) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Missing divudotp operator"); 17138ae0ca82SStefano Zampini ierr = PCBDDCComputeNoNetFlux(pc->pmat,pcbddc->divudotp,pcbddc->divudotp_trans,pcbddc->divudotp_vl2l,pcbddc->mat_graph,&nnfnnsp);CHKERRQ(ierr); 171471582508SStefano Zampini /* TODO what if a nearnullspace is already attached? */ 17158037d520SStefano Zampini if (nnfnnsp) { 1716669cc0f4SStefano Zampini ierr = MatSetNearNullSpace(pc->pmat,nnfnnsp);CHKERRQ(ierr); 1717669cc0f4SStefano Zampini ierr = MatNullSpaceDestroy(&nnfnnsp);CHKERRQ(ierr); 1718669cc0f4SStefano Zampini } 1719674ae819SStefano Zampini } 17208037d520SStefano Zampini } 172143371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Topology[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 1722fb8d54d4SStefano Zampini 17235408967cSStefano Zampini /* check existence of a divergence free extension, i.e. 17245408967cSStefano Zampini b(v_I,p_0) = 0 for all v_I (raise error if not). 17255408967cSStefano Zampini Also, check that PCBDDCBenignGetOrSetP0 works */ 1726ff1f7e73Sstefano_zampini if (pcbddc->benign_saddle_point && pcbddc->dbg_flag > 1) { 17275408967cSStefano Zampini ierr = PCBDDCBenignCheck(pc,zerodiag);CHKERRQ(ierr); 172809f581a4SStefano Zampini } 17294f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 173006f24817SStefano Zampini 1731b96c3477SStefano Zampini /* Setup local dirichlet solver ksp_D and sub_schurs solvers */ 1732c703fcc7SStefano Zampini if (computesubschurs && pcbddc->recompute_topography) { 173308122e43SStefano Zampini ierr = PCBDDCInitSubSchurs(pc);CHKERRQ(ierr); 1734b1b3d7a2SStefano Zampini } 17359d54b7f4SStefano Zampini /* SetUp Scaling operator (scaling matrices could be needed in SubSchursSetUp)*/ 17369d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) { 17379d54b7f4SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 17389d54b7f4SStefano Zampini } 1739c703fcc7SStefano Zampini 1740c703fcc7SStefano Zampini /* finish setup solvers and do adaptive selection of constraints */ 1741b334f244SStefano Zampini sub_schurs = pcbddc->sub_schurs; 1742b334f244SStefano Zampini if (sub_schurs && sub_schurs->schur_explicit) { 17432070dbb6SStefano Zampini if (computesubschurs) { 174408122e43SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 17452070dbb6SStefano Zampini } 1746d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 1747d5574798SStefano Zampini } else { 1748d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 17492070dbb6SStefano Zampini if (computesubschurs) { 1750d5574798SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 1751d5574798SStefano Zampini } 17522070dbb6SStefano Zampini } 175308122e43SStefano Zampini if (pcbddc->adaptive_selection) { 175408122e43SStefano Zampini ierr = PCBDDCAdaptiveSelection(pc);CHKERRQ(ierr); 17558de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1756b7eb3628SStefano Zampini } 1757684f6988SStefano Zampini 1758f4ddd8eeSStefano Zampini /* infer if NullSpace object attached to Mat via MatSetNearNullSpace has changed */ 1759fb8d54d4SStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1760f4ddd8eeSStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullspace);CHKERRQ(ierr); 1761f4ddd8eeSStefano Zampini if (pcbddc->onearnullspace) { /* already used nearnullspace */ 1762f4ddd8eeSStefano Zampini if (!nearnullspace) { /* near null space attached to mat has been destroyed */ 1763f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1764f4ddd8eeSStefano Zampini } else { 1765f4ddd8eeSStefano Zampini /* determine if the two nullspaces are different (should be lightweight) */ 1766f4ddd8eeSStefano Zampini if (nearnullspace != pcbddc->onearnullspace) { 1767f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1768165b64e2SStefano Zampini } else { /* maybe the user has changed the content of the nearnullspace so check vectors ObjectStateId */ 1769f4ddd8eeSStefano Zampini PetscInt i; 1770165b64e2SStefano Zampini const Vec *nearnullvecs; 1771165b64e2SStefano Zampini PetscObjectState state; 1772165b64e2SStefano Zampini PetscInt nnsp_size; 1773165b64e2SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullspace,NULL,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1774f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1775f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&state);CHKERRQ(ierr); 1776165b64e2SStefano Zampini if (pcbddc->onearnullvecs_state[i] != state) { 1777f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1778f4ddd8eeSStefano Zampini break; 1779f4ddd8eeSStefano Zampini } 1780f4ddd8eeSStefano Zampini } 1781f4ddd8eeSStefano Zampini } 1782f4ddd8eeSStefano Zampini } 1783f4ddd8eeSStefano Zampini } else { 1784f4ddd8eeSStefano Zampini if (!nearnullspace) { /* both nearnullspaces are null */ 1785f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1786f4ddd8eeSStefano Zampini } else { /* nearnullspace attached later */ 1787f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1788f4ddd8eeSStefano Zampini } 1789f4ddd8eeSStefano Zampini } 1790f4ddd8eeSStefano Zampini 1791f4ddd8eeSStefano Zampini /* Setup constraints and related work vectors */ 1792727cdba6SStefano Zampini /* reset primal space flags */ 179343371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_LocalWork[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 1794f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 1795727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 17968de1fae6SStefano Zampini if (computeconstraintsmatrix || new_nearnullspace_provided) { 1797727cdba6SStefano Zampini /* It also sets the primal space flags */ 1798674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 17999543d0ffSStefano Zampini } 1800e7b262bdSStefano Zampini /* Allocate needed local vectors (which depends on quantities defined during ConstraintsSetUp) */ 1801f4ddd8eeSStefano Zampini ierr = PCBDDCSetUpLocalWorkVectors(pc);CHKERRQ(ierr); 18025e8657edSStefano Zampini 18035e8657edSStefano Zampini if (pcbddc->use_change_of_basis) { 18045e8657edSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 18055e8657edSStefano Zampini 18065e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 18074f1b2e48SStefano Zampini if (pcbddc->benign_change) { 18081dd7afcfSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 1809c263805aSStefano Zampini /* pop B0 from pcbddc->local_mat */ 1810c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 1811c263805aSStefano Zampini } 18125e8657edSStefano Zampini /* get submatrices */ 18135e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 18145e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 18155e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 18167dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 18177dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 18187dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 18193975b054SStefano Zampini /* set flag in pcis to not reuse submatrices during PCISCreate */ 18203975b054SStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 18219c6a02ceSStefano Zampini } else if (!pcbddc->user_ChangeOfBasisMatrix && !pcbddc->benign_change) { 1822b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 18235e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 18245e8657edSStefano Zampini pcbddc->local_mat = matis->A; 18255e8657edSStefano Zampini } 182635509ce9Sstefano_zampini 182735509ce9Sstefano_zampini /* interface pressure block row for B_C */ 182835509ce9Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lP" ,(PetscObject*)&lP);CHKERRQ(ierr); 182935509ce9Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject*)&lA);CHKERRQ(ierr); 183035509ce9Sstefano_zampini if (lA && lP) { 183135509ce9Sstefano_zampini PC_IS* pcis = (PC_IS*)pc->data; 183235509ce9Sstefano_zampini Mat B_BI,B_BB,Bt_BI,Bt_BB; 183335509ce9Sstefano_zampini PetscBool issym; 183435509ce9Sstefano_zampini ierr = MatIsSymmetric(lA,PETSC_SMALL,&issym);CHKERRQ(ierr); 18356cc1294bSstefano_zampini if (issym) { 18367dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_I_local,MAT_INITIAL_MATRIX,&B_BI);CHKERRQ(ierr); 18377dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_B_local,MAT_INITIAL_MATRIX,&B_BB);CHKERRQ(ierr); 183835509ce9Sstefano_zampini ierr = MatCreateTranspose(B_BI,&Bt_BI);CHKERRQ(ierr); 183935509ce9Sstefano_zampini ierr = MatCreateTranspose(B_BB,&Bt_BB);CHKERRQ(ierr); 184035509ce9Sstefano_zampini } else { 18417dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_I_local,MAT_INITIAL_MATRIX,&B_BI);CHKERRQ(ierr); 18427dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_B_local,MAT_INITIAL_MATRIX,&B_BB);CHKERRQ(ierr); 18437dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,pcis->is_I_local,lP,MAT_INITIAL_MATRIX,&Bt_BI);CHKERRQ(ierr); 18447dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,pcis->is_B_local,lP,MAT_INITIAL_MATRIX,&Bt_BB);CHKERRQ(ierr); 184535509ce9Sstefano_zampini } 184635509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_B_BI",(PetscObject)B_BI);CHKERRQ(ierr); 184735509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_B_BB",(PetscObject)B_BB);CHKERRQ(ierr); 184835509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_Bt_BI",(PetscObject)Bt_BI);CHKERRQ(ierr); 184935509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_Bt_BB",(PetscObject)Bt_BB);CHKERRQ(ierr); 185035509ce9Sstefano_zampini ierr = MatDestroy(&B_BI);CHKERRQ(ierr); 185135509ce9Sstefano_zampini ierr = MatDestroy(&B_BB);CHKERRQ(ierr); 185235509ce9Sstefano_zampini ierr = MatDestroy(&Bt_BI);CHKERRQ(ierr); 185335509ce9Sstefano_zampini ierr = MatDestroy(&Bt_BB);CHKERRQ(ierr); 185435509ce9Sstefano_zampini } 185543371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_LocalWork[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 185635509ce9Sstefano_zampini 1857b96c3477SStefano Zampini /* SetUp coarse and local Neumann solvers */ 185899cc7994SStefano Zampini ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr); 1859b96c3477SStefano Zampini /* SetUp Scaling operator */ 18609d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1861674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 18620c7d97c5SJed Brown } 1863c703fcc7SStefano Zampini 18641dd7afcfSStefano Zampini /* mark topography as done */ 186556282151SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 18660369aaf7SStefano Zampini 18671dd7afcfSStefano Zampini /* wrap pcis->A_IB and pcis->A_BI if we did not change explicitly the variables on the pressures */ 18681dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_FALSE);CHKERRQ(ierr); 18691dd7afcfSStefano Zampini 187058a03d70SStefano Zampini if (pcbddc->dbg_flag) { 187158a03d70SStefano Zampini ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1872d9869140SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 18732b510759SStefano Zampini } 18740c7d97c5SJed Brown PetscFunctionReturn(0); 18750c7d97c5SJed Brown } 18760c7d97c5SJed Brown 18770c7d97c5SJed Brown /* 187850efa1b5SStefano Zampini PCApply_BDDC - Applies the BDDC operator to a vector. 18790c7d97c5SJed Brown 18800c7d97c5SJed Brown Input Parameters: 18810f202f7eSStefano Zampini + pc - the preconditioner context 18820f202f7eSStefano Zampini - r - input vector (global) 18830c7d97c5SJed Brown 18840c7d97c5SJed Brown Output Parameter: 18850c7d97c5SJed Brown . z - output vector (global) 18860c7d97c5SJed Brown 18870c7d97c5SJed Brown Application Interface Routine: PCApply() 18880c7d97c5SJed Brown */ 188953cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 18900c7d97c5SJed Brown { 18910c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 18920c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1893b3338236SStefano Zampini Mat lA = NULL; 1894b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 18950c7d97c5SJed Brown PetscErrorCode ierr; 18963b03a366Sstefano_zampini const PetscScalar one = 1.0; 18973b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 18982617d88aSStefano Zampini const PetscScalar zero = 0.0; 18990c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 19000c7d97c5SJed Brown NN interface preconditioner changed to BDDC 1901b097fa66SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static == PETSC_TRUE) */ 19020c7d97c5SJed Brown 19030c7d97c5SJed Brown PetscFunctionBegin; 1904f3d41395Sstefano_zampini ierr = PetscCitationsRegister(citation,&cited);CHKERRQ(ierr); 1905b3338236SStefano Zampini if (pcbddc->switch_static) { 1906b3338236SStefano Zampini ierr = MatISGetLocalMat(pc->useAmat ? pc->mat : pc->pmat,&lA);CHKERRQ(ierr); 1907b3338236SStefano Zampini } 1908b3338236SStefano Zampini 19091dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 19101dd7afcfSStefano Zampini Vec swap; 191127b6a85dSStefano Zampini 191227b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 19131dd7afcfSStefano Zampini swap = pcbddc->work_change; 19141dd7afcfSStefano Zampini pcbddc->work_change = r; 19151dd7afcfSStefano Zampini r = swap; 19161dd7afcfSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 19179cc2a9b1Sstefano_zampini if (pcbddc->benign_apply_coarse_only && pcbddc->use_exact_dirichlet_trick && pcbddc->change_interior) { 19181dd7afcfSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 19198860a134SJunchao Zhang ierr = VecLockReadPush(pcis->vec1_global);CHKERRQ(ierr); 19201dd7afcfSStefano Zampini } 19211dd7afcfSStefano Zampini } 192227b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 1923015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1924efc2fbd9SStefano Zampini } 19258ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 1926b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 19270c7d97c5SJed Brown /* First Dirichlet solve */ 19280c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19290c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19300c7d97c5SJed Brown /* 19310c7d97c5SJed Brown Assembling right hand side for BDDC operator 1932b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 1933674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 19340c7d97c5SJed Brown */ 1935b097fa66SStefano Zampini if (n_D) { 1936b097fa66SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 1937c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 19380c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 193916909a7fSStefano Zampini if (pcbddc->switch_static) { 194016909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 194116909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 194216909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 194316909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 1944b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 194516909a7fSStefano Zampini } else { 194616909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 1947b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 194816909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 194916909a7fSStefano Zampini } 195016909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 195116909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 195216909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 195316909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 195416909a7fSStefano Zampini } else { 1955b097fa66SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 195616909a7fSStefano Zampini } 1957b097fa66SStefano Zampini } else { 1958b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1959b097fa66SStefano Zampini } 19600c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19610c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1962674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 1963b76ba322SStefano Zampini } else { 19644fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 1965674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 1966b76ba322SStefano Zampini } 19674fee134fSStefano Zampini } 1968b76ba322SStefano Zampini 19692617d88aSStefano Zampini /* Apply interface preconditioner 19702617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1971dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 19722617d88aSStefano Zampini 1973674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 1974674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 19750c7d97c5SJed Brown 19763b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 19770c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19780c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1979b097fa66SStefano Zampini if (n_B) { 198016909a7fSStefano Zampini if (pcbddc->switch_static) { 198116909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 198216909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 198316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 198416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 198516909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 1986b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 198716909a7fSStefano Zampini } else { 198816909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 1989b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 199016909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 199116909a7fSStefano Zampini } 199216909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 199316909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 199416909a7fSStefano Zampini } else { 19950c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 199616909a7fSStefano Zampini } 199716909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 199816909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 1999b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 200016909a7fSStefano Zampini } else { 200116909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 2002b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 200316909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 200416909a7fSStefano Zampini } 2005b097fa66SStefano Zampini } 2006df187020SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 2007c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec4_D);CHKERRQ(ierr); 2008efc2fbd9SStefano Zampini 20098ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2010b097fa66SStefano Zampini if (pcbddc->switch_static) { 2011b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 2012b097fa66SStefano Zampini } else { 2013b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 2014b097fa66SStefano Zampini } 20150c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20160c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2017b097fa66SStefano Zampini } else { 2018b097fa66SStefano Zampini if (pcbddc->switch_static) { 2019b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 2020b097fa66SStefano Zampini } else { 2021b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 2022b097fa66SStefano Zampini } 2023b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2024b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2025b097fa66SStefano Zampini } 202627b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 20271dd7afcfSStefano Zampini if (pcbddc->benign_apply_coarse_only) { 2028580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->benign_p0,pcbddc->benign_n);CHKERRQ(ierr); 20291dd7afcfSStefano Zampini } 2030015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 2031efc2fbd9SStefano Zampini } 20321f4df5f7SStefano Zampini 20331dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2034f913dca9SStefano Zampini pcbddc->work_change = r; 20351dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 20361dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 20371dd7afcfSStefano Zampini } 20380c7d97c5SJed Brown PetscFunctionReturn(0); 20390c7d97c5SJed Brown } 204050efa1b5SStefano Zampini 204150efa1b5SStefano Zampini /* 204250efa1b5SStefano Zampini PCApplyTranspose_BDDC - Applies the transpose of the BDDC operator to a vector. 204350efa1b5SStefano Zampini 204450efa1b5SStefano Zampini Input Parameters: 20450f202f7eSStefano Zampini + pc - the preconditioner context 20460f202f7eSStefano Zampini - r - input vector (global) 204750efa1b5SStefano Zampini 204850efa1b5SStefano Zampini Output Parameter: 204950efa1b5SStefano Zampini . z - output vector (global) 205050efa1b5SStefano Zampini 205150efa1b5SStefano Zampini Application Interface Routine: PCApplyTranspose() 205250efa1b5SStefano Zampini */ 205350efa1b5SStefano Zampini PetscErrorCode PCApplyTranspose_BDDC(PC pc,Vec r,Vec z) 205450efa1b5SStefano Zampini { 205550efa1b5SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 205650efa1b5SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 2057b3338236SStefano Zampini Mat lA = NULL; 2058b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 205950efa1b5SStefano Zampini PetscErrorCode ierr; 206050efa1b5SStefano Zampini const PetscScalar one = 1.0; 206150efa1b5SStefano Zampini const PetscScalar m_one = -1.0; 206250efa1b5SStefano Zampini const PetscScalar zero = 0.0; 206350efa1b5SStefano Zampini 206450efa1b5SStefano Zampini PetscFunctionBegin; 2065f3d41395Sstefano_zampini ierr = PetscCitationsRegister(citation,&cited);CHKERRQ(ierr); 2066b3338236SStefano Zampini if (pcbddc->switch_static) { 2067b3338236SStefano Zampini ierr = MatISGetLocalMat(pc->useAmat ? pc->mat : pc->pmat,&lA);CHKERRQ(ierr); 2068b3338236SStefano Zampini } 20691dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 20701dd7afcfSStefano Zampini Vec swap; 207127b6a85dSStefano Zampini 207227b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 20731dd7afcfSStefano Zampini swap = pcbddc->work_change; 20741dd7afcfSStefano Zampini pcbddc->work_change = r; 20751dd7afcfSStefano Zampini r = swap; 207627b6a85dSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 20778ae0ca82SStefano Zampini if (pcbddc->benign_apply_coarse_only && pcbddc->exact_dirichlet_trick_app && pcbddc->change_interior) { 207827b6a85dSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 20798860a134SJunchao Zhang ierr = VecLockReadPush(pcis->vec1_global);CHKERRQ(ierr); 20801dd7afcfSStefano Zampini } 208127b6a85dSStefano Zampini } 208227b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 2083537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 2084537c1cdfSStefano Zampini } 20858ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2086b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 208750efa1b5SStefano Zampini /* First Dirichlet solve */ 208850efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 208950efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 209050efa1b5SStefano Zampini /* 209150efa1b5SStefano Zampini Assembling right hand side for BDDC operator 2092b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 209350efa1b5SStefano Zampini - pcis->vec1_B the interface part of the global vector z 209450efa1b5SStefano Zampini */ 2095b097fa66SStefano Zampini if (n_D) { 2096b097fa66SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 2097c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 209850efa1b5SStefano Zampini ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 209916909a7fSStefano Zampini if (pcbddc->switch_static) { 210016909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 210116909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 210216909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 210316909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 2104b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 210516909a7fSStefano Zampini } else { 210616909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 2107b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 210816909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 210916909a7fSStefano Zampini } 211016909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 211116909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 211216909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 211316909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 211416909a7fSStefano Zampini } else { 2115b097fa66SStefano Zampini ierr = MatMultTranspose(pcis->A_IB,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 211616909a7fSStefano Zampini } 2117b097fa66SStefano Zampini } else { 2118b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 2119b097fa66SStefano Zampini } 212050efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 212150efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 212250efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 212350efa1b5SStefano Zampini } else { 212450efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 212550efa1b5SStefano Zampini } 212650efa1b5SStefano Zampini 212750efa1b5SStefano Zampini /* Apply interface preconditioner 212850efa1b5SStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 2129dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_TRUE);CHKERRQ(ierr); 213050efa1b5SStefano Zampini 213150efa1b5SStefano Zampini /* Apply transpose of partition of unity operator */ 213250efa1b5SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 213350efa1b5SStefano Zampini 213450efa1b5SStefano Zampini /* Second Dirichlet solve and assembling of output */ 213550efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 213650efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2137b097fa66SStefano Zampini if (n_B) { 213816909a7fSStefano Zampini if (pcbddc->switch_static) { 213916909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 214016909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 214116909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 214216909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 214316909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 2144b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 214516909a7fSStefano Zampini } else { 214616909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 2147b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 214816909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 214916909a7fSStefano Zampini } 215016909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 215116909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 215216909a7fSStefano Zampini } else { 215350efa1b5SStefano Zampini ierr = MatMultTranspose(pcis->A_BI,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 215416909a7fSStefano Zampini } 215516909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 215616909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 2157b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 215816909a7fSStefano Zampini } else { 215916909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 2160b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 216116909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 216216909a7fSStefano Zampini } 2163b097fa66SStefano Zampini } 2164b0147a47SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 2165c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec4_D);CHKERRQ(ierr); 21668ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2167b097fa66SStefano Zampini if (pcbddc->switch_static) { 2168b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 2169b097fa66SStefano Zampini } else { 2170b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 2171b097fa66SStefano Zampini } 217250efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 217350efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2174b097fa66SStefano Zampini } else { 2175b097fa66SStefano Zampini if (pcbddc->switch_static) { 2176b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 2177b097fa66SStefano Zampini } else { 2178b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 2179b097fa66SStefano Zampini } 2180b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2181b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2182b097fa66SStefano Zampini } 218327b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 2184537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 2185537c1cdfSStefano Zampini } 21861dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2187f913dca9SStefano Zampini pcbddc->work_change = r; 21881dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 21891dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 21901dd7afcfSStefano Zampini } 219150efa1b5SStefano Zampini PetscFunctionReturn(0); 219250efa1b5SStefano Zampini } 2193674ae819SStefano Zampini 21949326c5c6Sstefano_zampini PetscErrorCode PCReset_BDDC(PC pc) 2195da1bb401SStefano Zampini { 2196da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 21979326c5c6Sstefano_zampini PC_IS *pcis = (PC_IS*)pc->data; 21989326c5c6Sstefano_zampini KSP kspD,kspR,kspC; 2199da1bb401SStefano Zampini PetscErrorCode ierr; 2200da1bb401SStefano Zampini 2201da1bb401SStefano Zampini PetscFunctionBegin; 2202674ae819SStefano Zampini /* free BDDC custom data */ 2203674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 2204674ae819SStefano Zampini /* destroy objects related to topography */ 2205674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 220634a97f8cSStefano Zampini /* destroy objects for scaling operator */ 2207674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 2208674ae819SStefano Zampini /* free solvers stuff */ 2209674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 221062a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 221162a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 221262a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 22131dd7afcfSStefano Zampini /* free data created by PCIS */ 22141dd7afcfSStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 22159326c5c6Sstefano_zampini 22169326c5c6Sstefano_zampini /* restore defaults */ 22179326c5c6Sstefano_zampini kspD = pcbddc->ksp_D; 22189326c5c6Sstefano_zampini kspR = pcbddc->ksp_R; 22199326c5c6Sstefano_zampini kspC = pcbddc->coarse_ksp; 22209326c5c6Sstefano_zampini ierr = PetscMemzero(pc->data,sizeof(*pcbddc));CHKERRQ(ierr); 22219326c5c6Sstefano_zampini pcis->n_neigh = -1; 22229326c5c6Sstefano_zampini pcis->scaling_factor = 1.0; 22239326c5c6Sstefano_zampini pcis->reusesubmatrices = PETSC_TRUE; 22249326c5c6Sstefano_zampini pcbddc->use_local_adj = PETSC_TRUE; 22259326c5c6Sstefano_zampini pcbddc->use_vertices = PETSC_TRUE; 22269326c5c6Sstefano_zampini pcbddc->use_edges = PETSC_TRUE; 22279326c5c6Sstefano_zampini pcbddc->symmetric_primal = PETSC_TRUE; 22289326c5c6Sstefano_zampini pcbddc->vertex_size = 1; 22299326c5c6Sstefano_zampini pcbddc->recompute_topography = PETSC_TRUE; 22309326c5c6Sstefano_zampini pcbddc->coarse_size = -1; 22319326c5c6Sstefano_zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 22329326c5c6Sstefano_zampini pcbddc->coarsening_ratio = 8; 22339326c5c6Sstefano_zampini pcbddc->coarse_eqs_per_proc = 1; 22349326c5c6Sstefano_zampini pcbddc->benign_compute_correction = PETSC_TRUE; 22359326c5c6Sstefano_zampini pcbddc->nedfield = -1; 22369326c5c6Sstefano_zampini pcbddc->nedglobal = PETSC_TRUE; 22379326c5c6Sstefano_zampini pcbddc->graphmaxcount = PETSC_MAX_INT; 22389326c5c6Sstefano_zampini pcbddc->sub_schurs_layers = -1; 22399326c5c6Sstefano_zampini pcbddc->ksp_D = kspD; 22409326c5c6Sstefano_zampini pcbddc->ksp_R = kspR; 22419326c5c6Sstefano_zampini pcbddc->coarse_ksp = kspC; 22429326c5c6Sstefano_zampini PetscFunctionReturn(0); 22439326c5c6Sstefano_zampini } 22449326c5c6Sstefano_zampini 22459326c5c6Sstefano_zampini PetscErrorCode PCDestroy_BDDC(PC pc) 22469326c5c6Sstefano_zampini { 22479326c5c6Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 22489326c5c6Sstefano_zampini PetscErrorCode ierr; 22499326c5c6Sstefano_zampini 22509326c5c6Sstefano_zampini PetscFunctionBegin; 22519326c5c6Sstefano_zampini ierr = PCReset_BDDC(pc);CHKERRQ(ierr); 22529326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 22539326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 22549326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 2255a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",NULL);CHKERRQ(ierr); 2256a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",NULL);CHKERRQ(ierr); 2257906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",NULL);CHKERRQ(ierr); 2258674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 225930368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",NULL);CHKERRQ(ierr); 2260bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 22612b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr); 2262b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr); 22632b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr); 2264bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 226582ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2266bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 226782ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2268bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 226982ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2270bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 2271785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2272bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 227363602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",NULL);CHKERRQ(ierr); 2274bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 2275bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 2276bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 2277bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 2278a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",NULL);CHKERRQ(ierr); 2279ab8c8b98SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",NULL);CHKERRQ(ierr); 2280674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 2281da1bb401SStefano Zampini PetscFunctionReturn(0); 2282da1bb401SStefano Zampini } 22831e6b0712SBarry Smith 2284ab8c8b98SStefano Zampini static PetscErrorCode PCSetCoordinates_BDDC(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 2285ab8c8b98SStefano Zampini { 2286ab8c8b98SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2287ab8c8b98SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 2288ab8c8b98SStefano Zampini PetscErrorCode ierr; 2289ab8c8b98SStefano Zampini 2290ab8c8b98SStefano Zampini PetscFunctionBegin; 2291ab8c8b98SStefano Zampini ierr = PetscFree(mat_graph->coords);CHKERRQ(ierr); 2292ab8c8b98SStefano Zampini ierr = PetscMalloc1(nloc*dim,&mat_graph->coords);CHKERRQ(ierr); 2293580bdb30SBarry Smith ierr = PetscArraycpy(mat_graph->coords,coords,nloc*dim);CHKERRQ(ierr); 2294ab8c8b98SStefano Zampini mat_graph->cnloc = nloc; 2295ab8c8b98SStefano Zampini mat_graph->cdim = dim; 2296ab8c8b98SStefano Zampini mat_graph->cloc = PETSC_FALSE; 22974f819b78SStefano Zampini /* flg setup */ 22984f819b78SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 22994f819b78SStefano Zampini pcbddc->corner_selected = PETSC_FALSE; 2300ab8c8b98SStefano Zampini PetscFunctionReturn(0); 2301ab8c8b98SStefano Zampini } 2302ab8c8b98SStefano Zampini 2303a06fd7f2SStefano Zampini static PetscErrorCode PCPreSolveChangeRHS_BDDC(PC pc, PetscBool* change) 2304a06fd7f2SStefano Zampini { 2305a06fd7f2SStefano Zampini PetscFunctionBegin; 2306a06fd7f2SStefano Zampini *change = PETSC_TRUE; 2307a06fd7f2SStefano Zampini PetscFunctionReturn(0); 2308a06fd7f2SStefano Zampini } 2309a06fd7f2SStefano Zampini 23103425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 23113425bc38SStefano Zampini { 2312674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 2313266e20e9SStefano Zampini Vec work; 23143425bc38SStefano Zampini PC_IS* pcis; 23153425bc38SStefano Zampini PC_BDDC* pcbddc; 23163425bc38SStefano Zampini PetscErrorCode ierr; 23170c7d97c5SJed Brown 23183425bc38SStefano Zampini PetscFunctionBegin; 23193425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 23203425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 23213425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 23223425bc38SStefano Zampini 2323229984c5Sstefano_zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 2324229984c5Sstefano_zampini /* copy rhs since we may change it during PCPreSolve_BDDC */ 2325229984c5Sstefano_zampini if (!pcbddc->original_rhs) { 2326229984c5Sstefano_zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 2327229984c5Sstefano_zampini } 23286cc1294bSstefano_zampini if (mat_ctx->rhs_flip) { 23296cc1294bSstefano_zampini ierr = VecPointwiseMult(pcbddc->original_rhs,standard_rhs,mat_ctx->rhs_flip);CHKERRQ(ierr); 23306cc1294bSstefano_zampini } else { 2331229984c5Sstefano_zampini ierr = VecCopy(standard_rhs,pcbddc->original_rhs);CHKERRQ(ierr); 23326cc1294bSstefano_zampini } 2333af140850Sstefano_zampini if (mat_ctx->g2g_p) { 2334229984c5Sstefano_zampini /* interface pressure rhs */ 2335022d8d2bSstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,fetidp_flux_rhs,pcbddc->original_rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2336022d8d2bSstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,fetidp_flux_rhs,pcbddc->original_rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2337229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,standard_rhs,fetidp_flux_rhs,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2338229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,standard_rhs,fetidp_flux_rhs,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23396cc1294bSstefano_zampini if (!mat_ctx->rhs_flip) { 2340229984c5Sstefano_zampini ierr = VecScale(fetidp_flux_rhs,-1.);CHKERRQ(ierr); 2341229984c5Sstefano_zampini } 23426cc1294bSstefano_zampini } 2343c08af4c6SStefano Zampini /* 2344c08af4c6SStefano Zampini change of basis for physical rhs if needed 2345c08af4c6SStefano Zampini It also changes the rhs in case of dirichlet boundaries 2346c08af4c6SStefano Zampini */ 23473738a8e6SStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,pcbddc->original_rhs,NULL);CHKERRQ(ierr); 2348fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 23493738a8e6SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcbddc->original_rhs,pcbddc->work_change);CHKERRQ(ierr); 23503738a8e6SStefano Zampini work = pcbddc->work_change; 2351fc17d649SStefano Zampini } else { 23523738a8e6SStefano Zampini work = pcbddc->original_rhs; 2353fc17d649SStefano Zampini } 23543425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 2355266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2356266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2357fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 2358fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 2359266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2360266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2361674ae819SStefano Zampini /* Apply partition of unity */ 23623425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 2363266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 23648eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 23653425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 23663425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 2367c0decd05SBarry Smith /* Cannot propagate up error in KSPSolve() because there is no access to the PC */ 23683425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 23693425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 2370266e20e9SStefano Zampini ierr = VecSet(work,0.0);CHKERRQ(ierr); 2371266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2372266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2373266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 2374266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2375266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23763425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 23773425bc38SStefano Zampini } 23783425bc38SStefano Zampini /* BDDC rhs */ 23793425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 23808eeda7d8SStefano Zampini if (pcbddc->switch_static) { 23813425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 23823425bc38SStefano Zampini } 23833425bc38SStefano Zampini /* apply BDDC */ 2384580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->benign_p0,pcbddc->benign_n);CHKERRQ(ierr); 2385dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2386580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->benign_p0,pcbddc->benign_n);CHKERRQ(ierr); 2387229984c5Sstefano_zampini 23883425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 23893425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 23903425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23913425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2392229984c5Sstefano_zampini /* Add contribution to interface pressures */ 2393229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2394229984c5Sstefano_zampini ierr = MatMult(mat_ctx->B_BB,pcis->vec1_B,mat_ctx->vP);CHKERRQ(ierr); 2395229984c5Sstefano_zampini if (pcbddc->switch_static) { 2396229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->B_BI,pcis->vec1_D,mat_ctx->vP,mat_ctx->vP);CHKERRQ(ierr); 2397229984c5Sstefano_zampini } 2398229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->l2g_p,mat_ctx->vP,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2399229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->l2g_p,mat_ctx->vP,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2400229984c5Sstefano_zampini } 24013425bc38SStefano Zampini PetscFunctionReturn(0); 24023425bc38SStefano Zampini } 24031e6b0712SBarry Smith 24043425bc38SStefano Zampini /*@ 24050f202f7eSStefano Zampini PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETI-DP linear system using the physical right-hand side 24063425bc38SStefano Zampini 24073425bc38SStefano Zampini Collective 24083425bc38SStefano Zampini 24093425bc38SStefano Zampini Input Parameters: 24100f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix object obtained by a call to PCBDDCCreateFETIDPOperators 24110f202f7eSStefano Zampini - standard_rhs - the right-hand side of the original linear system 24123425bc38SStefano Zampini 24133425bc38SStefano Zampini Output Parameters: 24140f202f7eSStefano Zampini . fetidp_flux_rhs - the right-hand side for the FETI-DP linear system 24153425bc38SStefano Zampini 24163425bc38SStefano Zampini Level: developer 24173425bc38SStefano Zampini 24183425bc38SStefano Zampini Notes: 24193425bc38SStefano Zampini 24200f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetSolution 24213425bc38SStefano Zampini @*/ 24223425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 24233425bc38SStefano Zampini { 2424674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 24253425bc38SStefano Zampini PetscErrorCode ierr; 24263425bc38SStefano Zampini 24273425bc38SStefano Zampini PetscFunctionBegin; 2428266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2429266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_rhs,VEC_CLASSID,2); 2430266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_rhs,VEC_CLASSID,3); 24313425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2432163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 24333425bc38SStefano Zampini PetscFunctionReturn(0); 24343425bc38SStefano Zampini } 24351e6b0712SBarry Smith 24363425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 24373425bc38SStefano Zampini { 2438674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 24393425bc38SStefano Zampini PC_IS* pcis; 24403425bc38SStefano Zampini PC_BDDC* pcbddc; 24413425bc38SStefano Zampini PetscErrorCode ierr; 2442229984c5Sstefano_zampini Vec work; 24433425bc38SStefano Zampini 24443425bc38SStefano Zampini PetscFunctionBegin; 24453425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 24463425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 24473425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 24483425bc38SStefano Zampini 24493425bc38SStefano Zampini /* apply B_delta^T */ 2450af140850Sstefano_zampini ierr = VecSet(pcis->vec1_B,0.);CHKERRQ(ierr); 24513425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24523425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24533425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 2454229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2455229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->l2g_p,fetidp_flux_sol,mat_ctx->vP,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2456229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->l2g_p,fetidp_flux_sol,mat_ctx->vP,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2457229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->Bt_BB,mat_ctx->vP,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 2458229984c5Sstefano_zampini } 2459229984c5Sstefano_zampini 24603425bc38SStefano Zampini /* compute rhs for BDDC application */ 24613425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 24628eeda7d8SStefano Zampini if (pcbddc->switch_static) { 24633425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 2464229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2465229984c5Sstefano_zampini ierr = VecScale(mat_ctx->vP,-1.);CHKERRQ(ierr); 2466229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->Bt_BI,mat_ctx->vP,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); 24673425bc38SStefano Zampini } 2468229984c5Sstefano_zampini } 2469229984c5Sstefano_zampini 24703425bc38SStefano Zampini /* apply BDDC */ 2471580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->benign_p0,pcbddc->benign_n);CHKERRQ(ierr); 2472dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2473229984c5Sstefano_zampini 2474229984c5Sstefano_zampini /* put values into global vector */ 2475af140850Sstefano_zampini if (pcbddc->ChangeOfBasisMatrix) work = pcbddc->work_change; 2476af140850Sstefano_zampini else work = standard_sol; 2477229984c5Sstefano_zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2478229984c5Sstefano_zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24798eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 24803425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 24813425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 248200f6b531SStefano Zampini ierr = VecAYPX(pcis->vec1_D,-1.0,mat_ctx->temp_solution_D);CHKERRQ(ierr); 248300f6b531SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); 2484c0decd05SBarry Smith /* Cannot propagate up error in KSPSolve() because there is no access to the PC */ 24853425bc38SStefano Zampini } 2486229984c5Sstefano_zampini 2487229984c5Sstefano_zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2488229984c5Sstefano_zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_D,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2489266e20e9SStefano Zampini /* add p0 solution to final solution */ 2490229984c5Sstefano_zampini ierr = PCBDDCBenignGetOrSetP0(mat_ctx->pc,work,PETSC_FALSE);CHKERRQ(ierr); 2491fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2492af140850Sstefano_zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,work,standard_sol);CHKERRQ(ierr); 2493fc17d649SStefano Zampini } 2494af140850Sstefano_zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 2495af140850Sstefano_zampini if (mat_ctx->g2g_p) { 2496229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,fetidp_flux_sol,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2497229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,fetidp_flux_sol,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2498229984c5Sstefano_zampini } 24993425bc38SStefano Zampini PetscFunctionReturn(0); 25003425bc38SStefano Zampini } 25011e6b0712SBarry Smith 25025a1e936bSStefano Zampini static PetscErrorCode PCView_BDDCIPC(PC pc, PetscViewer viewer) 25035a1e936bSStefano Zampini { 25045a1e936bSStefano Zampini PetscErrorCode ierr; 25055a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25065a1e936bSStefano Zampini PetscBool isascii; 25075a1e936bSStefano Zampini 25085a1e936bSStefano Zampini PetscFunctionBegin; 25095a1e936bSStefano Zampini ierr = PCShellGetContext(pc,(void **)&bddcipc_ctx);CHKERRQ(ierr); 25105a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 25115a1e936bSStefano Zampini if (isascii) { 25125a1e936bSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"BDDC interface preconditioner\n");CHKERRQ(ierr); 25135a1e936bSStefano Zampini } 25145a1e936bSStefano Zampini ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 25155a1e936bSStefano Zampini ierr = PCView(bddcipc_ctx->bddc,viewer);CHKERRQ(ierr); 25165a1e936bSStefano Zampini ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 25175a1e936bSStefano Zampini PetscFunctionReturn(0); 25185a1e936bSStefano Zampini } 25195a1e936bSStefano Zampini 25205a1e936bSStefano Zampini static PetscErrorCode PCSetUp_BDDCIPC(PC pc) 25215a1e936bSStefano Zampini { 25225a1e936bSStefano Zampini PetscErrorCode ierr; 25235a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25245a1e936bSStefano Zampini PetscBool isbddc; 25255a1e936bSStefano Zampini Vec vv; 25265a1e936bSStefano Zampini IS is; 25275a1e936bSStefano Zampini PC_IS *pcis; 25285a1e936bSStefano Zampini 25295a1e936bSStefano Zampini PetscFunctionBegin; 25305a1e936bSStefano Zampini ierr = PCShellGetContext(pc,(void **)&bddcipc_ctx);CHKERRQ(ierr); 25315a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)bddcipc_ctx->bddc,PCBDDC,&isbddc);CHKERRQ(ierr); 25325a1e936bSStefano Zampini if (!isbddc) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid type %s. Must be of type bddc",((PetscObject)bddcipc_ctx->bddc)->type_name); 25335a1e936bSStefano Zampini ierr = PCSetUp(bddcipc_ctx->bddc);CHKERRQ(ierr); 25345a1e936bSStefano Zampini 25355a1e936bSStefano Zampini /* create interface scatter */ 25365a1e936bSStefano Zampini pcis = (PC_IS*)(bddcipc_ctx->bddc->data); 25375a1e936bSStefano Zampini ierr = VecScatterDestroy(&bddcipc_ctx->g2l);CHKERRQ(ierr); 25385a1e936bSStefano Zampini ierr = MatCreateVecs(pc->pmat,&vv,NULL);CHKERRQ(ierr); 25395a1e936bSStefano Zampini ierr = ISRenumber(pcis->is_B_global,NULL,NULL,&is);CHKERRQ(ierr); 25409448b7f1SJunchao Zhang ierr = VecScatterCreate(vv,is,pcis->vec1_B,NULL,&bddcipc_ctx->g2l);CHKERRQ(ierr); 25415a1e936bSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 25425a1e936bSStefano Zampini ierr = VecDestroy(&vv);CHKERRQ(ierr); 25435a1e936bSStefano Zampini PetscFunctionReturn(0); 25445a1e936bSStefano Zampini } 25455a1e936bSStefano Zampini 25465a1e936bSStefano Zampini static PetscErrorCode PCApply_BDDCIPC(PC pc, Vec r, Vec x) 25475a1e936bSStefano Zampini { 25485a1e936bSStefano Zampini PetscErrorCode ierr; 25495a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25505a1e936bSStefano Zampini PC_IS *pcis; 25515a1e936bSStefano Zampini VecScatter tmps; 25525a1e936bSStefano Zampini 25535a1e936bSStefano Zampini PetscFunctionBegin; 25545a1e936bSStefano Zampini ierr = PCShellGetContext(pc,(void **)&bddcipc_ctx);CHKERRQ(ierr); 25555a1e936bSStefano Zampini pcis = (PC_IS*)(bddcipc_ctx->bddc->data); 25565a1e936bSStefano Zampini tmps = pcis->global_to_B; 25575a1e936bSStefano Zampini pcis->global_to_B = bddcipc_ctx->g2l; 25585a1e936bSStefano Zampini ierr = PCBDDCScalingRestriction(bddcipc_ctx->bddc,r,pcis->vec1_B);CHKERRQ(ierr); 25595a1e936bSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(bddcipc_ctx->bddc,PETSC_FALSE);CHKERRQ(ierr); 25605a1e936bSStefano Zampini ierr = PCBDDCScalingExtension(bddcipc_ctx->bddc,pcis->vec1_B,x);CHKERRQ(ierr); 25615a1e936bSStefano Zampini pcis->global_to_B = tmps; 25625a1e936bSStefano Zampini PetscFunctionReturn(0); 25635a1e936bSStefano Zampini } 25645a1e936bSStefano Zampini 25655a1e936bSStefano Zampini static PetscErrorCode PCApplyTranspose_BDDCIPC(PC pc, Vec r, Vec x) 25665a1e936bSStefano Zampini { 25675a1e936bSStefano Zampini PetscErrorCode ierr; 25685a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25695a1e936bSStefano Zampini PC_IS *pcis; 25705a1e936bSStefano Zampini VecScatter tmps; 25715a1e936bSStefano Zampini 25725a1e936bSStefano Zampini PetscFunctionBegin; 25735a1e936bSStefano Zampini ierr = PCShellGetContext(pc,(void **)&bddcipc_ctx);CHKERRQ(ierr); 25745a1e936bSStefano Zampini pcis = (PC_IS*)(bddcipc_ctx->bddc->data); 25755a1e936bSStefano Zampini tmps = pcis->global_to_B; 25765a1e936bSStefano Zampini pcis->global_to_B = bddcipc_ctx->g2l; 25775a1e936bSStefano Zampini ierr = PCBDDCScalingRestriction(bddcipc_ctx->bddc,r,pcis->vec1_B);CHKERRQ(ierr); 25785a1e936bSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(bddcipc_ctx->bddc,PETSC_TRUE);CHKERRQ(ierr); 25795a1e936bSStefano Zampini ierr = PCBDDCScalingExtension(bddcipc_ctx->bddc,pcis->vec1_B,x);CHKERRQ(ierr); 25805a1e936bSStefano Zampini pcis->global_to_B = tmps; 25815a1e936bSStefano Zampini PetscFunctionReturn(0); 25825a1e936bSStefano Zampini } 25835a1e936bSStefano Zampini 25845a1e936bSStefano Zampini static PetscErrorCode PCDestroy_BDDCIPC(PC pc) 25855a1e936bSStefano Zampini { 25865a1e936bSStefano Zampini PetscErrorCode ierr; 25875a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25885a1e936bSStefano Zampini 25895a1e936bSStefano Zampini PetscFunctionBegin; 25905a1e936bSStefano Zampini ierr = PCShellGetContext(pc,(void **)&bddcipc_ctx);CHKERRQ(ierr); 25915a1e936bSStefano Zampini ierr = PCDestroy(&bddcipc_ctx->bddc);CHKERRQ(ierr); 25925a1e936bSStefano Zampini ierr = VecScatterDestroy(&bddcipc_ctx->g2l);CHKERRQ(ierr); 25935a1e936bSStefano Zampini ierr = PetscFree(bddcipc_ctx);CHKERRQ(ierr); 25945a1e936bSStefano Zampini PetscFunctionReturn(0); 25955a1e936bSStefano Zampini } 25965a1e936bSStefano Zampini 25973425bc38SStefano Zampini /*@ 25980f202f7eSStefano Zampini PCBDDCMatFETIDPGetSolution - Compute the physical solution using the solution of the FETI-DP linear system 25993425bc38SStefano Zampini 26003425bc38SStefano Zampini Collective 26013425bc38SStefano Zampini 26023425bc38SStefano Zampini Input Parameters: 26030f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix obtained by a call to PCBDDCCreateFETIDPOperators 26040f202f7eSStefano Zampini - fetidp_flux_sol - the solution of the FETI-DP linear system 26053425bc38SStefano Zampini 26063425bc38SStefano Zampini Output Parameters: 26070f202f7eSStefano Zampini . standard_sol - the solution defined on the physical domain 26083425bc38SStefano Zampini 26093425bc38SStefano Zampini Level: developer 26103425bc38SStefano Zampini 26113425bc38SStefano Zampini Notes: 26123425bc38SStefano Zampini 26130f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetRHS 26143425bc38SStefano Zampini @*/ 26153425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 26163425bc38SStefano Zampini { 2617674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 26183425bc38SStefano Zampini PetscErrorCode ierr; 26193425bc38SStefano Zampini 26203425bc38SStefano Zampini PetscFunctionBegin; 2621266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2622266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_sol,VEC_CLASSID,2); 2623266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_sol,VEC_CLASSID,3); 26243425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2625163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 26263425bc38SStefano Zampini PetscFunctionReturn(0); 26273425bc38SStefano Zampini } 26281e6b0712SBarry Smith 2629547c9a8eSstefano_zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, PetscBool fully_redundant, const char* prefix, Mat *fetidp_mat, PC *fetidp_pc) 26303425bc38SStefano Zampini { 2631674ae819SStefano Zampini 2632674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 26333425bc38SStefano Zampini Mat newmat; 2634674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 26353425bc38SStefano Zampini PC newpc; 2636ce94432eSBarry Smith MPI_Comm comm; 26373425bc38SStefano Zampini PetscErrorCode ierr; 26383425bc38SStefano Zampini 26393425bc38SStefano Zampini PetscFunctionBegin; 2640ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 264115579a77SStefano Zampini /* FETI-DP matrix */ 26423425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 26431720468bSStefano Zampini fetidpmat_ctx->fully_redundant = fully_redundant; 26443425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 2645a5bb87b3Sstefano_zampini ierr = MatCreateShell(comm,fetidpmat_ctx->n,fetidpmat_ctx->n,fetidpmat_ctx->N,fetidpmat_ctx->N,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 264615579a77SStefano Zampini ierr = PetscObjectSetName((PetscObject)newmat,!fetidpmat_ctx->l2g_lambda_only ? "F" : "G");CHKERRQ(ierr); 26473425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 2648edf7251bSStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT_TRANSPOSE,(void (*)(void))FETIDPMatMultTranspose);CHKERRQ(ierr); 26493425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 265015579a77SStefano Zampini /* propagate MatOptions */ 265115579a77SStefano Zampini { 265215579a77SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)fetidpmat_ctx->pc->data; 265315579a77SStefano Zampini PetscBool issym; 265415579a77SStefano Zampini 265515579a77SStefano Zampini ierr = MatGetOption(pc->mat,MAT_SYMMETRIC,&issym);CHKERRQ(ierr); 265615579a77SStefano Zampini if (issym || pcbddc->symmetric_primal) { 265715579a77SStefano Zampini ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 265815579a77SStefano Zampini } 265915579a77SStefano Zampini } 2660547c9a8eSstefano_zampini ierr = MatSetOptionsPrefix(newmat,prefix);CHKERRQ(ierr); 2661547c9a8eSstefano_zampini ierr = MatAppendOptionsPrefix(newmat,"fetidp_");CHKERRQ(ierr); 26623425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 266315579a77SStefano Zampini /* FETI-DP preconditioner */ 26643425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 26653425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 26663425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 2667e1214c54Sstefano_zampini ierr = PCSetOperators(newpc,newmat,newmat);CHKERRQ(ierr); 2668e1214c54Sstefano_zampini ierr = PCSetOptionsPrefix(newpc,prefix);CHKERRQ(ierr); 2669e1214c54Sstefano_zampini ierr = PCAppendOptionsPrefix(newpc,"fetidp_");CHKERRQ(ierr); 2670399ffe99SStefano Zampini ierr = PCSetErrorIfFailure(newpc,pc->erroriffailure);CHKERRQ(ierr); 267115579a77SStefano Zampini if (!fetidpmat_ctx->l2g_lambda_only) { /* standard FETI-DP */ 26723425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 267315579a77SStefano Zampini ierr = PCShellSetName(newpc,"FETI-DP multipliers");CHKERRQ(ierr); 26743425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 26753425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 2676edf7251bSStefano Zampini ierr = PCShellSetApplyTranspose(newpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 2677c45b8d2dSstefano_zampini ierr = PCShellSetView(newpc,FETIDPPCView);CHKERRQ(ierr); 26783425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 26795a1e936bSStefano Zampini } else { /* saddle-point FETI-DP */ 26805a1e936bSStefano Zampini Mat M; 26815a1e936bSStefano Zampini PetscInt psize; 26825a1e936bSStefano Zampini PetscBool fake = PETSC_FALSE, isfieldsplit; 2683e1214c54Sstefano_zampini 268415579a77SStefano Zampini ierr = ISViewFromOptions(fetidpmat_ctx->lagrange,NULL,"-lag_view");CHKERRQ(ierr); 268515579a77SStefano Zampini ierr = ISViewFromOptions(fetidpmat_ctx->pressure,NULL,"-press_view");CHKERRQ(ierr); 2686e1214c54Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_PPmat",(PetscObject*)&M);CHKERRQ(ierr); 2687e1214c54Sstefano_zampini ierr = PCSetType(newpc,PCFIELDSPLIT);CHKERRQ(ierr); 2688e1214c54Sstefano_zampini ierr = PCFieldSplitSetIS(newpc,"lag",fetidpmat_ctx->lagrange);CHKERRQ(ierr); 2689e1214c54Sstefano_zampini ierr = PCFieldSplitSetIS(newpc,"p",fetidpmat_ctx->pressure);CHKERRQ(ierr); 2690e1214c54Sstefano_zampini ierr = PCFieldSplitSetType(newpc,PC_COMPOSITE_SCHUR);CHKERRQ(ierr); 269140c75d76SStefano Zampini ierr = PCFieldSplitSetSchurFactType(newpc,PC_FIELDSPLIT_SCHUR_FACT_DIAG);CHKERRQ(ierr); 26925a1e936bSStefano Zampini ierr = ISGetSize(fetidpmat_ctx->pressure,&psize);CHKERRQ(ierr); 26935a1e936bSStefano Zampini if (psize != M->rmap->N) { 26945a1e936bSStefano Zampini Mat M2; 26955a1e936bSStefano Zampini PetscInt lpsize; 26965a1e936bSStefano Zampini 26975a1e936bSStefano Zampini fake = PETSC_TRUE; 26985a1e936bSStefano Zampini ierr = ISGetLocalSize(fetidpmat_ctx->pressure,&lpsize);CHKERRQ(ierr); 26995a1e936bSStefano Zampini ierr = MatCreate(comm,&M2);CHKERRQ(ierr); 27005a1e936bSStefano Zampini ierr = MatSetType(M2,MATAIJ);CHKERRQ(ierr); 27015a1e936bSStefano Zampini ierr = MatSetSizes(M2,lpsize,lpsize,psize,psize);CHKERRQ(ierr); 27025a1e936bSStefano Zampini ierr = MatSetUp(M2);CHKERRQ(ierr); 27035a1e936bSStefano Zampini ierr = MatAssemblyBegin(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27045a1e936bSStefano Zampini ierr = MatAssemblyEnd(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27055a1e936bSStefano Zampini ierr = PCFieldSplitSetSchurPre(newpc,PC_FIELDSPLIT_SCHUR_PRE_USER,M2);CHKERRQ(ierr); 27065a1e936bSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 27075a1e936bSStefano Zampini } else { 2708e1214c54Sstefano_zampini ierr = PCFieldSplitSetSchurPre(newpc,PC_FIELDSPLIT_SCHUR_PRE_USER,M);CHKERRQ(ierr); 27095a1e936bSStefano Zampini } 2710c096484dSStefano Zampini ierr = PCFieldSplitSetSchurScale(newpc,1.0);CHKERRQ(ierr); 271115579a77SStefano Zampini 271215579a77SStefano Zampini /* we need to setfromoptions and setup here to access the blocks */ 2713e1214c54Sstefano_zampini ierr = PCSetFromOptions(newpc);CHKERRQ(ierr); 2714e1214c54Sstefano_zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 2715e1214c54Sstefano_zampini 27165a1e936bSStefano Zampini /* user may have changed the type (e.g. -fetidp_pc_type none) */ 27175a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)newpc,PCFIELDSPLIT,&isfieldsplit);CHKERRQ(ierr); 27185a1e936bSStefano Zampini if (isfieldsplit) { 27195a1e936bSStefano Zampini KSP *ksps; 27205a1e936bSStefano Zampini PC ppc,lagpc; 27215a1e936bSStefano Zampini PetscInt nn; 2722064a4176SStefano Zampini PetscBool ismatis,matisok = PETSC_FALSE,check = PETSC_FALSE; 27235a1e936bSStefano Zampini 2724e1214c54Sstefano_zampini /* set the solver for the (0,0) block */ 27255a1e936bSStefano Zampini ierr = PCFieldSplitSchurGetSubKSP(newpc,&nn,&ksps);CHKERRQ(ierr); 27265a1e936bSStefano Zampini if (!nn) { /* not of type PC_COMPOSITE_SCHUR */ 272740c75d76SStefano Zampini ierr = PCFieldSplitGetSubKSP(newpc,&nn,&ksps);CHKERRQ(ierr); 27285a1e936bSStefano Zampini if (!fake) { /* pass pmat to the pressure solver */ 27295a1e936bSStefano Zampini Mat F; 27305a1e936bSStefano Zampini 27315a1e936bSStefano Zampini ierr = KSPGetOperators(ksps[1],&F,NULL);CHKERRQ(ierr); 27325a1e936bSStefano Zampini ierr = KSPSetOperators(ksps[1],F,M);CHKERRQ(ierr); 27335a1e936bSStefano Zampini } 27345a1e936bSStefano Zampini } else { 27355a1e936bSStefano Zampini PetscBool issym; 27365a1e936bSStefano Zampini Mat S; 27375a1e936bSStefano Zampini 27385a1e936bSStefano Zampini ierr = PCFieldSplitSchurGetS(newpc,&S);CHKERRQ(ierr); 27395a1e936bSStefano Zampini 27405a1e936bSStefano Zampini ierr = MatGetOption(newmat,MAT_SYMMETRIC,&issym);CHKERRQ(ierr); 27415a1e936bSStefano Zampini if (issym) { 27425a1e936bSStefano Zampini ierr = MatSetOption(S,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 27435a1e936bSStefano Zampini } 27445a1e936bSStefano Zampini } 27455a1e936bSStefano Zampini ierr = KSPGetPC(ksps[0],&lagpc);CHKERRQ(ierr); 2746e1214c54Sstefano_zampini ierr = PCSetType(lagpc,PCSHELL);CHKERRQ(ierr); 27475a1e936bSStefano Zampini ierr = PCShellSetName(lagpc,"FETI-DP multipliers");CHKERRQ(ierr); 2748e1214c54Sstefano_zampini ierr = PCShellSetContext(lagpc,fetidppc_ctx);CHKERRQ(ierr); 2749e1214c54Sstefano_zampini ierr = PCShellSetApply(lagpc,FETIDPPCApply);CHKERRQ(ierr); 2750e1214c54Sstefano_zampini ierr = PCShellSetApplyTranspose(lagpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 2751e1214c54Sstefano_zampini ierr = PCShellSetView(lagpc,FETIDPPCView);CHKERRQ(ierr); 2752e1214c54Sstefano_zampini ierr = PCShellSetDestroy(lagpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 27535a1e936bSStefano Zampini 27545a1e936bSStefano Zampini /* Olof's idea: interface Schur complement preconditioner for the mass matrix */ 27555a1e936bSStefano Zampini ierr = KSPGetPC(ksps[1],&ppc);CHKERRQ(ierr); 27565a1e936bSStefano Zampini if (fake) { 27575a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 2758ff11fd76SStefano Zampini PetscContainer c; 27595a1e936bSStefano Zampini 27605a1e936bSStefano Zampini matisok = PETSC_TRUE; 27615a1e936bSStefano Zampini 27625a1e936bSStefano Zampini /* create inner BDDC solver */ 27635a1e936bSStefano Zampini ierr = PetscNew(&bddcipc_ctx);CHKERRQ(ierr); 27645a1e936bSStefano Zampini ierr = PCCreate(comm,&bddcipc_ctx->bddc);CHKERRQ(ierr); 27655a1e936bSStefano Zampini ierr = PCSetType(bddcipc_ctx->bddc,PCBDDC);CHKERRQ(ierr); 27665a1e936bSStefano Zampini ierr = PCSetOperators(bddcipc_ctx->bddc,M,M);CHKERRQ(ierr); 2767ff11fd76SStefano Zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_pCSR",(PetscObject*)&c);CHKERRQ(ierr); 2768ff11fd76SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)M,MATIS,&ismatis);CHKERRQ(ierr); 2769ff11fd76SStefano Zampini if (c && ismatis) { 2770ff11fd76SStefano Zampini Mat lM; 2771ff11fd76SStefano Zampini PetscInt *csr,n; 2772ff11fd76SStefano Zampini 2773ff11fd76SStefano Zampini ierr = MatISGetLocalMat(M,&lM);CHKERRQ(ierr); 2774ff11fd76SStefano Zampini ierr = MatGetSize(lM,&n,NULL);CHKERRQ(ierr); 2775ff11fd76SStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&csr);CHKERRQ(ierr); 2776ff11fd76SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(bddcipc_ctx->bddc,n,csr,csr + (n + 1),PETSC_COPY_VALUES);CHKERRQ(ierr); 2777ff11fd76SStefano Zampini ierr = MatISRestoreLocalMat(M,&lM);CHKERRQ(ierr); 2778ff11fd76SStefano Zampini } 27795a1e936bSStefano Zampini ierr = PCSetOptionsPrefix(bddcipc_ctx->bddc,((PetscObject)ksps[1])->prefix);CHKERRQ(ierr); 27805a1e936bSStefano Zampini ierr = PCSetErrorIfFailure(bddcipc_ctx->bddc,pc->erroriffailure);CHKERRQ(ierr); 27815a1e936bSStefano Zampini ierr = PCSetFromOptions(bddcipc_ctx->bddc);CHKERRQ(ierr); 27825a1e936bSStefano Zampini 27835a1e936bSStefano Zampini /* wrap the interface application */ 27845a1e936bSStefano Zampini ierr = PCSetType(ppc,PCSHELL);CHKERRQ(ierr); 27855a1e936bSStefano Zampini ierr = PCShellSetName(ppc,"FETI-DP pressure");CHKERRQ(ierr); 27865a1e936bSStefano Zampini ierr = PCShellSetContext(ppc,bddcipc_ctx);CHKERRQ(ierr); 27875a1e936bSStefano Zampini ierr = PCShellSetSetUp(ppc,PCSetUp_BDDCIPC);CHKERRQ(ierr); 27885a1e936bSStefano Zampini ierr = PCShellSetApply(ppc,PCApply_BDDCIPC);CHKERRQ(ierr); 27895a1e936bSStefano Zampini ierr = PCShellSetApplyTranspose(ppc,PCApplyTranspose_BDDCIPC);CHKERRQ(ierr); 27905a1e936bSStefano Zampini ierr = PCShellSetView(ppc,PCView_BDDCIPC);CHKERRQ(ierr); 27915a1e936bSStefano Zampini ierr = PCShellSetDestroy(ppc,PCDestroy_BDDCIPC);CHKERRQ(ierr); 27925a1e936bSStefano Zampini } 27935a1e936bSStefano Zampini 27945a1e936bSStefano Zampini /* determine if we need to assemble M to construct a preconditioner */ 27955a1e936bSStefano Zampini if (!matisok) { 27965a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)M,MATIS,&ismatis);CHKERRQ(ierr); 27975a1e936bSStefano Zampini ierr = PetscObjectTypeCompareAny((PetscObject)ppc,&matisok,PCBDDC,PCJACOBI,PCNONE,PCMG,"");CHKERRQ(ierr); 27985a1e936bSStefano Zampini if (ismatis && !matisok) { 27995a1e936bSStefano Zampini ierr = MatConvert(M,MATAIJ,MAT_INPLACE_MATRIX,&M);CHKERRQ(ierr); 28005a1e936bSStefano Zampini } 28015a1e936bSStefano Zampini } 2802064a4176SStefano Zampini 2803064a4176SStefano Zampini /* run the subproblems to check convergence */ 2804064a4176SStefano Zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)newmat)->prefix,"-check_saddlepoint",&check,NULL);CHKERRQ(ierr); 2805064a4176SStefano Zampini if (check) { 2806064a4176SStefano Zampini PetscInt i; 2807064a4176SStefano Zampini 2808064a4176SStefano Zampini for (i=0;i<nn;i++) { 2809064a4176SStefano Zampini KSP kspC; 2810064a4176SStefano Zampini PC pc; 2811064a4176SStefano Zampini Mat F,pF; 2812064a4176SStefano Zampini Vec x,y; 2813064a4176SStefano Zampini PetscBool isschur,prec = PETSC_TRUE; 2814064a4176SStefano Zampini 2815064a4176SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)ksps[i]),&kspC);CHKERRQ(ierr); 2816064a4176SStefano Zampini ierr = KSPSetOptionsPrefix(kspC,((PetscObject)ksps[i])->prefix);CHKERRQ(ierr); 2817064a4176SStefano Zampini ierr = KSPAppendOptionsPrefix(kspC,"check_");CHKERRQ(ierr); 2818064a4176SStefano Zampini ierr = KSPGetOperators(ksps[i],&F,&pF);CHKERRQ(ierr); 2819064a4176SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)F,MATSCHURCOMPLEMENT,&isschur);CHKERRQ(ierr); 2820064a4176SStefano Zampini if (isschur) { 2821064a4176SStefano Zampini KSP kspS,kspS2; 2822064a4176SStefano Zampini Mat A00,pA00,A10,A01,A11; 2823064a4176SStefano Zampini char prefix[256]; 2824064a4176SStefano Zampini 2825064a4176SStefano Zampini ierr = MatSchurComplementGetKSP(F,&kspS);CHKERRQ(ierr); 2826064a4176SStefano Zampini ierr = MatSchurComplementGetSubMatrices(F,&A00,&pA00,&A01,&A10,&A11);CHKERRQ(ierr); 2827064a4176SStefano Zampini ierr = MatCreateSchurComplement(A00,pA00,A01,A10,A11,&F);CHKERRQ(ierr); 2828064a4176SStefano Zampini ierr = MatSchurComplementGetKSP(F,&kspS2);CHKERRQ(ierr); 2829064a4176SStefano Zampini ierr = PetscSNPrintf(prefix,sizeof(prefix),"%sschur_",((PetscObject)kspC)->prefix);CHKERRQ(ierr); 2830064a4176SStefano Zampini ierr = KSPSetOptionsPrefix(kspS2,prefix);CHKERRQ(ierr); 2831064a4176SStefano Zampini ierr = KSPGetPC(kspS2,&pc);CHKERRQ(ierr); 2832064a4176SStefano Zampini ierr = PCSetType(pc,PCKSP);CHKERRQ(ierr); 2833064a4176SStefano Zampini ierr = PCKSPSetKSP(pc,kspS);CHKERRQ(ierr); 2834064a4176SStefano Zampini ierr = KSPSetFromOptions(kspS2);CHKERRQ(ierr); 2835064a4176SStefano Zampini ierr = KSPGetPC(kspS2,&pc);CHKERRQ(ierr); 2836064a4176SStefano Zampini ierr = PCSetUseAmat(pc,PETSC_TRUE);CHKERRQ(ierr); 2837064a4176SStefano Zampini } else { 2838064a4176SStefano Zampini ierr = PetscObjectReference((PetscObject)F);CHKERRQ(ierr); 2839064a4176SStefano Zampini } 2840064a4176SStefano Zampini ierr = KSPSetFromOptions(kspC);CHKERRQ(ierr); 2841064a4176SStefano Zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)kspC)->prefix,"-preconditioned",&prec,NULL);CHKERRQ(ierr); 2842064a4176SStefano Zampini if (prec) { 2843064a4176SStefano Zampini ierr = KSPGetPC(ksps[i],&pc);CHKERRQ(ierr); 2844064a4176SStefano Zampini ierr = KSPSetPC(kspC,pc);CHKERRQ(ierr); 2845064a4176SStefano Zampini } 2846064a4176SStefano Zampini ierr = KSPSetOperators(kspC,F,pF);CHKERRQ(ierr); 2847064a4176SStefano Zampini ierr = MatCreateVecs(F,&x,&y);CHKERRQ(ierr); 2848064a4176SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 2849064a4176SStefano Zampini ierr = MatMult(F,x,y);CHKERRQ(ierr); 2850064a4176SStefano Zampini ierr = KSPSolve(kspC,y,x);CHKERRQ(ierr); 2851c0decd05SBarry Smith ierr = KSPCheckSolve(kspC,pc,x);CHKERRQ(ierr); 2852064a4176SStefano Zampini ierr = KSPDestroy(&kspC);CHKERRQ(ierr); 2853064a4176SStefano Zampini ierr = MatDestroy(&F);CHKERRQ(ierr); 2854064a4176SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2855064a4176SStefano Zampini ierr = VecDestroy(&y);CHKERRQ(ierr); 2856064a4176SStefano Zampini } 2857064a4176SStefano Zampini } 2858e1214c54Sstefano_zampini ierr = PetscFree(ksps);CHKERRQ(ierr); 2859e1214c54Sstefano_zampini } 28605a1e936bSStefano Zampini } 28613425bc38SStefano Zampini /* return pointers for objects created */ 28623425bc38SStefano Zampini *fetidp_mat = newmat; 28633425bc38SStefano Zampini *fetidp_pc = newpc; 28643425bc38SStefano Zampini PetscFunctionReturn(0); 28653425bc38SStefano Zampini } 28661e6b0712SBarry Smith 286794ef8ddeSSatish Balay /*@C 28680f202f7eSStefano Zampini PCBDDCCreateFETIDPOperators - Create FETI-DP operators 28693425bc38SStefano Zampini 28703425bc38SStefano Zampini Collective 28713425bc38SStefano Zampini 28723425bc38SStefano Zampini Input Parameters: 28731720468bSStefano Zampini + pc - the BDDC preconditioning context (setup should have been called before) 2874547c9a8eSstefano_zampini . fully_redundant - true for a fully redundant set of Lagrange multipliers 2875547c9a8eSstefano_zampini - prefix - optional options database prefix for the objects to be created (can be NULL) 287628509bceSStefano Zampini 287728509bceSStefano Zampini Output Parameters: 28780f202f7eSStefano Zampini + fetidp_mat - shell FETI-DP matrix object 28790f202f7eSStefano Zampini - fetidp_pc - shell Dirichlet preconditioner for FETI-DP matrix 288028509bceSStefano Zampini 28813425bc38SStefano Zampini Level: developer 28823425bc38SStefano Zampini 28833425bc38SStefano Zampini Notes: 28840f202f7eSStefano Zampini Currently the only operations provided for FETI-DP matrix are MatMult and MatMultTranspose 28853425bc38SStefano Zampini 28860f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCMatFETIDPGetRHS, PCBDDCMatFETIDPGetSolution 28873425bc38SStefano Zampini @*/ 2888547c9a8eSstefano_zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, PetscBool fully_redundant, const char *prefix, Mat *fetidp_mat, PC *fetidp_pc) 28893425bc38SStefano Zampini { 28903425bc38SStefano Zampini PetscErrorCode ierr; 28913425bc38SStefano Zampini 28923425bc38SStefano Zampini PetscFunctionBegin; 28933425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 28943425bc38SStefano Zampini if (pc->setupcalled) { 2895547c9a8eSstefano_zampini ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,PetscBool,const char*,Mat*,PC*),(pc,fully_redundant,prefix,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 28966080607fSStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"You must call PCSetup_BDDC() first"); 28973425bc38SStefano Zampini PetscFunctionReturn(0); 28983425bc38SStefano Zampini } 28990c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2900da1bb401SStefano Zampini /*MC 2901da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 29020c7d97c5SJed Brown 290328509bceSStefano Zampini An implementation of the BDDC preconditioner based on 290428509bceSStefano Zampini 290528509bceSStefano Zampini .vb 290628509bceSStefano Zampini [1] C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 2907a8d69d7bSBarry Smith [2] A. Klawonn and O. B. Widlund. "Dual-Primal FETI Methods for Linear Elasticity", https://cs.nyu.edu/dynamic/reports/?year=all 2908a8d69d7bSBarry Smith [3] J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", https://arxiv.org/abs/0712.3977 29090f202f7eSStefano 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 291028509bceSStefano Zampini .ve 291128509bceSStefano Zampini 291228509bceSStefano Zampini The matrix to be preconditioned (Pmat) must be of type MATIS. 291328509bceSStefano Zampini 29140f202f7eSStefano Zampini Currently works with MATIS matrices with local matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers. 291528509bceSStefano Zampini 291628509bceSStefano Zampini It also works with unsymmetric and indefinite problems. 291728509bceSStefano Zampini 2918b6fdb6dfSStefano 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. 2919b6fdb6dfSStefano Zampini 2920c7017625SStefano 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). 292128509bceSStefano Zampini 29220f202f7eSStefano 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() 292330368db7SStefano Zampini Additional information on dofs can be provided by using PCBDDCSetDofsSplitting(), PCBDDCSetDirichletBoundaries(), PCBDDCSetNeumannBoundaries(), and PCBDDCSetPrimalVerticesIS() and their local counterparts. 292428509bceSStefano Zampini 29250f202f7eSStefano Zampini Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace(). Non-singular modes are retained via SVD. 292628509bceSStefano Zampini 29270f202f7eSStefano 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. 29280f202f7eSStefano Zampini User defined change of basis can be passed to PCBDDC by using PCBDDCSetChangeOfBasisMat() 292928509bceSStefano Zampini 29300f202f7eSStefano Zampini The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using a MatPartitioning object. 293128509bceSStefano Zampini 2932df4d28bfSStefano 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. 293328509bceSStefano Zampini 29340f202f7eSStefano 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. 29350f202f7eSStefano Zampini Deluxe scaling is not supported yet for FETI-DP. 29360f202f7eSStefano Zampini 29370f202f7eSStefano Zampini Options Database Keys (some of them, run with -h for a complete list): 29380f202f7eSStefano Zampini 2939a2b725a8SWilliam Gropp + -pc_bddc_use_vertices <true> - use or not vertices in primal space 29400f202f7eSStefano Zampini . -pc_bddc_use_edges <true> - use or not edges in primal space 29410f202f7eSStefano Zampini . -pc_bddc_use_faces <false> - use or not faces in primal space 29420f202f7eSStefano Zampini . -pc_bddc_symmetric <true> - symmetric computation of primal basis functions. Specify false for unsymmetric problems 29430f202f7eSStefano Zampini . -pc_bddc_use_change_of_basis <false> - use change of basis approach (on edges only) 29440f202f7eSStefano Zampini . -pc_bddc_use_change_on_faces <false> - use change of basis approach on faces if change of basis has been requested 29450f202f7eSStefano Zampini . -pc_bddc_switch_static <false> - switches from M_2 (default) to M_3 operator (see reference article [1]) 294628509bceSStefano Zampini . -pc_bddc_levels <0> - maximum number of levels for multilevel 29470f202f7eSStefano 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) 29485459c157SBarry 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) 29490f202f7eSStefano Zampini . -pc_bddc_use_deluxe_scaling <false> - use deluxe scaling 29500f202f7eSStefano 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) 2951bd2a564bSStefano 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) 295228509bceSStefano Zampini - -pc_bddc_check_level <0> - set verbosity level of debugging output 295328509bceSStefano Zampini 295428509bceSStefano Zampini Options for Dirichlet, Neumann or coarse solver can be set with 295528509bceSStefano Zampini .vb 295628509bceSStefano Zampini -pc_bddc_dirichlet_ 295728509bceSStefano Zampini -pc_bddc_neumann_ 295828509bceSStefano Zampini -pc_bddc_coarse_ 295928509bceSStefano Zampini .ve 29600f202f7eSStefano Zampini e.g -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg. PCBDDC uses by default KPSPREONLY and PCLU. 296128509bceSStefano Zampini 29620f202f7eSStefano Zampini When using a multilevel approach, solvers' options at the N-th level (N > 1) can be specified as 296328509bceSStefano Zampini .vb 2964312be037SStefano Zampini -pc_bddc_dirichlet_lN_ 2965312be037SStefano Zampini -pc_bddc_neumann_lN_ 2966312be037SStefano Zampini -pc_bddc_coarse_lN_ 296728509bceSStefano Zampini .ve 29680f202f7eSStefano Zampini Note that level number ranges from the finest (0) to the coarsest (N). 29690f202f7eSStefano 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. 29700f202f7eSStefano Zampini .vb 29710f202f7eSStefano Zampini -pc_bddc_coarse_pc_bddc_adaptive_threshold 5 -pc_bddc_coarse_l1_pc_bddc_redistribute 3 29720f202f7eSStefano Zampini .ve 29730f202f7eSStefano 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 2974da1bb401SStefano Zampini 2975da1bb401SStefano Zampini Level: intermediate 2976da1bb401SStefano Zampini 2977e94cfbe0SPatrick Sanan Developer Notes: 2978da1bb401SStefano Zampini 2979da1bb401SStefano Zampini Contributed by Stefano Zampini 2980da1bb401SStefano Zampini 2981da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 2982da1bb401SStefano Zampini M*/ 2983b2573a8aSBarry Smith 29848cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 2985da1bb401SStefano Zampini { 2986da1bb401SStefano Zampini PetscErrorCode ierr; 2987da1bb401SStefano Zampini PC_BDDC *pcbddc; 2988da1bb401SStefano Zampini 2989da1bb401SStefano Zampini PetscFunctionBegin; 2990b00a9115SJed Brown ierr = PetscNewLog(pc,&pcbddc);CHKERRQ(ierr); 2991da1bb401SStefano Zampini pc->data = (void*)pcbddc; 2992da1bb401SStefano Zampini 2993da1bb401SStefano Zampini /* create PCIS data structure */ 2994da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 2995da1bb401SStefano Zampini 29969326c5c6Sstefano_zampini /* create local graph structure */ 29979326c5c6Sstefano_zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 29989326c5c6Sstefano_zampini 29999326c5c6Sstefano_zampini /* BDDC nonzero defaults */ 300008a5cf49SStefano Zampini pcbddc->use_local_adj = PETSC_TRUE; 300147d04d0dSStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 300247d04d0dSStefano Zampini pcbddc->use_edges = PETSC_TRUE; 30033301b35fSStefano Zampini pcbddc->symmetric_primal = PETSC_TRUE; 300414f95afaSStefano Zampini pcbddc->vertex_size = 1; 3005c703fcc7SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 300668457ee5SStefano Zampini pcbddc->coarse_size = -1; 300785c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 300847d04d0dSStefano Zampini pcbddc->coarsening_ratio = 8; 300957de7509SStefano Zampini pcbddc->coarse_eqs_per_proc = 1; 301027b6a85dSStefano Zampini pcbddc->benign_compute_correction = PETSC_TRUE; 30111e0482f5SStefano Zampini pcbddc->nedfield = -1; 30121e0482f5SStefano Zampini pcbddc->nedglobal = PETSC_TRUE; 3013be12c134Sstefano_zampini pcbddc->graphmaxcount = PETSC_MAX_INT; 3014b96c3477SStefano Zampini pcbddc->sub_schurs_layers = -1; 3015bd2a564bSStefano Zampini pcbddc->adaptive_threshold[0] = 0.0; 3016bd2a564bSStefano Zampini pcbddc->adaptive_threshold[1] = 0.0; 3017b7eb3628SStefano Zampini 3018da1bb401SStefano Zampini /* function pointers */ 3019da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 302093bd9ae7SStefano Zampini pc->ops->applytranspose = PCApplyTranspose_BDDC; 3021da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 3022da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 3023da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 30246b78500eSPatrick Sanan pc->ops->view = PCView_BDDC; 3025da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 3026da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 3027da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 3028534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 3029534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 30309326c5c6Sstefano_zampini pc->ops->reset = PCReset_BDDC; 3031da1bb401SStefano Zampini 3032da1bb401SStefano Zampini /* composing function */ 3033a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",PCBDDCSetDiscreteGradient_BDDC);CHKERRQ(ierr); 3034a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",PCBDDCSetDivergenceMat_BDDC);CHKERRQ(ierr); 3035906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",PCBDDCSetChangeOfBasisMat_BDDC);CHKERRQ(ierr); 3036674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 303730368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",PCBDDCSetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 30383100ebe3SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetPrimalVerticesLocalIS_C",PCBDDCGetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 30393100ebe3SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetPrimalVerticesIS_C",PCBDDCGetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 3040bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 30412b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr); 3042b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr); 30432b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr); 3044bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 304582ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 3046bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 304782ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 3048bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 304982ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 3050bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 305182ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 3052bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 305363602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",PCBDDCSetDofsSplittingLocal_BDDC);CHKERRQ(ierr); 3054bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 3055bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 3056bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 3057bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 3058a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",PCPreSolveChangeRHS_BDDC);CHKERRQ(ierr); 3059ab8c8b98SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_BDDC);CHKERRQ(ierr); 3060da1bb401SStefano Zampini PetscFunctionReturn(0); 3061da1bb401SStefano Zampini } 306243371fb9SStefano Zampini 306343371fb9SStefano Zampini /*@C 306443371fb9SStefano Zampini PCBDDCInitializePackage - This function initializes everything in the PCBDDC package. It is called 30658a690491SBarry Smith from PCInitializePackage(). 306643371fb9SStefano Zampini 306743371fb9SStefano Zampini Level: developer 306843371fb9SStefano Zampini 306943371fb9SStefano Zampini .seealso: PetscInitialize() 307043371fb9SStefano Zampini @*/ 307143371fb9SStefano Zampini PetscErrorCode PCBDDCInitializePackage(void) 307243371fb9SStefano Zampini { 307343371fb9SStefano Zampini PetscErrorCode ierr; 307443371fb9SStefano Zampini int i; 307543371fb9SStefano Zampini 307643371fb9SStefano Zampini PetscFunctionBegin; 307743371fb9SStefano Zampini if (PCBDDCPackageInitialized) PetscFunctionReturn(0); 307843371fb9SStefano Zampini PCBDDCPackageInitialized = PETSC_TRUE; 307943371fb9SStefano Zampini ierr = PetscRegisterFinalize(PCBDDCFinalizePackage);CHKERRQ(ierr); 308043371fb9SStefano Zampini 308143371fb9SStefano Zampini /* general events */ 308243371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCTopo",PC_CLASSID,&PC_BDDC_Topology[0]);CHKERRQ(ierr); 308343371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCLKSP",PC_CLASSID,&PC_BDDC_LocalSolvers[0]);CHKERRQ(ierr); 308443371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCLWor",PC_CLASSID,&PC_BDDC_LocalWork[0]);CHKERRQ(ierr); 308543371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCorr",PC_CLASSID,&PC_BDDC_CorrectionSetUp[0]);CHKERRQ(ierr); 3086*8ead10e4SStefano Zampini ierr = PetscLogEventRegister("PCBDDCASet",PC_CLASSID,&PC_BDDC_ApproxSetUp[0]);CHKERRQ(ierr); 3087*8ead10e4SStefano Zampini ierr = PetscLogEventRegister("PCBDDCAApp",PC_CLASSID,&PC_BDDC_ApproxApply[0]);CHKERRQ(ierr); 308843371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCSet",PC_CLASSID,&PC_BDDC_CoarseSetUp[0]);CHKERRQ(ierr); 308943371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCKSP",PC_CLASSID,&PC_BDDC_CoarseSolver[0]);CHKERRQ(ierr); 309043371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCAdap",PC_CLASSID,&PC_BDDC_AdaptiveSetUp[0]);CHKERRQ(ierr); 309143371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCScal",PC_CLASSID,&PC_BDDC_Scaling[0]);CHKERRQ(ierr); 309243371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCSchr",PC_CLASSID,&PC_BDDC_Schurs[0]);CHKERRQ(ierr); 309343371fb9SStefano Zampini for (i=1;i<PETSC_PCBDDC_MAXLEVELS;i++) { 309443371fb9SStefano Zampini char ename[32]; 309543371fb9SStefano Zampini 309643371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCTopo l%02d",i);CHKERRQ(ierr); 309743371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Topology[i]);CHKERRQ(ierr); 309843371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCLKSP l%02d",i);CHKERRQ(ierr); 309943371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_LocalSolvers[i]);CHKERRQ(ierr); 310043371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCLWor l%02d",i);CHKERRQ(ierr); 310143371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_LocalWork[i]);CHKERRQ(ierr); 310243371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCorr l%02d",i);CHKERRQ(ierr); 310343371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CorrectionSetUp[i]);CHKERRQ(ierr); 3104*8ead10e4SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCASet l%02d",i);CHKERRQ(ierr); 3105*8ead10e4SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_ApproxSetUp[i]);CHKERRQ(ierr); 3106*8ead10e4SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCAApp l%02d",i);CHKERRQ(ierr); 3107*8ead10e4SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_ApproxApply[i]);CHKERRQ(ierr); 310843371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCSet l%02d",i);CHKERRQ(ierr); 310943371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CoarseSetUp[i]);CHKERRQ(ierr); 311043371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCKSP l%02d",i);CHKERRQ(ierr); 311143371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CoarseSolver[i]);CHKERRQ(ierr); 311243371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCAdap l%02d",i);CHKERRQ(ierr); 311343371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_AdaptiveSetUp[i]);CHKERRQ(ierr); 311443371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCScal l%02d",i);CHKERRQ(ierr); 311543371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Scaling[i]);CHKERRQ(ierr); 311643371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCSchr l%02d",i);CHKERRQ(ierr); 311743371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Schurs[i]);CHKERRQ(ierr); 311843371fb9SStefano Zampini } 311943371fb9SStefano Zampini PetscFunctionReturn(0); 312043371fb9SStefano Zampini } 312143371fb9SStefano Zampini 312243371fb9SStefano Zampini /*@C 312343371fb9SStefano Zampini PCBDDCFinalizePackage - This function frees everything from the PCBDDC package. It is 312443371fb9SStefano Zampini called from PetscFinalize() automatically. 312543371fb9SStefano Zampini 312643371fb9SStefano Zampini Level: developer 312743371fb9SStefano Zampini 312843371fb9SStefano Zampini .seealso: PetscFinalize() 312943371fb9SStefano Zampini @*/ 313043371fb9SStefano Zampini PetscErrorCode PCBDDCFinalizePackage(void) 313143371fb9SStefano Zampini { 313243371fb9SStefano Zampini PetscFunctionBegin; 313343371fb9SStefano Zampini PCBDDCPackageInitialized = PETSC_FALSE; 313443371fb9SStefano Zampini PetscFunctionReturn(0); 313543371fb9SStefano Zampini } 3136