153cdbc3dSStefano Zampini /* TODOLIST 2eb97c9d2SStefano Zampini 3eb97c9d2SStefano Zampini Solvers 4a0d3c3abSStefano Zampini - Add support for cholesky for coarse solver (similar to local solvers) 5eb97c9d2SStefano Zampini - Propagate ksp prefixes for solvers to mat objects? 6eb97c9d2SStefano Zampini 7eb97c9d2SStefano Zampini User interface 80f202f7eSStefano Zampini - ** DM attached to pc? 9eb97c9d2SStefano Zampini 10eb97c9d2SStefano Zampini Debugging output 11b9b85e73SStefano Zampini - * Better management of verbosity levels of debugging output 12eb97c9d2SStefano Zampini 13eb97c9d2SStefano Zampini Extra 14b9b85e73SStefano Zampini - *** Is it possible to work with PCBDDCGraph on boundary indices only (less memory consumed)? 15eb97c9d2SStefano Zampini - BDDC with MG framework? 16eb97c9d2SStefano Zampini 17eb97c9d2SStefano Zampini MATIS related operations contained in BDDC code 18eb97c9d2SStefano Zampini - Provide general case for subassembling 19eb97c9d2SStefano Zampini 2053cdbc3dSStefano Zampini */ 210c7d97c5SJed Brown 22ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 23ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 243b03a366Sstefano_zampini #include <petscblaslapack.h> 25674ae819SStefano Zampini 2643371fb9SStefano Zampini static PetscBool PCBDDCPackageInitialized = PETSC_FALSE; 2743371fb9SStefano Zampini 28f3d41395Sstefano_zampini static PetscBool cited = PETSC_FALSE; 29f3d41395Sstefano_zampini static const char citation[] = 30f3d41395Sstefano_zampini "@article{ZampiniPCBDDC,\n" 31f3d41395Sstefano_zampini "author = {Stefano Zampini},\n" 32f3d41395Sstefano_zampini "title = {{PCBDDC}: A Class of Robust Dual-Primal Methods in {PETS}c},\n" 33f3d41395Sstefano_zampini "journal = {SIAM Journal on Scientific Computing},\n" 34f3d41395Sstefano_zampini "volume = {38},\n" 35f3d41395Sstefano_zampini "number = {5},\n" 36f3d41395Sstefano_zampini "pages = {S282-S306},\n" 37f3d41395Sstefano_zampini "year = {2016},\n" 38f3d41395Sstefano_zampini "doi = {10.1137/15M1025785},\n" 39f3d41395Sstefano_zampini "URL = {http://dx.doi.org/10.1137/15M1025785},\n" 40f3d41395Sstefano_zampini "eprint = {http://dx.doi.org/10.1137/15M1025785}\n" 41f3d41395Sstefano_zampini "}\n"; 42f3d41395Sstefano_zampini 4343371fb9SStefano Zampini PetscLogEvent PC_BDDC_Topology[PETSC_PCBDDC_MAXLEVELS]; 4443371fb9SStefano Zampini PetscLogEvent PC_BDDC_LocalSolvers[PETSC_PCBDDC_MAXLEVELS]; 4543371fb9SStefano Zampini PetscLogEvent PC_BDDC_LocalWork[PETSC_PCBDDC_MAXLEVELS]; 4643371fb9SStefano Zampini PetscLogEvent PC_BDDC_CorrectionSetUp[PETSC_PCBDDC_MAXLEVELS]; 4743371fb9SStefano Zampini PetscLogEvent PC_BDDC_CoarseSetUp[PETSC_PCBDDC_MAXLEVELS]; 4843371fb9SStefano Zampini PetscLogEvent PC_BDDC_CoarseSolver[PETSC_PCBDDC_MAXLEVELS]; 4943371fb9SStefano Zampini PetscLogEvent PC_BDDC_AdaptiveSetUp[PETSC_PCBDDC_MAXLEVELS]; 5043371fb9SStefano Zampini PetscLogEvent PC_BDDC_Scaling[PETSC_PCBDDC_MAXLEVELS]; 5143371fb9SStefano Zampini PetscLogEvent PC_BDDC_Schurs[PETSC_PCBDDC_MAXLEVELS]; 5243371fb9SStefano Zampini 530369aaf7SStefano Zampini PetscErrorCode PCApply_BDDC(PC,Vec,Vec); 540369aaf7SStefano Zampini 554416b707SBarry Smith PetscErrorCode PCSetFromOptions_BDDC(PetscOptionItems *PetscOptionsObject,PC pc) 560c7d97c5SJed Brown { 570c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 58bd2a564bSStefano Zampini PetscInt nt; 590c7d97c5SJed Brown PetscErrorCode ierr; 600c7d97c5SJed Brown 610c7d97c5SJed Brown PetscFunctionBegin; 62e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"BDDC options");CHKERRQ(ierr); 638eeda7d8SStefano Zampini /* Verbose debugging */ 64a13144ffSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_check_level","Verbose output for PCBDDC (intended for debug)","none",pcbddc->dbg_flag,&pcbddc->dbg_flag,NULL);CHKERRQ(ierr); 65a13144ffSStefano Zampini /* Approximate solvers */ 66c7017625SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_dirichlet_approximate","Inform PCBDDC that we are using approximate Dirichlet solvers","none",pcbddc->NullSpace_corr[0],&pcbddc->NullSpace_corr[0],NULL);CHKERRQ(ierr); 67c7017625SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_dirichlet_approximate_scale","Inform PCBDDC that we need to scale the Dirichlet solve","none",pcbddc->NullSpace_corr[1],&pcbddc->NullSpace_corr[1],NULL);CHKERRQ(ierr); 68c7017625SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_neumann_approximate","Inform PCBDDC that we are using approximate Neumann solvers","none",pcbddc->NullSpace_corr[2],&pcbddc->NullSpace_corr[2],NULL);CHKERRQ(ierr); 69c7017625SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_neumann_approximate_scale","Inform PCBDDC that we need to scale the Neumann solve","none",pcbddc->NullSpace_corr[3],&pcbddc->NullSpace_corr[3],NULL);CHKERRQ(ierr); 706b78500eSPatrick Sanan /* Primal space customization */ 7108a5cf49SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_local_mat_graph","Use or not adjacency graph of local mat for interface analysis","none",pcbddc->use_local_adj,&pcbddc->use_local_adj,NULL);CHKERRQ(ierr); 72be12c134Sstefano_zampini ierr = PetscOptionsInt("-pc_bddc_graph_maxcount","Maximum number of shared subdomains for a connected component","none",pcbddc->graphmaxcount,&pcbddc->graphmaxcount,NULL);CHKERRQ(ierr); 731c7a958bSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_corner_selection","Activates face-based corner selection","none",pcbddc->corner_selection,&pcbddc->corner_selection,NULL);CHKERRQ(ierr); 748eeda7d8SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_vertices","Use or not corner dofs in coarse space","none",pcbddc->use_vertices,&pcbddc->use_vertices,NULL);CHKERRQ(ierr); 758eeda7d8SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_edges","Use or not edge constraints in coarse space","none",pcbddc->use_edges,&pcbddc->use_edges,NULL);CHKERRQ(ierr); 768eeda7d8SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_faces","Use or not face constraints in coarse space","none",pcbddc->use_faces,&pcbddc->use_faces,NULL);CHKERRQ(ierr); 7714f95afaSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_vertex_size","Connected components smaller or equal to vertex size will be considered as primal vertices","none",pcbddc->vertex_size,&pcbddc->vertex_size,NULL);CHKERRQ(ierr); 786661aa1dSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_true_nnsp","Use near null space attached to the matrix without modifications","none",pcbddc->use_nnsp_true,&pcbddc->use_nnsp_true,NULL);CHKERRQ(ierr); 7914f95afaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_qr_single","Use QR factorization for single constraints on cc (QR is always used when multiple constraints are present)","none",pcbddc->use_qr_single,&pcbddc->use_qr_single,NULL);CHKERRQ(ierr); 808eeda7d8SStefano Zampini /* Change of basis */ 81b9b85e73SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_change_of_basis","Use or not internal change of basis on local edge nodes","none",pcbddc->use_change_of_basis,&pcbddc->use_change_of_basis,NULL);CHKERRQ(ierr); 82b9b85e73SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_change_on_faces","Use or not internal change of basis on local face nodes","none",pcbddc->use_change_on_faces,&pcbddc->use_change_on_faces,NULL);CHKERRQ(ierr); 83674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 84674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 85674ae819SStefano Zampini } 868eeda7d8SStefano Zampini /* Switch between M_2 (default) and M_3 preconditioners (as defined by C. Dohrmann in the ref. article) */ 878eeda7d8SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_switch_static","Switch on static condensation ops around the interface preconditioner","none",pcbddc->switch_static,&pcbddc->switch_static,NULL);CHKERRQ(ierr); 8857de7509SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_coarse_eqs_per_proc","Number of equations per process for coarse problem redistribution (significant only at the coarsest level)","none",pcbddc->coarse_eqs_per_proc,&pcbddc->coarse_eqs_per_proc,NULL);CHKERRQ(ierr); 890298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr); 902b510759SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr); 91323d395dSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_coarse_estimates","Use estimated eigenvalues for coarse problem","none",pcbddc->use_coarse_estimates,&pcbddc->use_coarse_estimates,NULL);CHKERRQ(ierr); 92674ae819SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_deluxe_scaling","Use deluxe scaling for BDDC","none",pcbddc->use_deluxe_scaling,&pcbddc->use_deluxe_scaling,NULL);CHKERRQ(ierr); 93b96c3477SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_schur_rebuild","Whether or not the interface graph for Schur principal minors has to be rebuilt (i.e. define the interface without any adjacency)","none",pcbddc->sub_schurs_rebuild,&pcbddc->sub_schurs_rebuild,NULL);CHKERRQ(ierr); 94b96c3477SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_schur_layers","Number of dofs' layers for the computation of principal minors (i.e. -1 uses all dofs)","none",pcbddc->sub_schurs_layers,&pcbddc->sub_schurs_layers,NULL);CHKERRQ(ierr); 95b96c3477SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_schur_use_useradj","Whether or not the CSR graph specified by the user should be used for computing successive layers (default is to use adj of local mat)","none",pcbddc->sub_schurs_use_useradj,&pcbddc->sub_schurs_use_useradj,NULL);CHKERRQ(ierr); 96683d3df6SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_schur_exact","Whether or not to use the exact Schur complement instead of the reduced one (which excludes size 1 cc)","none",pcbddc->sub_schurs_exact_schur,&pcbddc->sub_schurs_exact_schur,NULL);CHKERRQ(ierr); 97bf3a8328SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_deluxe_zerorows","Zero rows and columns of deluxe operators associated with primal dofs","none",pcbddc->deluxe_zerorows,&pcbddc->deluxe_zerorows,NULL);CHKERRQ(ierr); 98839e9adbSstefano_zampini ierr = PetscOptionsBool("-pc_bddc_deluxe_singlemat","Collapse deluxe operators","none",pcbddc->deluxe_singlemat,&pcbddc->deluxe_singlemat,NULL);CHKERRQ(ierr); 99bf3a8328SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_adaptive_userdefined","Use user-defined constraints (should be attached via MatSetNearNullSpace to pmat) in addition to those adaptively generated","none",pcbddc->adaptive_userdefined,&pcbddc->adaptive_userdefined,NULL);CHKERRQ(ierr); 100bd2a564bSStefano Zampini nt = 2; 101bd2a564bSStefano Zampini ierr = PetscOptionsRealArray("-pc_bddc_adaptive_threshold","Thresholds to be used for adaptive selection of constraints","none",pcbddc->adaptive_threshold,&nt,NULL);CHKERRQ(ierr); 102bd2a564bSStefano Zampini if (nt == 1) pcbddc->adaptive_threshold[1] = pcbddc->adaptive_threshold[0]; 10308122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmin","Minimum number of constraints per connected components","none",pcbddc->adaptive_nmin,&pcbddc->adaptive_nmin,NULL);CHKERRQ(ierr); 10408122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmax","Maximum number of constraints per connected components","none",pcbddc->adaptive_nmax,&pcbddc->adaptive_nmax,NULL);CHKERRQ(ierr); 1053301b35fSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_symmetric","Symmetric computation of primal basis functions","none",pcbddc->symmetric_primal,&pcbddc->symmetric_primal,NULL);CHKERRQ(ierr); 106b0c7d250SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_coarse_adj","Number of processors where to map the coarse adjacency list","none",pcbddc->coarse_adj_red,&pcbddc->coarse_adj_red,NULL);CHKERRQ(ierr); 107b3afcdbeSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_benign_trick","Apply the benign subspace trick to saddle point problems with discontinuous pressures","none",pcbddc->benign_saddle_point,&pcbddc->benign_saddle_point,NULL);CHKERRQ(ierr); 108e9627c49SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_benign_change","Compute the pressure change of basis explicitly","none",pcbddc->benign_change_explicit,&pcbddc->benign_change_explicit,NULL);CHKERRQ(ierr); 10927b6a85dSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_benign_compute_correction","Compute the benign correction during PreSolve","none",pcbddc->benign_compute_correction,&pcbddc->benign_compute_correction,NULL);CHKERRQ(ierr); 110a198735bSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nonetflux","Automatic computation of no-net-flux quadrature weights","none",pcbddc->compute_nonetflux,&pcbddc->compute_nonetflux,NULL);CHKERRQ(ierr); 1114f1b2e48SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_detect_disconnected","Detects disconnected subdomains","none",pcbddc->detect_disconnected,&pcbddc->detect_disconnected,NULL);CHKERRQ(ierr); 1128361f951SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_detect_disconnected_filter","Filters out small entries in the local matrix when detecting disconnected subdomains","none",pcbddc->detect_disconnected_filter,&pcbddc->detect_disconnected_filter,NULL);CHKERRQ(ierr); 11370c64980SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_eliminate_dirichlet","Whether or not we want to eliminate dirichlet dofs during presolve","none",pcbddc->eliminate_dirdofs,&pcbddc->eliminate_dirdofs,NULL);CHKERRQ(ierr); 1140c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 1150c7d97c5SJed Brown PetscFunctionReturn(0); 1160c7d97c5SJed Brown } 1176b78500eSPatrick Sanan 1186b78500eSPatrick Sanan static PetscErrorCode PCView_BDDC(PC pc,PetscViewer viewer) 1196b78500eSPatrick Sanan { 1206b78500eSPatrick Sanan PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 121e9627c49SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1226b78500eSPatrick Sanan PetscErrorCode ierr; 12371783a16SStefano Zampini PetscBool isascii; 124e9627c49SStefano Zampini PetscSubcomm subcomm; 125e9627c49SStefano Zampini PetscViewer subviewer; 1266b78500eSPatrick Sanan 1276b78500eSPatrick Sanan PetscFunctionBegin; 1286b78500eSPatrick Sanan ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1296b78500eSPatrick Sanan /* ASCII viewer */ 1306b78500eSPatrick Sanan if (isascii) { 1314b2aedd3SStefano Zampini PetscMPIInt color,rank,size; 132fbad9177SStefano Zampini PetscInt64 loc[7],gsum[6],gmax[6],gmin[6],totbenign; 133e9627c49SStefano Zampini PetscScalar interface_size; 134e9627c49SStefano Zampini PetscReal ratio1=0.,ratio2=0.; 135e9627c49SStefano Zampini Vec counter; 1366b78500eSPatrick Sanan 137b74ba07aSstefano_zampini if (!pc->setupcalled) { 138b74ba07aSstefano_zampini ierr = PetscViewerASCIIPrintf(viewer," Partial information available: preconditioner has not been setup yet\n");CHKERRQ(ierr); 139b74ba07aSstefano_zampini } 140efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use verbose output: %D\n",pcbddc->dbg_flag);CHKERRQ(ierr); 1416f0c0a6aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use user-defined CSR: %d\n",!!pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 1426f0c0a6aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use local mat graph: %d\n",pcbddc->use_local_adj && !pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 143e9627c49SStefano Zampini if (pcbddc->mat_graph->twodim) { 144efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Connectivity graph topological dimension: 2\n");CHKERRQ(ierr); 145e9627c49SStefano Zampini } else { 146efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Connectivity graph topological dimension: 3\n");CHKERRQ(ierr); 147e9627c49SStefano Zampini } 148aefa1729SStefano Zampini if (pcbddc->graphmaxcount != PETSC_MAX_INT) { 149efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Graph max count: %D\n",pcbddc->graphmaxcount);CHKERRQ(ierr); 150aefa1729SStefano Zampini } 15150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use vertices: %d (vertex size %D)\n",pcbddc->use_vertices,pcbddc->vertex_size);CHKERRQ(ierr); 152efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use edges: %d\n",pcbddc->use_edges);CHKERRQ(ierr); 153efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use faces: %d\n",pcbddc->use_faces);CHKERRQ(ierr); 154efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use true near null space: %d\n",pcbddc->use_nnsp_true);CHKERRQ(ierr); 155efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use QR for single constraints on cc: %d\n",pcbddc->use_qr_single);CHKERRQ(ierr); 156efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use change of basis on local edge nodes: %d\n",pcbddc->use_change_of_basis);CHKERRQ(ierr); 157efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use change of basis on local face nodes: %d\n",pcbddc->use_change_on_faces);CHKERRQ(ierr); 158efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," User defined change of basis matrix: %d\n",!!pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 159efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Has change of basis matrix: %d\n",!!pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 160efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eliminate dirichlet boundary dofs: %d\n",pcbddc->eliminate_dirdofs);CHKERRQ(ierr); 161efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Switch on static condensation ops around the interface preconditioner: %d\n",pcbddc->switch_static);CHKERRQ(ierr); 162efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use exact dirichlet trick: %d\n",pcbddc->use_exact_dirichlet_trick);CHKERRQ(ierr); 16350e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Multilevel max levels: %D\n",pcbddc->max_levels);CHKERRQ(ierr); 16450e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Multilevel coarsening ratio: %D\n",pcbddc->coarsening_ratio);CHKERRQ(ierr); 165efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use estimated eigs for coarse problem: %d\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 166efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe scaling: %d\n",pcbddc->use_deluxe_scaling);CHKERRQ(ierr); 167efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe zerorows: %d\n",pcbddc->deluxe_zerorows);CHKERRQ(ierr); 168efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe singlemat: %d\n",pcbddc->deluxe_singlemat);CHKERRQ(ierr); 169efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Rebuild interface graph for Schur principal minors: %d\n",pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 17050e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Number of dofs' layers for the computation of principal minors: %D\n",pcbddc->sub_schurs_layers);CHKERRQ(ierr); 171efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use user CSR graph to compute successive layers: %d\n",pcbddc->sub_schurs_use_useradj);CHKERRQ(ierr); 172bd2a564bSStefano Zampini if (pcbddc->adaptive_threshold[1] != pcbddc->adaptive_threshold[0]) { 173bd2a564bSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Adaptive constraint selection thresholds (active %d, userdefined %d): %g,%g\n",pcbddc->adaptive_selection,pcbddc->adaptive_userdefined,pcbddc->adaptive_threshold[0],pcbddc->adaptive_threshold[1]);CHKERRQ(ierr); 174bd2a564bSStefano Zampini } else { 175bd2a564bSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Adaptive constraint selection threshold (active %d, userdefined %d): %g\n",pcbddc->adaptive_selection,pcbddc->adaptive_userdefined,pcbddc->adaptive_threshold[0]);CHKERRQ(ierr); 176bd2a564bSStefano Zampini } 17750e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Min constraints / connected component: %D\n",pcbddc->adaptive_nmin);CHKERRQ(ierr); 17850e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Max constraints / connected component: %D\n",pcbddc->adaptive_nmax);CHKERRQ(ierr); 179efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Invert exact Schur complement for adaptive selection: %d\n",pcbddc->sub_schurs_exact_schur);CHKERRQ(ierr); 180efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Symmetric computation of primal basis functions: %d\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 18150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Num. Procs. to map coarse adjacency list: %D\n",pcbddc->coarse_adj_red);CHKERRQ(ierr); 18250e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Coarse eqs per proc (significant at the coarsest level): %D\n",pcbddc->coarse_eqs_per_proc);CHKERRQ(ierr); 1838361f951SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Detect disconnected: %d (filter %d)\n",pcbddc->detect_disconnected,pcbddc->detect_disconnected_filter);CHKERRQ(ierr); 184efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Benign subspace trick: %d (change explicit %d)\n",pcbddc->benign_saddle_point,pcbddc->benign_change_explicit);CHKERRQ(ierr); 185efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Benign subspace trick is active: %d\n",pcbddc->benign_have_null);CHKERRQ(ierr); 186*15579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Algebraic computation of no-net-flux: %d\n",pcbddc->compute_nonetflux);CHKERRQ(ierr); 187b74ba07aSstefano_zampini if (!pc->setupcalled) PetscFunctionReturn(0); 1886b78500eSPatrick Sanan 189fbad9177SStefano Zampini /* compute interface size */ 190e9627c49SStefano Zampini ierr = VecSet(pcis->vec1_B,1.0);CHKERRQ(ierr); 191e9627c49SStefano Zampini ierr = MatCreateVecs(pc->pmat,&counter,0);CHKERRQ(ierr); 192e9627c49SStefano Zampini ierr = VecSet(counter,0.0);CHKERRQ(ierr); 193e9627c49SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 194e9627c49SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 195e9627c49SStefano Zampini ierr = VecSum(counter,&interface_size);CHKERRQ(ierr); 196e9627c49SStefano Zampini ierr = VecDestroy(&counter);CHKERRQ(ierr); 197fbad9177SStefano Zampini 198fbad9177SStefano Zampini /* compute some statistics on the domain decomposition */ 199e9627c49SStefano Zampini gsum[0] = 1; 200fbad9177SStefano Zampini gsum[1] = gsum[2] = gsum[3] = gsum[4] = gsum[5] = 0; 201e9627c49SStefano Zampini loc[0] = !!pcis->n; 202e9627c49SStefano Zampini loc[1] = pcis->n - pcis->n_B; 203e9627c49SStefano Zampini loc[2] = pcis->n_B; 204e9627c49SStefano Zampini loc[3] = pcbddc->local_primal_size; 205345ecf6cSStefano Zampini loc[4] = pcis->n; 206fbad9177SStefano Zampini loc[5] = pcbddc->n_local_subs > 0 ? pcbddc->n_local_subs : (pcis->n ? 1 : 0); 207fbad9177SStefano Zampini loc[6] = pcbddc->benign_n; 208fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gsum,6,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 209fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = -1; 210fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gmax,6,MPIU_INT64,MPI_MAX,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 211fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = PETSC_MAX_INT; 212fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gmin,6,MPIU_INT64,MPI_MIN,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 213fbad9177SStefano Zampini ierr = MPI_Reduce(&loc[6],&totbenign,1,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 214e9627c49SStefano Zampini if (pcbddc->coarse_size) { 215e9627c49SStefano Zampini ratio1 = pc->pmat->rmap->N/(1.*pcbddc->coarse_size); 216e9627c49SStefano Zampini ratio2 = PetscRealPart(interface_size)/pcbddc->coarse_size; 217e9627c49SStefano Zampini } 218efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"********************************** STATISTICS AT LEVEL %d **********************************\n",pcbddc->current_level);CHKERRQ(ierr); 21950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Global dofs sizes: all %D interface %D coarse %D\n",pc->pmat->rmap->N,(PetscInt)PetscRealPart(interface_size),pcbddc->coarse_size);CHKERRQ(ierr); 22050e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Coarsening ratios: all/coarse %D interface/coarse %D\n",(PetscInt)ratio1,(PetscInt)ratio2);CHKERRQ(ierr); 22150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Active processes : %D\n",(PetscInt)gsum[0]);CHKERRQ(ierr); 22250e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Total subdomains : %D\n",(PetscInt)gsum[5]);CHKERRQ(ierr); 223345ecf6cSStefano Zampini if (pcbddc->benign_have_null) { 22450e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Benign subs : %D\n",(PetscInt)totbenign);CHKERRQ(ierr); 225345ecf6cSStefano Zampini } 22650e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Dofs type :\tMIN\tMAX\tMEAN\n");CHKERRQ(ierr); 22750e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Interior dofs :\t%D\t%D\t%D\n",(PetscInt)gmin[1],(PetscInt)gmax[1],(PetscInt)(gsum[1]/gsum[0]));CHKERRQ(ierr); 22850e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Interface dofs :\t%D\t%D\t%D\n",(PetscInt)gmin[2],(PetscInt)gmax[2],(PetscInt)(gsum[2]/gsum[0]));CHKERRQ(ierr); 22950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Primal dofs :\t%D\t%D\t%D\n",(PetscInt)gmin[3],(PetscInt)gmax[3],(PetscInt)(gsum[3]/gsum[0]));CHKERRQ(ierr); 23050e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Local dofs :\t%D\t%D\t%D\n",(PetscInt)gmin[4],(PetscInt)gmax[4],(PetscInt)(gsum[4]/gsum[0]));CHKERRQ(ierr); 23150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Local subs :\t%D\t%D\n" ,(PetscInt)gmin[5],(PetscInt)gmax[5]);CHKERRQ(ierr); 232*15579a77SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 233*15579a77SStefano Zampini 234*15579a77SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 235*15579a77SStefano Zampini 236*15579a77SStefano Zampini /* local solvers */ 237*15579a77SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscObjectComm((PetscObject)pcbddc->ksp_D),&subviewer);CHKERRQ(ierr); 238*15579a77SStefano Zampini if (!rank) { 239*15579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Interior solver (rank 0)\n");CHKERRQ(ierr); 240*15579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 241*15579a77SStefano Zampini ierr = KSPView(pcbddc->ksp_D,subviewer);CHKERRQ(ierr); 242*15579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 243*15579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Correction solver (rank 0)\n");CHKERRQ(ierr); 244*15579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 245*15579a77SStefano Zampini ierr = KSPView(pcbddc->ksp_R,subviewer);CHKERRQ(ierr); 246*15579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 247*15579a77SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 248*15579a77SStefano Zampini } 249*15579a77SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscObjectComm((PetscObject)pcbddc->ksp_D),&subviewer);CHKERRQ(ierr); 25027b6a85dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 251e9627c49SStefano Zampini 252fbad9177SStefano Zampini /* the coarse problem can be handled by a different communicator */ 253e9627c49SStefano Zampini if (pcbddc->coarse_ksp) color = 1; 254e9627c49SStefano Zampini else color = 0; 2554b2aedd3SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 256e9627c49SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)pc),&subcomm);CHKERRQ(ierr); 2574b2aedd3SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,PetscMin(size,2));CHKERRQ(ierr); 258e9627c49SStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 259e9627c49SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 260e9627c49SStefano Zampini if (color == 1) { 261*15579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Coarse solver\n");CHKERRQ(ierr); 262*15579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 263e9627c49SStefano Zampini ierr = KSPView(pcbddc->coarse_ksp,subviewer);CHKERRQ(ierr); 264*15579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 265e9627c49SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 266e9627c49SStefano Zampini } 267e9627c49SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 268e9627c49SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 269e9627c49SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 270e9627c49SStefano Zampini } 2716b78500eSPatrick Sanan PetscFunctionReturn(0); 2726b78500eSPatrick Sanan } 273a13144ffSStefano Zampini 2741e0482f5SStefano Zampini static PetscErrorCode PCBDDCSetDiscreteGradient_BDDC(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 275a13144ffSStefano Zampini { 276a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 277a13144ffSStefano Zampini PetscErrorCode ierr; 278a13144ffSStefano Zampini 279a13144ffSStefano Zampini PetscFunctionBegin; 280a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr); 281a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 282a13144ffSStefano Zampini pcbddc->discretegradient = G; 283a13144ffSStefano Zampini pcbddc->nedorder = order > 0 ? order : -order; 284495a2a07SStefano Zampini pcbddc->nedfield = field; 2851e0482f5SStefano Zampini pcbddc->nedglobal = global; 2861e0482f5SStefano Zampini pcbddc->conforming = conforming; 287a13144ffSStefano Zampini PetscFunctionReturn(0); 288a13144ffSStefano Zampini } 289a13144ffSStefano Zampini 290a13144ffSStefano Zampini /*@ 291a13144ffSStefano Zampini PCBDDCSetDiscreteGradient - Sets the discrete gradient 292a13144ffSStefano Zampini 293a13144ffSStefano Zampini Collective on PC 294a13144ffSStefano Zampini 295a13144ffSStefano Zampini Input Parameters: 296a13144ffSStefano Zampini + pc - the preconditioning context 297a13144ffSStefano Zampini . G - the discrete gradient matrix (should be in AIJ format) 298a13144ffSStefano Zampini . order - the order of the Nedelec space (1 for the lowest order) 299495a2a07SStefano Zampini . field - the field id of the Nedelec dofs (not used if the fields have not been specified) 3001e0482f5SStefano Zampini . global - the type of global ordering for the rows of G 301a13144ffSStefano Zampini - conforming - whether the mesh is conforming or not 302a13144ffSStefano Zampini 303a13144ffSStefano Zampini Level: advanced 304a13144ffSStefano Zampini 30595452b02SPatrick Sanan Notes: 30695452b02SPatrick Sanan The discrete gradient matrix G is used to analyze the subdomain edges, and it should not contain any zero entry. 307495a2a07SStefano Zampini For variable order spaces, the order should be set to zero. 3081e0482f5SStefano Zampini If global is true, the rows of G should be given in global ordering for the whole dofs; 3091e0482f5SStefano Zampini if false, the ordering should be global for the Nedelec field. 3101e0482f5SStefano 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 3111e0482f5SStefano Zampini and geid the one for the Nedelec field. 312a13144ffSStefano Zampini 313495a2a07SStefano Zampini .seealso: PCBDDC,PCBDDCSetDofsSplitting(),PCBDDCSetDofsSplittingLocal() 314a13144ffSStefano Zampini @*/ 3151e0482f5SStefano Zampini PetscErrorCode PCBDDCSetDiscreteGradient(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 316a13144ffSStefano Zampini { 317a13144ffSStefano Zampini PetscErrorCode ierr; 318a13144ffSStefano Zampini 319a13144ffSStefano Zampini PetscFunctionBegin; 320a13144ffSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 321a13144ffSStefano Zampini PetscValidHeaderSpecific(G,MAT_CLASSID,2); 322a13144ffSStefano Zampini PetscValidLogicalCollectiveInt(pc,order,3); 3231e0482f5SStefano Zampini PetscValidLogicalCollectiveInt(pc,field,4); 3241e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,global,5); 3251e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,conforming,6); 3261e0482f5SStefano Zampini PetscCheckSameComm(pc,1,G,2); 3271e0482f5SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDiscreteGradient_C",(PC,Mat,PetscInt,PetscInt,PetscBool,PetscBool),(pc,G,order,field,global,conforming));CHKERRQ(ierr); 328a13144ffSStefano Zampini PetscFunctionReturn(0); 329a13144ffSStefano Zampini } 330a13144ffSStefano Zampini 3318ae0ca82SStefano Zampini static PetscErrorCode PCBDDCSetDivergenceMat_BDDC(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 332a198735bSStefano Zampini { 333a198735bSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 334a198735bSStefano Zampini PetscErrorCode ierr; 3356b78500eSPatrick Sanan 336a198735bSStefano Zampini PetscFunctionBegin; 337a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)divudotp);CHKERRQ(ierr); 338a198735bSStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 339a198735bSStefano Zampini pcbddc->divudotp = divudotp; 3408ae0ca82SStefano Zampini pcbddc->divudotp_trans = trans; 341a198735bSStefano Zampini pcbddc->compute_nonetflux = PETSC_TRUE; 342a198735bSStefano Zampini if (vl2l) { 343a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2l);CHKERRQ(ierr); 344fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 345a198735bSStefano Zampini pcbddc->divudotp_vl2l = vl2l; 346a198735bSStefano Zampini } 347a198735bSStefano Zampini PetscFunctionReturn(0); 348a198735bSStefano Zampini } 3493d996552SStefano Zampini 350a198735bSStefano Zampini /*@ 351a198735bSStefano Zampini PCBDDCSetDivergenceMat - Sets the linear operator representing \int_\Omega \div {\bf u} \cdot p dx 352a198735bSStefano Zampini 353a198735bSStefano Zampini Collective on PC 354a198735bSStefano Zampini 355a198735bSStefano Zampini Input Parameters: 356a198735bSStefano Zampini + pc - the preconditioning context 357a198735bSStefano Zampini . divudotp - the matrix (must be of type MATIS) 3588ae0ca82SStefano Zampini . trans - if trans if false (resp. true), then pressures are in the test (trial) space and velocities are in the trial (test) space. 35905a3bf82SStefano 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 360a198735bSStefano Zampini 361a198735bSStefano Zampini Level: advanced 362a198735bSStefano Zampini 36395452b02SPatrick Sanan Notes: 36495452b02SPatrick Sanan This auxiliary matrix is used to compute quadrature weights representing the net-flux across subdomain boundaries 36505a3bf82SStefano Zampini If vl2l is NULL, the local ordering for velocities in divudotp should match that of the preconditioning matrix 366a198735bSStefano Zampini 367a198735bSStefano Zampini .seealso: PCBDDC 368a198735bSStefano Zampini @*/ 3698ae0ca82SStefano Zampini PetscErrorCode PCBDDCSetDivergenceMat(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 370a198735bSStefano Zampini { 371a198735bSStefano Zampini PetscBool ismatis; 372a198735bSStefano Zampini PetscErrorCode ierr; 373a198735bSStefano Zampini 374a198735bSStefano Zampini PetscFunctionBegin; 375a198735bSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 376a198735bSStefano Zampini PetscValidHeaderSpecific(divudotp,MAT_CLASSID,2); 377a198735bSStefano Zampini PetscCheckSameComm(pc,1,divudotp,2); 3788ae0ca82SStefano Zampini PetscValidLogicalCollectiveBool(pc,trans,3); 3798ae0ca82SStefano Zampini if (vl2l) PetscValidHeaderSpecific(divudotp,IS_CLASSID,4); 380a198735bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)divudotp,MATIS,&ismatis);CHKERRQ(ierr); 381a198735bSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Divergence matrix needs to be of type MATIS"); 3828ae0ca82SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDivergenceMat_C",(PC,Mat,PetscBool,IS),(pc,divudotp,trans,vl2l));CHKERRQ(ierr); 383a198735bSStefano Zampini PetscFunctionReturn(0); 384a198735bSStefano Zampini } 3852d505d7fSStefano Zampini 3861dd7afcfSStefano Zampini static PetscErrorCode PCBDDCSetChangeOfBasisMat_BDDC(PC pc, Mat change, PetscBool interior) 387b9b85e73SStefano Zampini { 388b9b85e73SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 389b9b85e73SStefano Zampini PetscErrorCode ierr; 390b9b85e73SStefano Zampini 391b9b85e73SStefano Zampini PetscFunctionBegin; 392b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)change);CHKERRQ(ierr); 39356282151SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 394b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = change; 3951dd7afcfSStefano Zampini pcbddc->change_interior = interior; 396b9b85e73SStefano Zampini PetscFunctionReturn(0); 397b9b85e73SStefano Zampini } 398b9b85e73SStefano Zampini /*@ 399906d46d4SStefano Zampini PCBDDCSetChangeOfBasisMat - Set user defined change of basis for dofs 400b9b85e73SStefano Zampini 401b9b85e73SStefano Zampini Collective on PC 402b9b85e73SStefano Zampini 403b9b85e73SStefano Zampini Input Parameters: 404b9b85e73SStefano Zampini + pc - the preconditioning context 4051dd7afcfSStefano Zampini . change - the change of basis matrix 4061dd7afcfSStefano Zampini - interior - whether or not the change of basis modifies interior dofs 407b9b85e73SStefano Zampini 408b9b85e73SStefano Zampini Level: intermediate 409b9b85e73SStefano Zampini 410b9b85e73SStefano Zampini Notes: 411b9b85e73SStefano Zampini 412b9b85e73SStefano Zampini .seealso: PCBDDC 413b9b85e73SStefano Zampini @*/ 4141dd7afcfSStefano Zampini PetscErrorCode PCBDDCSetChangeOfBasisMat(PC pc, Mat change, PetscBool interior) 415b9b85e73SStefano Zampini { 416b9b85e73SStefano Zampini PetscErrorCode ierr; 417b9b85e73SStefano Zampini 418b9b85e73SStefano Zampini PetscFunctionBegin; 419b9b85e73SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 420b9b85e73SStefano Zampini PetscValidHeaderSpecific(change,MAT_CLASSID,2); 421906d46d4SStefano Zampini PetscCheckSameComm(pc,1,change,2); 422906d46d4SStefano Zampini if (pc->mat) { 423906d46d4SStefano Zampini PetscInt rows_c,cols_c,rows,cols; 424906d46d4SStefano Zampini ierr = MatGetSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 425906d46d4SStefano Zampini ierr = MatGetSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 426e0fe2d75SToby 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); 427e0fe2d75SToby 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); 428906d46d4SStefano Zampini ierr = MatGetLocalSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 429906d46d4SStefano Zampini ierr = MatGetLocalSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 430e0fe2d75SToby 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); 431e0fe2d75SToby 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); 432906d46d4SStefano Zampini } 4331dd7afcfSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetChangeOfBasisMat_C",(PC,Mat,PetscBool),(pc,change,interior));CHKERRQ(ierr); 434b9b85e73SStefano Zampini PetscFunctionReturn(0); 435b9b85e73SStefano Zampini } 4362d505d7fSStefano Zampini 43730368db7SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesIS_BDDC(PC pc, IS PrimalVertices) 43830368db7SStefano Zampini { 43930368db7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 44056282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 44130368db7SStefano Zampini PetscErrorCode ierr; 44230368db7SStefano Zampini 44330368db7SStefano Zampini PetscFunctionBegin; 44456282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 44556282151SStefano Zampini if (pcbddc->user_primal_vertices) { 44656282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices,&isequal);CHKERRQ(ierr); 44756282151SStefano Zampini } 44830368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 44930368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 45030368db7SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 45156282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 45230368db7SStefano Zampini PetscFunctionReturn(0); 45330368db7SStefano Zampini } 454ab8c8b98SStefano Zampini 45530368db7SStefano Zampini /*@ 45630368db7SStefano Zampini PCBDDCSetPrimalVerticesIS - Set additional user defined primal vertices in PCBDDC 45730368db7SStefano Zampini 45830368db7SStefano Zampini Collective 45930368db7SStefano Zampini 46030368db7SStefano Zampini Input Parameters: 46130368db7SStefano Zampini + pc - the preconditioning context 46230368db7SStefano Zampini - PrimalVertices - index set of primal vertices in global numbering (can be empty) 46330368db7SStefano Zampini 46430368db7SStefano Zampini Level: intermediate 46530368db7SStefano Zampini 46630368db7SStefano Zampini Notes: 46730368db7SStefano Zampini Any process can list any global node 46830368db7SStefano Zampini 46930368db7SStefano Zampini .seealso: PCBDDC 47030368db7SStefano Zampini @*/ 47130368db7SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesIS(PC pc, IS PrimalVertices) 47230368db7SStefano Zampini { 47330368db7SStefano Zampini PetscErrorCode ierr; 47430368db7SStefano Zampini 47530368db7SStefano Zampini PetscFunctionBegin; 47630368db7SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 47730368db7SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 47830368db7SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 47930368db7SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 48030368db7SStefano Zampini PetscFunctionReturn(0); 48130368db7SStefano Zampini } 4822d505d7fSStefano Zampini 483674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 484674ae819SStefano Zampini { 485674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 48656282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 487674ae819SStefano Zampini PetscErrorCode ierr; 4881e6b0712SBarry Smith 489674ae819SStefano Zampini PetscFunctionBegin; 49056282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 49156282151SStefano Zampini if (pcbddc->user_primal_vertices_local) { 49256282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices_local,&isequal);CHKERRQ(ierr); 49356282151SStefano Zampini } 494674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 49530368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 49630368db7SStefano Zampini pcbddc->user_primal_vertices_local = PrimalVertices; 49756282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 498674ae819SStefano Zampini PetscFunctionReturn(0); 499674ae819SStefano Zampini } 500674ae819SStefano Zampini /*@ 50128509bceSStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC 502674ae819SStefano Zampini 50317eb1463SStefano Zampini Collective 504674ae819SStefano Zampini 505674ae819SStefano Zampini Input Parameters: 506674ae819SStefano Zampini + pc - the preconditioning context 50717eb1463SStefano Zampini - PrimalVertices - index set of primal vertices in local numbering (can be empty) 508674ae819SStefano Zampini 509674ae819SStefano Zampini Level: intermediate 510674ae819SStefano Zampini 511674ae819SStefano Zampini Notes: 512674ae819SStefano Zampini 513674ae819SStefano Zampini .seealso: PCBDDC 514674ae819SStefano Zampini @*/ 515674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 516674ae819SStefano Zampini { 517674ae819SStefano Zampini PetscErrorCode ierr; 518674ae819SStefano Zampini 519674ae819SStefano Zampini PetscFunctionBegin; 520674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 521674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 52217eb1463SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 523674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 524674ae819SStefano Zampini PetscFunctionReturn(0); 525674ae819SStefano Zampini } 5262d505d7fSStefano Zampini 5274fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 5284fad6a16SStefano Zampini { 5294fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5304fad6a16SStefano Zampini 5314fad6a16SStefano Zampini PetscFunctionBegin; 5324fad6a16SStefano Zampini pcbddc->coarsening_ratio = k; 5334fad6a16SStefano Zampini PetscFunctionReturn(0); 5344fad6a16SStefano Zampini } 5351e6b0712SBarry Smith 5364fad6a16SStefano Zampini /*@ 53728509bceSStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel 5384fad6a16SStefano Zampini 5394fad6a16SStefano Zampini Logically collective on PC 5404fad6a16SStefano Zampini 5414fad6a16SStefano Zampini Input Parameters: 5424fad6a16SStefano Zampini + pc - the preconditioning context 54328509bceSStefano Zampini - k - coarsening ratio (H/h at the coarser level) 5444fad6a16SStefano Zampini 5450f202f7eSStefano Zampini Options Database Keys: 5460f202f7eSStefano Zampini . -pc_bddc_coarsening_ratio 5474fad6a16SStefano Zampini 5484fad6a16SStefano Zampini Level: intermediate 5494fad6a16SStefano Zampini 5504fad6a16SStefano Zampini Notes: 5510f202f7eSStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level 5524fad6a16SStefano Zampini 5530f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetLevels() 5544fad6a16SStefano Zampini @*/ 5554fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 5564fad6a16SStefano Zampini { 5574fad6a16SStefano Zampini PetscErrorCode ierr; 5584fad6a16SStefano Zampini 5594fad6a16SStefano Zampini PetscFunctionBegin; 5604fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5612b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,k,2); 5624fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 5634fad6a16SStefano Zampini PetscFunctionReturn(0); 5644fad6a16SStefano Zampini } 5652b510759SStefano Zampini 566b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */ 567b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg) 568b8ffe317SStefano Zampini { 569b8ffe317SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 570b8ffe317SStefano Zampini 571b8ffe317SStefano Zampini PetscFunctionBegin; 57285c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = flg; 573b8ffe317SStefano Zampini PetscFunctionReturn(0); 574b8ffe317SStefano Zampini } 575b8ffe317SStefano Zampini 576b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg) 5772b510759SStefano Zampini { 5782b510759SStefano Zampini PetscErrorCode ierr; 5792b510759SStefano Zampini 5802b510759SStefano Zampini PetscFunctionBegin; 5812b510759SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 582b8ffe317SStefano Zampini PetscValidLogicalCollectiveBool(pc,flg,2); 583b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr); 5842b510759SStefano Zampini PetscFunctionReturn(0); 5852b510759SStefano Zampini } 5861e6b0712SBarry Smith 5872b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level) 5884fad6a16SStefano Zampini { 5894fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5904fad6a16SStefano Zampini 5914fad6a16SStefano Zampini PetscFunctionBegin; 5922b510759SStefano Zampini pcbddc->current_level = level; 5934fad6a16SStefano Zampini PetscFunctionReturn(0); 5944fad6a16SStefano Zampini } 5951e6b0712SBarry Smith 596b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 597b8ffe317SStefano Zampini { 598b8ffe317SStefano Zampini PetscErrorCode ierr; 599b8ffe317SStefano Zampini 600b8ffe317SStefano Zampini PetscFunctionBegin; 601b8ffe317SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 602b8ffe317SStefano Zampini PetscValidLogicalCollectiveInt(pc,level,2); 603b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr); 604b8ffe317SStefano Zampini PetscFunctionReturn(0); 605b8ffe317SStefano Zampini } 606b8ffe317SStefano Zampini 6072b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels) 6082b510759SStefano Zampini { 6092b510759SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6102b510759SStefano Zampini 6112b510759SStefano Zampini PetscFunctionBegin; 6122b510759SStefano Zampini pcbddc->max_levels = levels; 6132b510759SStefano Zampini PetscFunctionReturn(0); 6142b510759SStefano Zampini } 6152b510759SStefano Zampini 6164fad6a16SStefano Zampini /*@ 61737ebbdf7SStefano Zampini PCBDDCSetLevels - Sets the maximum number of additional levels allowed for multilevel BDDC 6184fad6a16SStefano Zampini 6194fad6a16SStefano Zampini Logically collective on PC 6204fad6a16SStefano Zampini 6214fad6a16SStefano Zampini Input Parameters: 6224fad6a16SStefano Zampini + pc - the preconditioning context 62337ebbdf7SStefano Zampini - levels - the maximum number of levels 6244fad6a16SStefano Zampini 6250f202f7eSStefano Zampini Options Database Keys: 6260f202f7eSStefano Zampini . -pc_bddc_levels 6274fad6a16SStefano Zampini 6284fad6a16SStefano Zampini Level: intermediate 6294fad6a16SStefano Zampini 6304fad6a16SStefano Zampini Notes: 63137ebbdf7SStefano Zampini The default value is 0, that gives the classical two-levels BDDC 6324fad6a16SStefano Zampini 6330f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetCoarseningRatio() 6344fad6a16SStefano Zampini @*/ 6352b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels) 6364fad6a16SStefano Zampini { 6374fad6a16SStefano Zampini PetscErrorCode ierr; 6384fad6a16SStefano Zampini 6394fad6a16SStefano Zampini PetscFunctionBegin; 6404fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6412b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,levels,2); 64237ebbdf7SStefano Zampini if (levels > PETSC_PCBDDC_MAXLEVELS-1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Maximum number of additional levels for BDDC is %d\n",PETSC_PCBDDC_MAXLEVELS-1); 6432b510759SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr); 6444fad6a16SStefano Zampini PetscFunctionReturn(0); 6454fad6a16SStefano Zampini } 6461e6b0712SBarry Smith 6473b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 6483b03a366Sstefano_zampini { 6493b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 65056282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 6513b03a366Sstefano_zampini PetscErrorCode ierr; 6523b03a366Sstefano_zampini 6533b03a366Sstefano_zampini PetscFunctionBegin; 65456282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 65556282151SStefano Zampini if (pcbddc->DirichletBoundaries) { 65656282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundaries,&isequal);CHKERRQ(ierr); 65756282151SStefano Zampini } 658785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 659785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 6603b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 66136e030ebSStefano Zampini pcbddc->DirichletBoundaries = DirichletBoundaries; 66256282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 6633b03a366Sstefano_zampini PetscFunctionReturn(0); 6643b03a366Sstefano_zampini } 6651e6b0712SBarry Smith 6663b03a366Sstefano_zampini /*@ 66728509bceSStefano Zampini PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem. 6683b03a366Sstefano_zampini 669785d1243SStefano Zampini Collective 6703b03a366Sstefano_zampini 6713b03a366Sstefano_zampini Input Parameters: 6723b03a366Sstefano_zampini + pc - the preconditioning context 673785d1243SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries 6743b03a366Sstefano_zampini 6753b03a366Sstefano_zampini Level: intermediate 6763b03a366Sstefano_zampini 6770f202f7eSStefano Zampini Notes: 6780f202f7eSStefano Zampini Provide the information if you used MatZeroRows/Columns routines. Any process can list any global node 6793b03a366Sstefano_zampini 6800f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundariesLocal(), MatZeroRows(), MatZeroRowsColumns() 6813b03a366Sstefano_zampini @*/ 6823b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 6833b03a366Sstefano_zampini { 6843b03a366Sstefano_zampini PetscErrorCode ierr; 6853b03a366Sstefano_zampini 6863b03a366Sstefano_zampini PetscFunctionBegin; 6873b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 688674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 689785d1243SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 6903b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 6913b03a366Sstefano_zampini PetscFunctionReturn(0); 6923b03a366Sstefano_zampini } 6931e6b0712SBarry Smith 69482ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries) 6953b03a366Sstefano_zampini { 6963b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 69756282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 6983b03a366Sstefano_zampini PetscErrorCode ierr; 6993b03a366Sstefano_zampini 7003b03a366Sstefano_zampini PetscFunctionBegin; 70156282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 70256282151SStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 70356282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundariesLocal,&isequal);CHKERRQ(ierr); 70456282151SStefano Zampini } 705785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 706785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 7073b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 708785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = DirichletBoundaries; 70956282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7103b03a366Sstefano_zampini PetscFunctionReturn(0); 7113b03a366Sstefano_zampini } 7123b03a366Sstefano_zampini 7133b03a366Sstefano_zampini /*@ 71482ba6b80SStefano Zampini PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering. 7153b03a366Sstefano_zampini 716785d1243SStefano Zampini Collective 7173b03a366Sstefano_zampini 7183b03a366Sstefano_zampini Input Parameters: 7193b03a366Sstefano_zampini + pc - the preconditioning context 72082ba6b80SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering) 7213b03a366Sstefano_zampini 7223b03a366Sstefano_zampini Level: intermediate 7233b03a366Sstefano_zampini 7243b03a366Sstefano_zampini Notes: 7253b03a366Sstefano_zampini 7260f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundaries(), MatZeroRows(), MatZeroRowsColumns() 7273b03a366Sstefano_zampini @*/ 72882ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries) 7293b03a366Sstefano_zampini { 7303b03a366Sstefano_zampini PetscErrorCode ierr; 7313b03a366Sstefano_zampini 7323b03a366Sstefano_zampini PetscFunctionBegin; 7333b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 7343b03a366Sstefano_zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 73582ba6b80SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 73682ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 7373b03a366Sstefano_zampini PetscFunctionReturn(0); 7383b03a366Sstefano_zampini } 7393b03a366Sstefano_zampini 74053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 7410c7d97c5SJed Brown { 7420c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 74356282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 74453cdbc3dSStefano Zampini PetscErrorCode ierr; 7450c7d97c5SJed Brown 7460c7d97c5SJed Brown PetscFunctionBegin; 74756282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 74856282151SStefano Zampini if (pcbddc->NeumannBoundaries) { 74956282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundaries,&isequal);CHKERRQ(ierr); 75056282151SStefano Zampini } 751785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 752785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 75353cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 75436e030ebSStefano Zampini pcbddc->NeumannBoundaries = NeumannBoundaries; 75556282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7560c7d97c5SJed Brown PetscFunctionReturn(0); 7570c7d97c5SJed Brown } 7581e6b0712SBarry Smith 75957527edcSJed Brown /*@ 76028509bceSStefano Zampini PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem. 76157527edcSJed Brown 762785d1243SStefano Zampini Collective 76357527edcSJed Brown 76457527edcSJed Brown Input Parameters: 76557527edcSJed Brown + pc - the preconditioning context 766785d1243SStefano Zampini - NeumannBoundaries - parallel IS defining the Neumann boundaries 76757527edcSJed Brown 76857527edcSJed Brown Level: intermediate 76957527edcSJed Brown 7700f202f7eSStefano Zampini Notes: 7710f202f7eSStefano Zampini Any process can list any global node 77257527edcSJed Brown 7730f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundariesLocal() 77457527edcSJed Brown @*/ 77553cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 7760c7d97c5SJed Brown { 7770c7d97c5SJed Brown PetscErrorCode ierr; 7780c7d97c5SJed Brown 7790c7d97c5SJed Brown PetscFunctionBegin; 7800c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 781674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 782785d1243SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 78353cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 78453cdbc3dSStefano Zampini PetscFunctionReturn(0); 78553cdbc3dSStefano Zampini } 7861e6b0712SBarry Smith 78782ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries) 7880c7d97c5SJed Brown { 7890c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 79056282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 7910c7d97c5SJed Brown PetscErrorCode ierr; 7920c7d97c5SJed Brown 7930c7d97c5SJed Brown PetscFunctionBegin; 79456282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 79556282151SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 79656282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundariesLocal,&isequal);CHKERRQ(ierr); 79756282151SStefano Zampini } 798785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 799785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 8000c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 801785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = NeumannBoundaries; 80256282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 8030c7d97c5SJed Brown PetscFunctionReturn(0); 8040c7d97c5SJed Brown } 8050c7d97c5SJed Brown 8060c7d97c5SJed Brown /*@ 80782ba6b80SStefano Zampini PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering. 8080c7d97c5SJed Brown 809785d1243SStefano Zampini Collective 8100c7d97c5SJed Brown 8110c7d97c5SJed Brown Input Parameters: 8120c7d97c5SJed Brown + pc - the preconditioning context 81382ba6b80SStefano Zampini - NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering) 8140c7d97c5SJed Brown 8150c7d97c5SJed Brown Level: intermediate 8160c7d97c5SJed Brown 8170c7d97c5SJed Brown Notes: 8180c7d97c5SJed Brown 8190f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundaries() 8200c7d97c5SJed Brown @*/ 82182ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries) 8220c7d97c5SJed Brown { 8230c7d97c5SJed Brown PetscErrorCode ierr; 8240c7d97c5SJed Brown 8250c7d97c5SJed Brown PetscFunctionBegin; 8260c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 8270c7d97c5SJed Brown PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 82882ba6b80SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 82982ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 83053cdbc3dSStefano Zampini PetscFunctionReturn(0); 83153cdbc3dSStefano Zampini } 83253cdbc3dSStefano Zampini 833da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 834da1bb401SStefano Zampini { 835da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 836da1bb401SStefano Zampini 837da1bb401SStefano Zampini PetscFunctionBegin; 838da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 839da1bb401SStefano Zampini PetscFunctionReturn(0); 840da1bb401SStefano Zampini } 8411e6b0712SBarry Smith 842da1bb401SStefano Zampini /*@ 843785d1243SStefano Zampini PCBDDCGetDirichletBoundaries - Get parallel IS for Dirichlet boundaries 844da1bb401SStefano Zampini 845785d1243SStefano Zampini Collective 846785d1243SStefano Zampini 847785d1243SStefano Zampini Input Parameters: 848785d1243SStefano Zampini . pc - the preconditioning context 849785d1243SStefano Zampini 850785d1243SStefano Zampini Output Parameters: 851785d1243SStefano Zampini . DirichletBoundaries - index set defining the Dirichlet boundaries 852785d1243SStefano Zampini 853785d1243SStefano Zampini Level: intermediate 854785d1243SStefano Zampini 8550f202f7eSStefano Zampini Notes: 8560f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetDirichletBoundaries 857785d1243SStefano Zampini 858785d1243SStefano Zampini .seealso: PCBDDC 859785d1243SStefano Zampini @*/ 860785d1243SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 861785d1243SStefano Zampini { 862785d1243SStefano Zampini PetscErrorCode ierr; 863785d1243SStefano Zampini 864785d1243SStefano Zampini PetscFunctionBegin; 865785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 866785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 867785d1243SStefano Zampini PetscFunctionReturn(0); 868785d1243SStefano Zampini } 869785d1243SStefano Zampini 870785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries) 871785d1243SStefano Zampini { 872785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 873785d1243SStefano Zampini 874785d1243SStefano Zampini PetscFunctionBegin; 875785d1243SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundariesLocal; 876785d1243SStefano Zampini PetscFunctionReturn(0); 877785d1243SStefano Zampini } 878785d1243SStefano Zampini 879da1bb401SStefano Zampini /*@ 88082ba6b80SStefano Zampini PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering) 881da1bb401SStefano Zampini 882785d1243SStefano Zampini Collective 883da1bb401SStefano Zampini 884da1bb401SStefano Zampini Input Parameters: 88528509bceSStefano Zampini . pc - the preconditioning context 886da1bb401SStefano Zampini 887da1bb401SStefano Zampini Output Parameters: 88828509bceSStefano Zampini . DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 889da1bb401SStefano Zampini 890da1bb401SStefano Zampini Level: intermediate 891da1bb401SStefano Zampini 892da1bb401SStefano Zampini Notes: 8930f202f7eSStefano 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). 8940f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 895da1bb401SStefano Zampini 896da1bb401SStefano Zampini .seealso: PCBDDC 897da1bb401SStefano Zampini @*/ 89882ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries) 899da1bb401SStefano Zampini { 900da1bb401SStefano Zampini PetscErrorCode ierr; 901da1bb401SStefano Zampini 902da1bb401SStefano Zampini PetscFunctionBegin; 903da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 90482ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 905da1bb401SStefano Zampini PetscFunctionReturn(0); 906da1bb401SStefano Zampini } 9071e6b0712SBarry Smith 90853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 90953cdbc3dSStefano Zampini { 91053cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 91153cdbc3dSStefano Zampini 91253cdbc3dSStefano Zampini PetscFunctionBegin; 91353cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 91453cdbc3dSStefano Zampini PetscFunctionReturn(0); 91553cdbc3dSStefano Zampini } 9161e6b0712SBarry Smith 91753cdbc3dSStefano Zampini /*@ 918785d1243SStefano Zampini PCBDDCGetNeumannBoundaries - Get parallel IS for Neumann boundaries 91953cdbc3dSStefano Zampini 920785d1243SStefano Zampini Collective 921785d1243SStefano Zampini 922785d1243SStefano Zampini Input Parameters: 923785d1243SStefano Zampini . pc - the preconditioning context 924785d1243SStefano Zampini 925785d1243SStefano Zampini Output Parameters: 926785d1243SStefano Zampini . NeumannBoundaries - index set defining the Neumann boundaries 927785d1243SStefano Zampini 928785d1243SStefano Zampini Level: intermediate 929785d1243SStefano Zampini 9300f202f7eSStefano Zampini Notes: 9310f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetNeumannBoundaries 932785d1243SStefano Zampini 933785d1243SStefano Zampini .seealso: PCBDDC 934785d1243SStefano Zampini @*/ 935785d1243SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 936785d1243SStefano Zampini { 937785d1243SStefano Zampini PetscErrorCode ierr; 938785d1243SStefano Zampini 939785d1243SStefano Zampini PetscFunctionBegin; 940785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 941785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 942785d1243SStefano Zampini PetscFunctionReturn(0); 943785d1243SStefano Zampini } 944785d1243SStefano Zampini 945785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries) 946785d1243SStefano Zampini { 947785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 948785d1243SStefano Zampini 949785d1243SStefano Zampini PetscFunctionBegin; 950785d1243SStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundariesLocal; 951785d1243SStefano Zampini PetscFunctionReturn(0); 952785d1243SStefano Zampini } 953785d1243SStefano Zampini 95453cdbc3dSStefano Zampini /*@ 95582ba6b80SStefano Zampini PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering) 95653cdbc3dSStefano Zampini 957785d1243SStefano Zampini Collective 95853cdbc3dSStefano Zampini 95953cdbc3dSStefano Zampini Input Parameters: 96028509bceSStefano Zampini . pc - the preconditioning context 96153cdbc3dSStefano Zampini 96253cdbc3dSStefano Zampini Output Parameters: 96328509bceSStefano Zampini . NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 96453cdbc3dSStefano Zampini 96553cdbc3dSStefano Zampini Level: intermediate 96653cdbc3dSStefano Zampini 96753cdbc3dSStefano Zampini Notes: 9680f202f7eSStefano 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). 9690f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 97053cdbc3dSStefano Zampini 97153cdbc3dSStefano Zampini .seealso: PCBDDC 97253cdbc3dSStefano Zampini @*/ 97382ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries) 97453cdbc3dSStefano Zampini { 97553cdbc3dSStefano Zampini PetscErrorCode ierr; 97653cdbc3dSStefano Zampini 97753cdbc3dSStefano Zampini PetscFunctionBegin; 97853cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 97982ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 9800c7d97c5SJed Brown PetscFunctionReturn(0); 9810c7d97c5SJed Brown } 9821e6b0712SBarry Smith 9831a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 98436e030ebSStefano Zampini { 98536e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 986da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 98756282151SStefano Zampini PetscBool same_data = PETSC_FALSE; 988da1bb401SStefano Zampini PetscErrorCode ierr; 98936e030ebSStefano Zampini 99036e030ebSStefano Zampini PetscFunctionBegin; 9918687889aSStefano Zampini if (!nvtxs) { 99204194a47SStefano Zampini if (copymode == PETSC_OWN_POINTER) { 99304194a47SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 99404194a47SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 99504194a47SStefano Zampini } 9968687889aSStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 9978687889aSStefano Zampini PetscFunctionReturn(0); 9988687889aSStefano Zampini } 99966da6bd7Sstefano_zampini if (mat_graph->nvtxs == nvtxs && mat_graph->freecsr) { /* we own the data */ 100056282151SStefano Zampini if (mat_graph->xadj == xadj && mat_graph->adjncy == adjncy) same_data = PETSC_TRUE; 100156282151SStefano Zampini if (!same_data && mat_graph->xadj[nvtxs] == xadj[nvtxs]) { 10022d505d7fSStefano Zampini ierr = PetscMemcmp(xadj,mat_graph->xadj,(nvtxs+1)*sizeof(PetscInt),&same_data);CHKERRQ(ierr); 10032d505d7fSStefano Zampini if (same_data) { 10042d505d7fSStefano Zampini ierr = PetscMemcmp(adjncy,mat_graph->adjncy,xadj[nvtxs]*sizeof(PetscInt),&same_data);CHKERRQ(ierr); 10052d505d7fSStefano Zampini } 100656282151SStefano Zampini } 100756282151SStefano Zampini } 100856282151SStefano Zampini if (!same_data) { 1009674ae819SStefano Zampini /* free old CSR */ 1010674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 1011674ae819SStefano Zampini /* get CSR into graph structure */ 1012da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 1013854ce69bSBarry Smith ierr = PetscMalloc1(nvtxs+1,&mat_graph->xadj);CHKERRQ(ierr); 1014785e854fSJed Brown ierr = PetscMalloc1(xadj[nvtxs],&mat_graph->adjncy);CHKERRQ(ierr); 1015674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 1016674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 1017a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 1018da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 10191a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 10201a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 1021a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 1022a1dbd327SStefano Zampini } else if (copymode == PETSC_USE_POINTER) { 1023a1dbd327SStefano Zampini mat_graph->xadj = (PetscInt*)xadj; 1024a1dbd327SStefano Zampini mat_graph->adjncy = (PetscInt*)adjncy; 1025a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_FALSE; 1026e0fe2d75SToby Isaac } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %D",copymode); 1027575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 102856282151SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 102956282151SStefano Zampini } 103036e030ebSStefano Zampini PetscFunctionReturn(0); 103136e030ebSStefano Zampini } 10321e6b0712SBarry Smith 103336e030ebSStefano Zampini /*@ 103454fffbccSStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local degrees of freedom. 103536e030ebSStefano Zampini 103636e030ebSStefano Zampini Not collective 103736e030ebSStefano Zampini 103836e030ebSStefano Zampini Input Parameters: 103954fffbccSStefano Zampini + pc - the preconditioning context. 104054fffbccSStefano Zampini . nvtxs - number of local vertices of the graph (i.e., the number of local dofs). 104154fffbccSStefano Zampini . xadj, adjncy - the connectivity of the dofs in CSR format. 104254fffbccSStefano Zampini - copymode - supported modes are PETSC_COPY_VALUES, PETSC_USE_POINTER or PETSC_OWN_POINTER. 104336e030ebSStefano Zampini 104436e030ebSStefano Zampini Level: intermediate 104536e030ebSStefano Zampini 104695452b02SPatrick Sanan Notes: 104795452b02SPatrick Sanan A dof is considered connected with all local dofs if xadj[dof+1]-xadj[dof] == 1 and adjncy[xadj[dof]] is negative. 104836e030ebSStefano Zampini 104928509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode 105036e030ebSStefano Zampini @*/ 10511a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 105236e030ebSStefano Zampini { 1053575ad6abSStefano Zampini void (*f)(void) = 0; 105436e030ebSStefano Zampini PetscErrorCode ierr; 105536e030ebSStefano Zampini 105636e030ebSStefano Zampini PetscFunctionBegin; 105736e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 10588687889aSStefano Zampini if (nvtxs) { 1059674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 10601633d1f0SStefano Zampini if (xadj[nvtxs]) PetscValidIntPointer(adjncy,4); 10618687889aSStefano Zampini } 10621a83f524SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 1063575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 1064575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 1065575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 1066575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 1067575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 1068da1bb401SStefano Zampini } 106936e030ebSStefano Zampini PetscFunctionReturn(0); 107036e030ebSStefano Zampini } 10711e6b0712SBarry Smith 107263602bcaSStefano Zampini static PetscErrorCode PCBDDCSetDofsSplittingLocal_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 107363602bcaSStefano Zampini { 107463602bcaSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 107563602bcaSStefano Zampini PetscInt i; 107656282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 107763602bcaSStefano Zampini PetscErrorCode ierr; 107863602bcaSStefano Zampini 107963602bcaSStefano Zampini PetscFunctionBegin; 108056282151SStefano Zampini if (pcbddc->n_ISForDofsLocal == n_is) { 108156282151SStefano Zampini for (i=0;i<n_is;i++) { 108256282151SStefano Zampini PetscBool isequalt; 108356282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofsLocal[i],&isequalt);CHKERRQ(ierr); 108456282151SStefano Zampini if (!isequalt) break; 108556282151SStefano Zampini } 108656282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 108756282151SStefano Zampini } 108856282151SStefano Zampini for (i=0;i<n_is;i++) { 108956282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 109056282151SStefano Zampini } 109163602bcaSStefano Zampini /* Destroy ISes if they were already set */ 109263602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 109363602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 109463602bcaSStefano Zampini } 109563602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 109663602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 109763602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 109863602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 109963602bcaSStefano Zampini } 110063602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 110163602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 110263602bcaSStefano Zampini /* allocate space then set */ 1103d02579f5SStefano Zampini if (n_is) { 1104d02579f5SStefano Zampini ierr = PetscMalloc1(n_is,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1105d02579f5SStefano Zampini } 110663602bcaSStefano Zampini for (i=0;i<n_is;i++) { 110763602bcaSStefano Zampini pcbddc->ISForDofsLocal[i] = ISForDofs[i]; 110863602bcaSStefano Zampini } 110963602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = n_is; 111063602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 111156282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 111263602bcaSStefano Zampini PetscFunctionReturn(0); 111363602bcaSStefano Zampini } 111463602bcaSStefano Zampini 111563602bcaSStefano Zampini /*@ 111663602bcaSStefano Zampini PCBDDCSetDofsSplittingLocal - Set index sets defining fields of the local subdomain matrix 111763602bcaSStefano Zampini 111863602bcaSStefano Zampini Collective 111963602bcaSStefano Zampini 112063602bcaSStefano Zampini Input Parameters: 112163602bcaSStefano Zampini + pc - the preconditioning context 11220f202f7eSStefano Zampini . n_is - number of index sets defining the fields 11230f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in local ordering 112463602bcaSStefano Zampini 112563602bcaSStefano Zampini Level: intermediate 112663602bcaSStefano Zampini 11270f202f7eSStefano Zampini Notes: 11280f202f7eSStefano Zampini n_is should be the same among processes. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 112963602bcaSStefano Zampini 113063602bcaSStefano Zampini .seealso: PCBDDC 113163602bcaSStefano Zampini @*/ 113263602bcaSStefano Zampini PetscErrorCode PCBDDCSetDofsSplittingLocal(PC pc,PetscInt n_is, IS ISForDofs[]) 113363602bcaSStefano Zampini { 113463602bcaSStefano Zampini PetscInt i; 113563602bcaSStefano Zampini PetscErrorCode ierr; 113663602bcaSStefano Zampini 113763602bcaSStefano Zampini PetscFunctionBegin; 113863602bcaSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 113963602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 114063602bcaSStefano Zampini for (i=0;i<n_is;i++) { 114163602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 114263602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 114363602bcaSStefano Zampini } 1144e71e7a71SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplittingLocal_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 114563602bcaSStefano Zampini PetscFunctionReturn(0); 114663602bcaSStefano Zampini } 114763602bcaSStefano Zampini 11489c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 11499c0446d6SStefano Zampini { 11509c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 11519c0446d6SStefano Zampini PetscInt i; 115256282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 11539c0446d6SStefano Zampini PetscErrorCode ierr; 11549c0446d6SStefano Zampini 11559c0446d6SStefano Zampini PetscFunctionBegin; 115656282151SStefano Zampini if (pcbddc->n_ISForDofs == n_is) { 115756282151SStefano Zampini for (i=0;i<n_is;i++) { 115856282151SStefano Zampini PetscBool isequalt; 115956282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofs[i],&isequalt);CHKERRQ(ierr); 116056282151SStefano Zampini if (!isequalt) break; 116156282151SStefano Zampini } 116256282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 116356282151SStefano Zampini } 116456282151SStefano Zampini for (i=0;i<n_is;i++) { 116556282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 116656282151SStefano Zampini } 1167da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 11689c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 11699c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 11709c0446d6SStefano Zampini } 1171d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 117263602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 117363602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 117463602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 117563602bcaSStefano Zampini } 117663602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 117763602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 1178da1bb401SStefano Zampini /* allocate space then set */ 1179d02579f5SStefano Zampini if (n_is) { 1180785e854fSJed Brown ierr = PetscMalloc1(n_is,&pcbddc->ISForDofs);CHKERRQ(ierr); 1181d02579f5SStefano Zampini } 11829c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 1183da1bb401SStefano Zampini pcbddc->ISForDofs[i] = ISForDofs[i]; 11849c0446d6SStefano Zampini } 11859c0446d6SStefano Zampini pcbddc->n_ISForDofs = n_is; 118663602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 118756282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 11889c0446d6SStefano Zampini PetscFunctionReturn(0); 11899c0446d6SStefano Zampini } 11901e6b0712SBarry Smith 11919c0446d6SStefano Zampini /*@ 119263602bcaSStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of the global matrix 11939c0446d6SStefano Zampini 119463602bcaSStefano Zampini Collective 11959c0446d6SStefano Zampini 11969c0446d6SStefano Zampini Input Parameters: 11979c0446d6SStefano Zampini + pc - the preconditioning context 11980f202f7eSStefano Zampini . n_is - number of index sets defining the fields 11990f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in global ordering 12009c0446d6SStefano Zampini 12019c0446d6SStefano Zampini Level: intermediate 12029c0446d6SStefano Zampini 12030f202f7eSStefano Zampini Notes: 12040f202f7eSStefano Zampini Any process can list any global node. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 12059c0446d6SStefano Zampini 12069c0446d6SStefano Zampini .seealso: PCBDDC 12079c0446d6SStefano Zampini @*/ 12089c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 12099c0446d6SStefano Zampini { 12102b510759SStefano Zampini PetscInt i; 12119c0446d6SStefano Zampini PetscErrorCode ierr; 12129c0446d6SStefano Zampini 12139c0446d6SStefano Zampini PetscFunctionBegin; 12149c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 121563602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 12162b510759SStefano Zampini for (i=0;i<n_is;i++) { 121763602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 1218a011d5a7Sstefano_zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 12192b510759SStefano Zampini } 12209c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 12219c0446d6SStefano Zampini PetscFunctionReturn(0); 12229c0446d6SStefano Zampini } 1223906d46d4SStefano Zampini 1224534831adSStefano Zampini /* 1225534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 1226534831adSStefano Zampini guess if a transformation of basis approach has been selected. 12279c0446d6SStefano Zampini 1228534831adSStefano Zampini Input Parameter: 1229534831adSStefano Zampini + pc - the preconditioner contex 1230534831adSStefano Zampini 1231534831adSStefano Zampini Application Interface Routine: PCPreSolve() 1232534831adSStefano Zampini 1233534831adSStefano Zampini Notes: 1234534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 1235534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1236534831adSStefano Zampini */ 1237534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1238534831adSStefano Zampini { 1239534831adSStefano Zampini PetscErrorCode ierr; 1240534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1241534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 12423972b0daSStefano Zampini Vec used_vec; 124327b6a85dSStefano Zampini PetscBool save_rhs = PETSC_TRUE, benign_correction_computed; 1244534831adSStefano Zampini 1245534831adSStefano Zampini PetscFunctionBegin; 12461f4df5f7SStefano Zampini /* if we are working with CG, one dirichlet solve can be avoided during Krylov iterations */ 124785c4d303SStefano Zampini if (ksp) { 12481f4df5f7SStefano Zampini PetscBool iscg, isgroppcg, ispipecg, ispipecgrr; 124985c4d303SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr); 125027b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPGROPPCG,&isgroppcg);CHKERRQ(ierr); 125127b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECG,&ispipecg);CHKERRQ(ierr); 1252f94e96cbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECGRR,&ispipecgrr);CHKERRQ(ierr); 12531f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static || (!iscg && !isgroppcg && !ispipecg && !ispipecgrr)) { 125485c4d303SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 125585c4d303SStefano Zampini } 125685c4d303SStefano Zampini } 1257fc17d649SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static) { 1258fc17d649SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 1259fc17d649SStefano Zampini } 12601f4df5f7SStefano Zampini 126185c4d303SStefano Zampini /* Creates parallel work vectors used in presolve */ 126262a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 126362a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 126462a6ff1dSStefano Zampini } 126562a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 126662a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 126762a6ff1dSStefano Zampini } 12688d00608fSStefano Zampini 126927b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_FALSE; 12703972b0daSStefano Zampini if (x) { 12713972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 12723972b0daSStefano Zampini used_vec = x; 12738d00608fSStefano Zampini } else { /* it can only happen when calling PCBDDCMatFETIDPGetRHS */ 12743972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 12753972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 12763972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 127727b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 1278266e20e9SStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 1279266e20e9SStefano Zampini save_rhs = PETSC_FALSE; 1280266e20e9SStefano Zampini pcbddc->eliminate_dirdofs = PETSC_TRUE; 12813972b0daSStefano Zampini } 12828efcfb23SStefano Zampini 12838efcfb23SStefano Zampini /* hack into ksp data structure since PCPreSolve comes earlier than setting to zero the guess in src/ksp/ksp/interface/itfunc.c */ 12843972b0daSStefano Zampini if (ksp) { 1285a0cb1b98SStefano Zampini /* store the flag for the initial guess since it will be restored back during PCPostSolve_BDDC */ 12868efcfb23SStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 12878efcfb23SStefano Zampini if (!pcbddc->ksp_guess_nonzero) { 12883972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 12893972b0daSStefano Zampini } 12903972b0daSStefano Zampini } 12913308cffdSStefano Zampini 12928d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 12933972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 129470c64980SStefano Zampini if (rhs && pcbddc->eliminate_dirdofs) { 12953975b054SStefano Zampini IS dirIS = NULL; 12963975b054SStefano Zampini 1297a07ea27aSStefano Zampini /* DirichletBoundariesLocal may not be consistent among neighbours; gets a dirichlet dofs IS from graph (may be cached) */ 12983975b054SStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 12993975b054SStefano Zampini if (dirIS) { 1300906d46d4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1301785d1243SStefano Zampini PetscInt dirsize,i,*is_indices; 13022b095fd8SStefano Zampini PetscScalar *array_x; 13032b095fd8SStefano Zampini const PetscScalar *array_diagonal; 1304785d1243SStefano Zampini 13053972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 13063972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 1307e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1308e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1309e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1310e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 131182ba6b80SStefano Zampini ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr); 13123972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 13132b095fd8SStefano Zampini ierr = VecGetArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 13143972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 13152fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 13163972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 13172b095fd8SStefano Zampini ierr = VecRestoreArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 13183972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 1319e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1320e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13218d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 13221b968477SStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 13238efcfb23SStefano Zampini } 1324a07ea27aSStefano Zampini } 1325b76ba322SStefano Zampini 13268efcfb23SStefano Zampini /* remove the computed solution or the initial guess from the rhs */ 13278d00608fSStefano Zampini if (pcbddc->rhs_change || (ksp && pcbddc->ksp_guess_nonzero) ) { 132827b6a85dSStefano Zampini /* save the original rhs */ 132927b6a85dSStefano Zampini if (save_rhs) { 133027b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 133127b6a85dSStefano Zampini save_rhs = PETSC_FALSE; 13328d00608fSStefano Zampini } 13338d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 13343972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 133527b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,used_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 13363972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 13378efcfb23SStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 133827b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 13397acc28cbSStefano Zampini if (ksp) { 13407acc28cbSStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_FALSE);CHKERRQ(ierr); 13417acc28cbSStefano Zampini } 13423308cffdSStefano Zampini } 13438efcfb23SStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 1344b76ba322SStefano Zampini 1345fc17d649SStefano Zampini /* compute initial vector in benign space if needed 134627b6a85dSStefano Zampini and remove non-benign solution from the rhs */ 134727b6a85dSStefano Zampini benign_correction_computed = PETSC_FALSE; 1348c69e9cc1SStefano Zampini if (rhs && pcbddc->benign_compute_correction && (pcbddc->benign_have_null || pcbddc->benign_apply_coarse_only)) { 13491f4df5f7SStefano Zampini /* compute u^*_h using ideas similar to those in Xuemin Tu's PhD thesis (see Section 4.8.1) 13501f4df5f7SStefano Zampini Recursively apply BDDC in the multilevel case */ 13510369aaf7SStefano Zampini if (!pcbddc->benign_vec) { 13520369aaf7SStefano Zampini ierr = VecDuplicate(rhs,&pcbddc->benign_vec);CHKERRQ(ierr); 13530369aaf7SStefano Zampini } 1354c69e9cc1SStefano Zampini /* keep applying coarse solver unless we no longer have benign subdomains */ 1355c69e9cc1SStefano Zampini pcbddc->benign_apply_coarse_only = pcbddc->benign_have_null ? PETSC_TRUE : PETSC_FALSE; 135627b6a85dSStefano Zampini if (!pcbddc->benign_skip_correction) { 13571dd7afcfSStefano Zampini ierr = PCApply_BDDC(pc,rhs,pcbddc->benign_vec);CHKERRQ(ierr); 13583bca92a6SStefano Zampini benign_correction_computed = PETSC_TRUE; 13591f4df5f7SStefano Zampini if (pcbddc->temp_solution_used) { 13601f4df5f7SStefano Zampini ierr = VecAXPY(pcbddc->temp_solution,1.0,pcbddc->benign_vec);CHKERRQ(ierr); 13611f4df5f7SStefano Zampini } 13621f4df5f7SStefano Zampini ierr = VecScale(pcbddc->benign_vec,-1.0);CHKERRQ(ierr); 136327b6a85dSStefano Zampini /* store the original rhs if not done earlier */ 136427b6a85dSStefano Zampini if (save_rhs) { 136527b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 136692e3dcfbSStefano Zampini } 136727b6a85dSStefano Zampini if (pcbddc->rhs_change) { 13680369aaf7SStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,rhs,rhs);CHKERRQ(ierr); 136927b6a85dSStefano Zampini } else { 137027b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 137127b6a85dSStefano Zampini } 13720369aaf7SStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 137327b6a85dSStefano Zampini } 137427b6a85dSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_FALSE; 13750369aaf7SStefano Zampini } 13762d4c4fecSStefano Zampini 13772d4c4fecSStefano Zampini /* dbg output */ 1378a198735bSStefano Zampini if (pcbddc->dbg_flag && benign_correction_computed) { 13791f4df5f7SStefano Zampini Vec v; 1380c69e9cc1SStefano Zampini 13811f4df5f7SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&v);CHKERRQ(ierr); 1382c69e9cc1SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 13831f4df5f7SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,v);CHKERRQ(ierr); 1384c69e9cc1SStefano Zampini } else { 1385c69e9cc1SStefano Zampini ierr = VecCopy(rhs,v);CHKERRQ(ierr); 1386c69e9cc1SStefano Zampini } 13871f4df5f7SStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,v,PETSC_TRUE);CHKERRQ(ierr); 1388e0fe2d75SToby Isaac ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"LEVEL %D: is the correction benign?\n",pcbddc->current_level);CHKERRQ(ierr); 1389c69e9cc1SStefano Zampini ierr = PetscScalarView(pcbddc->benign_n,pcbddc->benign_p0,pcbddc->dbg_viewer);CHKERRQ(ierr); 1390c69e9cc1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 13911f4df5f7SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 13921f4df5f7SStefano Zampini } 13930369aaf7SStefano Zampini 13940369aaf7SStefano Zampini /* set initial guess if using PCG */ 13958ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 13960369aaf7SStefano Zampini if (x && pcbddc->use_exact_dirichlet_trick) { 13970369aaf7SStefano Zampini ierr = VecSet(x,0.0);CHKERRQ(ierr); 13981dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 139927b6a85dSStefano Zampini if (benign_correction_computed) { /* we have already saved the changed rhs */ 14001dd7afcfSStefano Zampini ierr = VecLockPop(pcis->vec1_global);CHKERRQ(ierr); 14011dd7afcfSStefano Zampini } else { 14021dd7afcfSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,pcis->vec1_global);CHKERRQ(ierr); 14031dd7afcfSStefano Zampini } 14041dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14051dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14061dd7afcfSStefano Zampini } else { 14070369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14080369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14091dd7afcfSStefano Zampini } 14100369aaf7SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 14111dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 14121dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.);CHKERRQ(ierr); 14131dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 14141dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 14151dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x);CHKERRQ(ierr); 14161dd7afcfSStefano Zampini } else { 14170369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 14180369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 14191dd7afcfSStefano Zampini } 14200369aaf7SStefano Zampini if (ksp) { 14210369aaf7SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 14220369aaf7SStefano Zampini } 14238ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_TRUE; 1424266e20e9SStefano Zampini } else if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior && benign_correction_computed && pcbddc->use_exact_dirichlet_trick) { 1425266e20e9SStefano Zampini ierr = VecLockPop(pcis->vec1_global);CHKERRQ(ierr); 14260369aaf7SStefano Zampini } 1427534831adSStefano Zampini PetscFunctionReturn(0); 1428534831adSStefano Zampini } 1429906d46d4SStefano Zampini 1430534831adSStefano Zampini /* 1431534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 1432534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 1433534831adSStefano Zampini 1434534831adSStefano Zampini Input Parameter: 1435534831adSStefano Zampini + pc - the preconditioner contex 1436534831adSStefano Zampini 1437534831adSStefano Zampini Application Interface Routine: PCPostSolve() 1438534831adSStefano Zampini 1439534831adSStefano Zampini Notes: 1440534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 1441534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1442534831adSStefano Zampini */ 1443534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1444534831adSStefano Zampini { 1445534831adSStefano Zampini PetscErrorCode ierr; 1446534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1447534831adSStefano Zampini 1448534831adSStefano Zampini PetscFunctionBegin; 14493972b0daSStefano Zampini /* add solution removed in presolve */ 14506bcfc461SStefano Zampini if (x && pcbddc->rhs_change) { 145127b6a85dSStefano Zampini if (pcbddc->temp_solution_used) { 14523425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 1453af140850Sstefano_zampini } else if (pcbddc->benign_compute_correction && pcbddc->benign_vec) { 145427b6a85dSStefano Zampini ierr = VecAXPY(x,-1.0,pcbddc->benign_vec);CHKERRQ(ierr); 14553425bc38SStefano Zampini } 1456af140850Sstefano_zampini /* restore to original state (not for FETI-DP) */ 1457af140850Sstefano_zampini if (ksp) pcbddc->temp_solution_used = PETSC_FALSE; 145827b6a85dSStefano Zampini } 145927b6a85dSStefano Zampini 1460266e20e9SStefano Zampini /* restore rhs to its original state (not needed for FETI-DP) */ 14618d00608fSStefano Zampini if (rhs && pcbddc->rhs_change) { 146227b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 14638d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 1464af140850Sstefano_zampini } 14658efcfb23SStefano Zampini /* restore ksp guess state */ 14668efcfb23SStefano Zampini if (ksp) { 14678efcfb23SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 14688ae0ca82SStefano Zampini /* reset flag for exact dirichlet trick */ 14698ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 1470af140850Sstefano_zampini } 1471534831adSStefano Zampini PetscFunctionReturn(0); 1472534831adSStefano Zampini } 1473af140850Sstefano_zampini 14740c7d97c5SJed Brown /* 14750c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 14760c7d97c5SJed Brown by setting data structures and options. 14770c7d97c5SJed Brown 14780c7d97c5SJed Brown Input Parameter: 147953cdbc3dSStefano Zampini + pc - the preconditioner context 14800c7d97c5SJed Brown 14810c7d97c5SJed Brown Application Interface Routine: PCSetUp() 14820c7d97c5SJed Brown 14830c7d97c5SJed Brown Notes: 14840c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 14850c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 14860c7d97c5SJed Brown */ 148753cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 14880c7d97c5SJed Brown { 14890c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1490c703fcc7SStefano Zampini PCBDDCSubSchurs sub_schurs; 14915e8657edSStefano Zampini Mat_IS* matis; 149208122e43SStefano Zampini MatNullSpace nearnullspace; 149335509ce9Sstefano_zampini Mat lA; 149435509ce9Sstefano_zampini IS lP,zerodiag = NULL; 149591e8d312SStefano Zampini PetscInt nrows,ncols; 149686bfa4cfSStefano Zampini PetscMPIInt size; 1497c703fcc7SStefano Zampini PetscBool computesubschurs; 14988de1fae6SStefano Zampini PetscBool computeconstraintsmatrix; 14995e8657edSStefano Zampini PetscBool new_nearnullspace_provided,ismatis; 1500c703fcc7SStefano Zampini PetscErrorCode ierr; 15010c7d97c5SJed Brown 15020c7d97c5SJed Brown PetscFunctionBegin; 15035e8657edSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATIS,&ismatis);CHKERRQ(ierr); 15046c4ed002SBarry Smith if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner requires matrix of type MATIS"); 150591e8d312SStefano Zampini ierr = MatGetSize(pc->pmat,&nrows,&ncols);CHKERRQ(ierr); 15066c4ed002SBarry Smith if (nrows != ncols) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PCBDDC preconditioner requires a square preconditioning matrix"); 150786bfa4cfSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 150886bfa4cfSStefano Zampini 15095e8657edSStefano Zampini matis = (Mat_IS*)pc->pmat->data; 1510f4ddd8eeSStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other future nonoverlapping preconditioners */ 15113b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 151271582508SStefano Zampini Also, BDDC builds its own KSP for the Dirichlet problem */ 1513a485753aSstefano_zampini if (!pc->setupcalled || pc->flag == DIFFERENT_NONZERO_PATTERN) pcbddc->recompute_topography = PETSC_TRUE; 1514c83e1ba7SStefano Zampini if (pcbddc->recompute_topography) { 1515c83e1ba7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 1516c83e1ba7SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1517c83e1ba7SStefano Zampini } else { 15188de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_FALSE; 1519c83e1ba7SStefano Zampini } 1520b087196eSStefano Zampini 1521b087196eSStefano Zampini /* check parameters' compatibility */ 1522b7ab4a40SStefano Zampini if (!pcbddc->use_deluxe_scaling) pcbddc->deluxe_zerorows = PETSC_FALSE; 1523bd2a564bSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_threshold[0] != 0.0 || pcbddc->adaptive_threshold[1] != 0.0); 152486bfa4cfSStefano Zampini pcbddc->use_deluxe_scaling = (PetscBool)(pcbddc->use_deluxe_scaling && size > 1); 152586bfa4cfSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_selection && size > 1); 1526bf3a8328SStefano Zampini pcbddc->adaptive_userdefined = (PetscBool)(pcbddc->adaptive_selection && pcbddc->adaptive_userdefined); 1527862806e4SStefano Zampini if (pcbddc->adaptive_selection) pcbddc->use_faces = PETSC_TRUE; 1528862806e4SStefano Zampini 15295a95e1ceSStefano Zampini computesubschurs = (PetscBool)(pcbddc->adaptive_selection || pcbddc->use_deluxe_scaling); 153016909a7fSStefano Zampini if (pcbddc->switch_static) { 153116909a7fSStefano Zampini PetscBool ismatis; 1532d9869140SStefano Zampini 153316909a7fSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->mat,MATIS,&ismatis);CHKERRQ(ierr); 153416909a7fSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"When the static switch is one, the iteration matrix should be of type MATIS"); 153516909a7fSStefano Zampini } 153616909a7fSStefano Zampini 153771582508SStefano Zampini /* activate all connected components if the netflux has been requested */ 1538bb05f991SStefano Zampini if (pcbddc->compute_nonetflux) { 1539bb05f991SStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 1540bb05f991SStefano Zampini pcbddc->use_edges = PETSC_TRUE; 1541bb05f991SStefano Zampini pcbddc->use_faces = PETSC_TRUE; 1542bb05f991SStefano Zampini } 1543bb05f991SStefano Zampini 1544f4ddd8eeSStefano Zampini /* Get stdout for dbg */ 154570cf5478SStefano Zampini if (pcbddc->dbg_flag) { 154670cf5478SStefano Zampini if (!pcbddc->dbg_viewer) { 154758a03d70SStefano Zampini pcbddc->dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pc)); 1548f4ddd8eeSStefano Zampini } 1549d9869140SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 155058a03d70SStefano Zampini ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1551f4ddd8eeSStefano Zampini } 1552f4ddd8eeSStefano Zampini 1553c703fcc7SStefano Zampini /* process topology information */ 155443371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Topology[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 155571582508SStefano Zampini if (pcbddc->recompute_topography) { 155671582508SStefano Zampini ierr = PCBDDCComputeLocalTopologyInfo(pc);CHKERRQ(ierr); 1557c703fcc7SStefano Zampini if (pcbddc->discretegradient) { 1558a13144ffSStefano Zampini ierr = PCBDDCNedelecSupport(pc);CHKERRQ(ierr); 1559a13144ffSStefano Zampini } 1560c703fcc7SStefano Zampini } 1561a13144ffSStefano Zampini 1562c703fcc7SStefano Zampini /* change basis if requested by the user */ 15635e8657edSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 15645e8657edSStefano Zampini /* use_change_of_basis flag is used to automatically compute a change of basis from constraints */ 15655e8657edSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 15665e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 15675e8657edSStefano Zampini } else { 1568b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 15695e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 15705e8657edSStefano Zampini pcbddc->local_mat = matis->A; 1571d16cbb6bSStefano Zampini } 1572d16cbb6bSStefano Zampini 15734f1b2e48SStefano Zampini /* 1574c703fcc7SStefano Zampini Compute change of basis on local pressures (aka zerodiag dofs) with the benign trick 15754f1b2e48SStefano Zampini This should come earlier then PCISSetUp for extracting the correct subdomain matrices 15764f1b2e48SStefano Zampini */ 15771dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 1578d16cbb6bSStefano Zampini if (pcbddc->benign_saddle_point) { 15799f47a83aSStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 15809f47a83aSStefano Zampini 158105b28244SStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->use_change_of_basis || !computesubschurs) pcbddc->benign_change_explicit = PETSC_TRUE; 1582669cc0f4SStefano Zampini /* detect local saddle point and change the basis in pcbddc->local_mat (TODO: reuse case) */ 1583339f8db1SStefano Zampini ierr = PCBDDCBenignDetectSaddlePoint(pc,&zerodiag);CHKERRQ(ierr); 1584a3df083aSStefano Zampini /* pop B0 mat from local mat */ 1585c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 15861dd7afcfSStefano Zampini /* give pcis a hint to not reuse submatrices during PCISCreate */ 15871dd7afcfSStefano Zampini if (pc->flag == SAME_NONZERO_PATTERN && pcis->reusesubmatrices == PETSC_TRUE) { 15881dd7afcfSStefano Zampini if (pcbddc->benign_n && (pcbddc->benign_change_explicit || pcbddc->dbg_flag)) { 15891dd7afcfSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 15901dd7afcfSStefano Zampini } else { 1591a3df083aSStefano Zampini pcis->reusesubmatrices = PETSC_TRUE; 15921dd7afcfSStefano Zampini } 1593a3df083aSStefano Zampini } else { 15949f47a83aSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 1595674ae819SStefano Zampini } 1596a3df083aSStefano Zampini } 159727b6a85dSStefano Zampini 15988037d520SStefano Zampini /* propagate relevant information */ 159906a4e24aSStefano Zampini if (matis->A->symmetric_set) { 160006a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 160106a4e24aSStefano Zampini } 160206a4e24aSStefano Zampini if (matis->A->spd_set) { 160306a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SPD,matis->A->spd);CHKERRQ(ierr); 160406a4e24aSStefano Zampini } 1605e496cd5dSStefano Zampini 16065e8657edSStefano Zampini /* Set up all the "iterative substructuring" common block without computing solvers */ 16075e8657edSStefano Zampini { 16085e8657edSStefano Zampini Mat temp_mat; 16095e8657edSStefano Zampini 16105e8657edSStefano Zampini temp_mat = matis->A; 16115e8657edSStefano Zampini matis->A = pcbddc->local_mat; 1612d9869140SStefano Zampini ierr = PCISSetUp(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 16135e8657edSStefano Zampini pcbddc->local_mat = matis->A; 16145e8657edSStefano Zampini matis->A = temp_mat; 16155e8657edSStefano Zampini } 1616684f6988SStefano Zampini 161781d14e9dSStefano Zampini /* Analyze interface */ 161864ac59b8SStefano Zampini if (!pcbddc->graphanalyzed) { 1619674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 16208de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1621345ecf6cSStefano Zampini if (pcbddc->adaptive_selection && !pcbddc->use_deluxe_scaling && !pcbddc->mat_graph->twodim) { 16224247aa23Sstefano_zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot compute the adaptive primal space for a problem with 3D edges without deluxe scaling"); 1623345ecf6cSStefano Zampini } 1624a198735bSStefano Zampini if (pcbddc->compute_nonetflux) { 1625669cc0f4SStefano Zampini MatNullSpace nnfnnsp; 1626669cc0f4SStefano Zampini 162721ef3d20SStefano Zampini if (!pcbddc->divudotp) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Missing divudotp operator"); 16288ae0ca82SStefano Zampini ierr = PCBDDCComputeNoNetFlux(pc->pmat,pcbddc->divudotp,pcbddc->divudotp_trans,pcbddc->divudotp_vl2l,pcbddc->mat_graph,&nnfnnsp);CHKERRQ(ierr); 162971582508SStefano Zampini /* TODO what if a nearnullspace is already attached? */ 16308037d520SStefano Zampini if (nnfnnsp) { 1631669cc0f4SStefano Zampini ierr = MatSetNearNullSpace(pc->pmat,nnfnnsp);CHKERRQ(ierr); 1632669cc0f4SStefano Zampini ierr = MatNullSpaceDestroy(&nnfnnsp);CHKERRQ(ierr); 1633669cc0f4SStefano Zampini } 1634674ae819SStefano Zampini } 16358037d520SStefano Zampini } 163643371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Topology[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 1637fb8d54d4SStefano Zampini 16385408967cSStefano Zampini /* check existence of a divergence free extension, i.e. 16395408967cSStefano Zampini b(v_I,p_0) = 0 for all v_I (raise error if not). 16405408967cSStefano Zampini Also, check that PCBDDCBenignGetOrSetP0 works */ 1641ff1f7e73Sstefano_zampini if (pcbddc->benign_saddle_point && pcbddc->dbg_flag > 1) { 16425408967cSStefano Zampini ierr = PCBDDCBenignCheck(pc,zerodiag);CHKERRQ(ierr); 164309f581a4SStefano Zampini } 16444f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 164506f24817SStefano Zampini 1646b96c3477SStefano Zampini /* Setup local dirichlet solver ksp_D and sub_schurs solvers */ 1647c703fcc7SStefano Zampini if (computesubschurs && pcbddc->recompute_topography) { 164808122e43SStefano Zampini ierr = PCBDDCInitSubSchurs(pc);CHKERRQ(ierr); 1649b1b3d7a2SStefano Zampini } 16509d54b7f4SStefano Zampini /* SetUp Scaling operator (scaling matrices could be needed in SubSchursSetUp)*/ 16519d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) { 16529d54b7f4SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 16539d54b7f4SStefano Zampini } 1654c703fcc7SStefano Zampini 1655c703fcc7SStefano Zampini /* finish setup solvers and do adaptive selection of constraints */ 1656b334f244SStefano Zampini sub_schurs = pcbddc->sub_schurs; 1657b334f244SStefano Zampini if (sub_schurs && sub_schurs->schur_explicit) { 16582070dbb6SStefano Zampini if (computesubschurs) { 165908122e43SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 16602070dbb6SStefano Zampini } 1661d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 1662d5574798SStefano Zampini } else { 1663d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 16642070dbb6SStefano Zampini if (computesubschurs) { 1665d5574798SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 1666d5574798SStefano Zampini } 16672070dbb6SStefano Zampini } 166808122e43SStefano Zampini if (pcbddc->adaptive_selection) { 166908122e43SStefano Zampini ierr = PCBDDCAdaptiveSelection(pc);CHKERRQ(ierr); 16708de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1671b7eb3628SStefano Zampini } 1672684f6988SStefano Zampini 1673f4ddd8eeSStefano Zampini /* infer if NullSpace object attached to Mat via MatSetNearNullSpace has changed */ 1674fb8d54d4SStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1675f4ddd8eeSStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullspace);CHKERRQ(ierr); 1676f4ddd8eeSStefano Zampini if (pcbddc->onearnullspace) { /* already used nearnullspace */ 1677f4ddd8eeSStefano Zampini if (!nearnullspace) { /* near null space attached to mat has been destroyed */ 1678f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1679f4ddd8eeSStefano Zampini } else { 1680f4ddd8eeSStefano Zampini /* determine if the two nullspaces are different (should be lightweight) */ 1681f4ddd8eeSStefano Zampini if (nearnullspace != pcbddc->onearnullspace) { 1682f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1683165b64e2SStefano Zampini } else { /* maybe the user has changed the content of the nearnullspace so check vectors ObjectStateId */ 1684f4ddd8eeSStefano Zampini PetscInt i; 1685165b64e2SStefano Zampini const Vec *nearnullvecs; 1686165b64e2SStefano Zampini PetscObjectState state; 1687165b64e2SStefano Zampini PetscInt nnsp_size; 1688165b64e2SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullspace,NULL,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1689f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1690f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&state);CHKERRQ(ierr); 1691165b64e2SStefano Zampini if (pcbddc->onearnullvecs_state[i] != state) { 1692f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1693f4ddd8eeSStefano Zampini break; 1694f4ddd8eeSStefano Zampini } 1695f4ddd8eeSStefano Zampini } 1696f4ddd8eeSStefano Zampini } 1697f4ddd8eeSStefano Zampini } 1698f4ddd8eeSStefano Zampini } else { 1699f4ddd8eeSStefano Zampini if (!nearnullspace) { /* both nearnullspaces are null */ 1700f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1701f4ddd8eeSStefano Zampini } else { /* nearnullspace attached later */ 1702f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1703f4ddd8eeSStefano Zampini } 1704f4ddd8eeSStefano Zampini } 1705f4ddd8eeSStefano Zampini 1706f4ddd8eeSStefano Zampini /* Setup constraints and related work vectors */ 1707727cdba6SStefano Zampini /* reset primal space flags */ 170843371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_LocalWork[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 1709f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 1710727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 17118de1fae6SStefano Zampini if (computeconstraintsmatrix || new_nearnullspace_provided) { 1712727cdba6SStefano Zampini /* It also sets the primal space flags */ 1713674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 17149543d0ffSStefano Zampini } 1715e7b262bdSStefano Zampini /* Allocate needed local vectors (which depends on quantities defined during ConstraintsSetUp) */ 1716f4ddd8eeSStefano Zampini ierr = PCBDDCSetUpLocalWorkVectors(pc);CHKERRQ(ierr); 17175e8657edSStefano Zampini 17185e8657edSStefano Zampini if (pcbddc->use_change_of_basis) { 17195e8657edSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 17205e8657edSStefano Zampini 17215e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 17224f1b2e48SStefano Zampini if (pcbddc->benign_change) { 17231dd7afcfSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 1724c263805aSStefano Zampini /* pop B0 from pcbddc->local_mat */ 1725c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 1726c263805aSStefano Zampini } 17275e8657edSStefano Zampini /* get submatrices */ 17285e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 17295e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 17305e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 17317dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 17327dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 17337dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 17343975b054SStefano Zampini /* set flag in pcis to not reuse submatrices during PCISCreate */ 17353975b054SStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 17369c6a02ceSStefano Zampini } else if (!pcbddc->user_ChangeOfBasisMatrix && !pcbddc->benign_change) { 1737b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 17385e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 17395e8657edSStefano Zampini pcbddc->local_mat = matis->A; 17405e8657edSStefano Zampini } 174135509ce9Sstefano_zampini 174235509ce9Sstefano_zampini /* interface pressure block row for B_C */ 174335509ce9Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lP" ,(PetscObject*)&lP);CHKERRQ(ierr); 174435509ce9Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject*)&lA);CHKERRQ(ierr); 174535509ce9Sstefano_zampini if (lA && lP) { 174635509ce9Sstefano_zampini PC_IS* pcis = (PC_IS*)pc->data; 174735509ce9Sstefano_zampini Mat B_BI,B_BB,Bt_BI,Bt_BB; 174835509ce9Sstefano_zampini PetscBool issym; 174935509ce9Sstefano_zampini ierr = MatIsSymmetric(lA,PETSC_SMALL,&issym);CHKERRQ(ierr); 17506cc1294bSstefano_zampini if (issym) { 17517dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_I_local,MAT_INITIAL_MATRIX,&B_BI);CHKERRQ(ierr); 17527dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_B_local,MAT_INITIAL_MATRIX,&B_BB);CHKERRQ(ierr); 175335509ce9Sstefano_zampini ierr = MatCreateTranspose(B_BI,&Bt_BI);CHKERRQ(ierr); 175435509ce9Sstefano_zampini ierr = MatCreateTranspose(B_BB,&Bt_BB);CHKERRQ(ierr); 175535509ce9Sstefano_zampini } else { 17567dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_I_local,MAT_INITIAL_MATRIX,&B_BI);CHKERRQ(ierr); 17577dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_B_local,MAT_INITIAL_MATRIX,&B_BB);CHKERRQ(ierr); 17587dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,pcis->is_I_local,lP,MAT_INITIAL_MATRIX,&Bt_BI);CHKERRQ(ierr); 17597dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,pcis->is_B_local,lP,MAT_INITIAL_MATRIX,&Bt_BB);CHKERRQ(ierr); 176035509ce9Sstefano_zampini } 176135509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_B_BI",(PetscObject)B_BI);CHKERRQ(ierr); 176235509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_B_BB",(PetscObject)B_BB);CHKERRQ(ierr); 176335509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_Bt_BI",(PetscObject)Bt_BI);CHKERRQ(ierr); 176435509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_Bt_BB",(PetscObject)Bt_BB);CHKERRQ(ierr); 176535509ce9Sstefano_zampini ierr = MatDestroy(&B_BI);CHKERRQ(ierr); 176635509ce9Sstefano_zampini ierr = MatDestroy(&B_BB);CHKERRQ(ierr); 176735509ce9Sstefano_zampini ierr = MatDestroy(&Bt_BI);CHKERRQ(ierr); 176835509ce9Sstefano_zampini ierr = MatDestroy(&Bt_BB);CHKERRQ(ierr); 176935509ce9Sstefano_zampini } 177043371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_LocalWork[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 177135509ce9Sstefano_zampini 1772b96c3477SStefano Zampini /* SetUp coarse and local Neumann solvers */ 177399cc7994SStefano Zampini ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr); 1774b96c3477SStefano Zampini /* SetUp Scaling operator */ 17759d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1776674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 17770c7d97c5SJed Brown } 1778c703fcc7SStefano Zampini 17791dd7afcfSStefano Zampini /* mark topography as done */ 178056282151SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 17810369aaf7SStefano Zampini 17821dd7afcfSStefano Zampini /* wrap pcis->A_IB and pcis->A_BI if we did not change explicitly the variables on the pressures */ 17831dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_FALSE);CHKERRQ(ierr); 17841dd7afcfSStefano Zampini 178558a03d70SStefano Zampini if (pcbddc->dbg_flag) { 178658a03d70SStefano Zampini ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1787d9869140SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 17882b510759SStefano Zampini } 17890c7d97c5SJed Brown PetscFunctionReturn(0); 17900c7d97c5SJed Brown } 17910c7d97c5SJed Brown 17920c7d97c5SJed Brown /* 179350efa1b5SStefano Zampini PCApply_BDDC - Applies the BDDC operator to a vector. 17940c7d97c5SJed Brown 17950c7d97c5SJed Brown Input Parameters: 17960f202f7eSStefano Zampini + pc - the preconditioner context 17970f202f7eSStefano Zampini - r - input vector (global) 17980c7d97c5SJed Brown 17990c7d97c5SJed Brown Output Parameter: 18000c7d97c5SJed Brown . z - output vector (global) 18010c7d97c5SJed Brown 18020c7d97c5SJed Brown Application Interface Routine: PCApply() 18030c7d97c5SJed Brown */ 180453cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 18050c7d97c5SJed Brown { 18060c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 18070c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1808b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 18090c7d97c5SJed Brown PetscErrorCode ierr; 18103b03a366Sstefano_zampini const PetscScalar one = 1.0; 18113b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 18122617d88aSStefano Zampini const PetscScalar zero = 0.0; 18130c7d97c5SJed Brown 18140c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 18150c7d97c5SJed Brown NN interface preconditioner changed to BDDC 1816b097fa66SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static == PETSC_TRUE) */ 18170c7d97c5SJed Brown 18180c7d97c5SJed Brown PetscFunctionBegin; 1819f3d41395Sstefano_zampini ierr = PetscCitationsRegister(citation,&cited);CHKERRQ(ierr); 18201dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 18211dd7afcfSStefano Zampini Vec swap; 182227b6a85dSStefano Zampini 182327b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 18241dd7afcfSStefano Zampini swap = pcbddc->work_change; 18251dd7afcfSStefano Zampini pcbddc->work_change = r; 18261dd7afcfSStefano Zampini r = swap; 18271dd7afcfSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 18289cc2a9b1Sstefano_zampini if (pcbddc->benign_apply_coarse_only && pcbddc->use_exact_dirichlet_trick && pcbddc->change_interior) { 18291dd7afcfSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 18301dd7afcfSStefano Zampini ierr = VecLockPush(pcis->vec1_global);CHKERRQ(ierr); 18311dd7afcfSStefano Zampini } 18321dd7afcfSStefano Zampini } 183327b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 1834015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1835efc2fbd9SStefano Zampini } 18368ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 1837b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 18380c7d97c5SJed Brown /* First Dirichlet solve */ 18390c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18400c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18410c7d97c5SJed Brown /* 18420c7d97c5SJed Brown Assembling right hand side for BDDC operator 1843b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 1844674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 18450c7d97c5SJed Brown */ 1846b097fa66SStefano Zampini if (n_D) { 1847b097fa66SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 18480c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 184916909a7fSStefano Zampini if (pcbddc->switch_static) { 185016909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 185116909a7fSStefano Zampini 185216909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 185316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 185416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 185516909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 185616909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 185716909a7fSStefano Zampini } else { 185816909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 185916909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 186016909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 186116909a7fSStefano Zampini } 186216909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 186316909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 186416909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 186516909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 186616909a7fSStefano Zampini } else { 1867b097fa66SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 186816909a7fSStefano Zampini } 1869b097fa66SStefano Zampini } else { 1870b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1871b097fa66SStefano Zampini } 18720c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 18730c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1874674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 1875b76ba322SStefano Zampini } else { 18764fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 1877674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 1878b76ba322SStefano Zampini } 18794fee134fSStefano Zampini } 1880b76ba322SStefano Zampini 18812617d88aSStefano Zampini /* Apply interface preconditioner 18822617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1883dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 18842617d88aSStefano Zampini 1885674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 1886674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 18870c7d97c5SJed Brown 18883b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 18890c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18900c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1891b097fa66SStefano Zampini if (n_B) { 189216909a7fSStefano Zampini if (pcbddc->switch_static) { 189316909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 189416909a7fSStefano Zampini 189516909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 189616909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 189716909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 189816909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 189916909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 190016909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 190116909a7fSStefano Zampini } else { 190216909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 190316909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 190416909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 190516909a7fSStefano Zampini } 190616909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 190716909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 190816909a7fSStefano Zampini } else { 19090c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 191016909a7fSStefano Zampini } 191116909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 191216909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 191316909a7fSStefano Zampini 191416909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 191516909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 191616909a7fSStefano Zampini } else { 191716909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 191816909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 191916909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 192016909a7fSStefano Zampini } 1921b097fa66SStefano Zampini } 1922df187020SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 1923efc2fbd9SStefano Zampini 19248ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 1925b097fa66SStefano Zampini if (pcbddc->switch_static) { 1926b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 1927b097fa66SStefano Zampini } else { 1928b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 1929b097fa66SStefano Zampini } 19300c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19310c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1932b097fa66SStefano Zampini } else { 1933b097fa66SStefano Zampini if (pcbddc->switch_static) { 1934b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 1935b097fa66SStefano Zampini } else { 1936b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 1937b097fa66SStefano Zampini } 1938b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1939b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1940b097fa66SStefano Zampini } 194127b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 19421dd7afcfSStefano Zampini if (pcbddc->benign_apply_coarse_only) { 19431dd7afcfSStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 19441dd7afcfSStefano Zampini } 1945015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 1946efc2fbd9SStefano Zampini } 19471f4df5f7SStefano Zampini 19481dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1949f913dca9SStefano Zampini pcbddc->work_change = r; 19501dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 19511dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 19521dd7afcfSStefano Zampini } 19530c7d97c5SJed Brown PetscFunctionReturn(0); 19540c7d97c5SJed Brown } 195550efa1b5SStefano Zampini 195650efa1b5SStefano Zampini /* 195750efa1b5SStefano Zampini PCApplyTranspose_BDDC - Applies the transpose of the BDDC operator to a vector. 195850efa1b5SStefano Zampini 195950efa1b5SStefano Zampini Input Parameters: 19600f202f7eSStefano Zampini + pc - the preconditioner context 19610f202f7eSStefano Zampini - r - input vector (global) 196250efa1b5SStefano Zampini 196350efa1b5SStefano Zampini Output Parameter: 196450efa1b5SStefano Zampini . z - output vector (global) 196550efa1b5SStefano Zampini 196650efa1b5SStefano Zampini Application Interface Routine: PCApplyTranspose() 196750efa1b5SStefano Zampini */ 196850efa1b5SStefano Zampini PetscErrorCode PCApplyTranspose_BDDC(PC pc,Vec r,Vec z) 196950efa1b5SStefano Zampini { 197050efa1b5SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 197150efa1b5SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1972b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 197350efa1b5SStefano Zampini PetscErrorCode ierr; 197450efa1b5SStefano Zampini const PetscScalar one = 1.0; 197550efa1b5SStefano Zampini const PetscScalar m_one = -1.0; 197650efa1b5SStefano Zampini const PetscScalar zero = 0.0; 197750efa1b5SStefano Zampini 197850efa1b5SStefano Zampini PetscFunctionBegin; 1979f3d41395Sstefano_zampini ierr = PetscCitationsRegister(citation,&cited);CHKERRQ(ierr); 19801dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 19811dd7afcfSStefano Zampini Vec swap; 198227b6a85dSStefano Zampini 198327b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 19841dd7afcfSStefano Zampini swap = pcbddc->work_change; 19851dd7afcfSStefano Zampini pcbddc->work_change = r; 19861dd7afcfSStefano Zampini r = swap; 198727b6a85dSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 19888ae0ca82SStefano Zampini if (pcbddc->benign_apply_coarse_only && pcbddc->exact_dirichlet_trick_app && pcbddc->change_interior) { 198927b6a85dSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 199027b6a85dSStefano Zampini ierr = VecLockPush(pcis->vec1_global);CHKERRQ(ierr); 19911dd7afcfSStefano Zampini } 199227b6a85dSStefano Zampini } 199327b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 1994537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1995537c1cdfSStefano Zampini } 19968ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 1997b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 199850efa1b5SStefano Zampini /* First Dirichlet solve */ 199950efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 200050efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 200150efa1b5SStefano Zampini /* 200250efa1b5SStefano Zampini Assembling right hand side for BDDC operator 2003b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 200450efa1b5SStefano Zampini - pcis->vec1_B the interface part of the global vector z 200550efa1b5SStefano Zampini */ 2006b097fa66SStefano Zampini if (n_D) { 2007b097fa66SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 200850efa1b5SStefano Zampini ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 200916909a7fSStefano Zampini if (pcbddc->switch_static) { 201016909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 201116909a7fSStefano Zampini 201216909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 201316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 201416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 201516909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 201616909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 201716909a7fSStefano Zampini } else { 201816909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 201916909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 202016909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 202116909a7fSStefano Zampini } 202216909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 202316909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 202416909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 202516909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 202616909a7fSStefano Zampini } else { 2027b097fa66SStefano Zampini ierr = MatMultTranspose(pcis->A_IB,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 202816909a7fSStefano Zampini } 2029b097fa66SStefano Zampini } else { 2030b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 2031b097fa66SStefano Zampini } 203250efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 203350efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 203450efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 203550efa1b5SStefano Zampini } else { 203650efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 203750efa1b5SStefano Zampini } 203850efa1b5SStefano Zampini 203950efa1b5SStefano Zampini /* Apply interface preconditioner 204050efa1b5SStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 2041dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_TRUE);CHKERRQ(ierr); 204250efa1b5SStefano Zampini 204350efa1b5SStefano Zampini /* Apply transpose of partition of unity operator */ 204450efa1b5SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 204550efa1b5SStefano Zampini 204650efa1b5SStefano Zampini /* Second Dirichlet solve and assembling of output */ 204750efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 204850efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2049b097fa66SStefano Zampini if (n_B) { 205016909a7fSStefano Zampini if (pcbddc->switch_static) { 205116909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 205216909a7fSStefano Zampini 205316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 205416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 205516909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 205616909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 205716909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 205816909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 205916909a7fSStefano Zampini } else { 206016909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 206116909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 206216909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 206316909a7fSStefano Zampini } 206416909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 206516909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 206616909a7fSStefano Zampini } else { 206750efa1b5SStefano Zampini ierr = MatMultTranspose(pcis->A_BI,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 206816909a7fSStefano Zampini } 206916909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 207016909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 207116909a7fSStefano Zampini 207216909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 207316909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 207416909a7fSStefano Zampini } else { 207516909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 207616909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 207716909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 207816909a7fSStefano Zampini } 2079b097fa66SStefano Zampini } 2080b0147a47SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 20818ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2082b097fa66SStefano Zampini if (pcbddc->switch_static) { 2083b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 2084b097fa66SStefano Zampini } else { 2085b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 2086b097fa66SStefano Zampini } 208750efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 208850efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2089b097fa66SStefano Zampini } else { 2090b097fa66SStefano Zampini if (pcbddc->switch_static) { 2091b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 2092b097fa66SStefano Zampini } else { 2093b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 2094b097fa66SStefano Zampini } 2095b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2096b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2097b097fa66SStefano Zampini } 209827b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 2099537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 2100537c1cdfSStefano Zampini } 21011dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2102f913dca9SStefano Zampini pcbddc->work_change = r; 21031dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 21041dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 21051dd7afcfSStefano Zampini } 210650efa1b5SStefano Zampini PetscFunctionReturn(0); 210750efa1b5SStefano Zampini } 2108674ae819SStefano Zampini 21099326c5c6Sstefano_zampini PetscErrorCode PCReset_BDDC(PC pc) 2110da1bb401SStefano Zampini { 2111da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 21129326c5c6Sstefano_zampini PC_IS *pcis = (PC_IS*)pc->data; 21139326c5c6Sstefano_zampini KSP kspD,kspR,kspC; 2114da1bb401SStefano Zampini PetscErrorCode ierr; 2115da1bb401SStefano Zampini 2116da1bb401SStefano Zampini PetscFunctionBegin; 2117674ae819SStefano Zampini /* free BDDC custom data */ 2118674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 2119674ae819SStefano Zampini /* destroy objects related to topography */ 2120674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 212134a97f8cSStefano Zampini /* destroy objects for scaling operator */ 2122674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 2123674ae819SStefano Zampini /* free solvers stuff */ 2124674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 212562a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 212662a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 212762a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 21281dd7afcfSStefano Zampini /* free data created by PCIS */ 21291dd7afcfSStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 21309326c5c6Sstefano_zampini 21319326c5c6Sstefano_zampini /* restore defaults */ 21329326c5c6Sstefano_zampini kspD = pcbddc->ksp_D; 21339326c5c6Sstefano_zampini kspR = pcbddc->ksp_R; 21349326c5c6Sstefano_zampini kspC = pcbddc->coarse_ksp; 21359326c5c6Sstefano_zampini ierr = PetscMemzero(pc->data,sizeof(*pcbddc));CHKERRQ(ierr); 21369326c5c6Sstefano_zampini pcis->n_neigh = -1; 21379326c5c6Sstefano_zampini pcis->scaling_factor = 1.0; 21389326c5c6Sstefano_zampini pcis->reusesubmatrices = PETSC_TRUE; 21399326c5c6Sstefano_zampini pcbddc->use_local_adj = PETSC_TRUE; 21409326c5c6Sstefano_zampini pcbddc->use_vertices = PETSC_TRUE; 21419326c5c6Sstefano_zampini pcbddc->use_edges = PETSC_TRUE; 21429326c5c6Sstefano_zampini pcbddc->symmetric_primal = PETSC_TRUE; 21439326c5c6Sstefano_zampini pcbddc->vertex_size = 1; 21449326c5c6Sstefano_zampini pcbddc->recompute_topography = PETSC_TRUE; 21459326c5c6Sstefano_zampini pcbddc->coarse_size = -1; 21469326c5c6Sstefano_zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 21479326c5c6Sstefano_zampini pcbddc->coarsening_ratio = 8; 21489326c5c6Sstefano_zampini pcbddc->coarse_eqs_per_proc = 1; 21499326c5c6Sstefano_zampini pcbddc->benign_compute_correction = PETSC_TRUE; 21509326c5c6Sstefano_zampini pcbddc->nedfield = -1; 21519326c5c6Sstefano_zampini pcbddc->nedglobal = PETSC_TRUE; 21529326c5c6Sstefano_zampini pcbddc->graphmaxcount = PETSC_MAX_INT; 21539326c5c6Sstefano_zampini pcbddc->sub_schurs_layers = -1; 21549326c5c6Sstefano_zampini pcbddc->ksp_D = kspD; 21559326c5c6Sstefano_zampini pcbddc->ksp_R = kspR; 21569326c5c6Sstefano_zampini pcbddc->coarse_ksp = kspC; 21579326c5c6Sstefano_zampini PetscFunctionReturn(0); 21589326c5c6Sstefano_zampini } 21599326c5c6Sstefano_zampini 21609326c5c6Sstefano_zampini PetscErrorCode PCDestroy_BDDC(PC pc) 21619326c5c6Sstefano_zampini { 21629326c5c6Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 21639326c5c6Sstefano_zampini PetscErrorCode ierr; 21649326c5c6Sstefano_zampini 21659326c5c6Sstefano_zampini PetscFunctionBegin; 21669326c5c6Sstefano_zampini ierr = PCReset_BDDC(pc);CHKERRQ(ierr); 21679326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 21689326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 21699326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 2170a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",NULL);CHKERRQ(ierr); 2171a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",NULL);CHKERRQ(ierr); 2172906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",NULL);CHKERRQ(ierr); 2173674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 217430368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",NULL);CHKERRQ(ierr); 2175bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 21762b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr); 2177b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr); 21782b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr); 2179bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 218082ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2181bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 218282ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2183bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 218482ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2185bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 2186785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2187bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 218863602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",NULL);CHKERRQ(ierr); 2189bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 2190bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 2191bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 2192bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 2193a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",NULL);CHKERRQ(ierr); 2194ab8c8b98SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",NULL);CHKERRQ(ierr); 2195674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 2196da1bb401SStefano Zampini PetscFunctionReturn(0); 2197da1bb401SStefano Zampini } 21981e6b0712SBarry Smith 2199ab8c8b98SStefano Zampini static PetscErrorCode PCSetCoordinates_BDDC(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 2200ab8c8b98SStefano Zampini { 2201ab8c8b98SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2202ab8c8b98SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 2203ab8c8b98SStefano Zampini PetscErrorCode ierr; 2204ab8c8b98SStefano Zampini 2205ab8c8b98SStefano Zampini PetscFunctionBegin; 2206ab8c8b98SStefano Zampini ierr = PetscFree(mat_graph->coords);CHKERRQ(ierr); 2207ab8c8b98SStefano Zampini ierr = PetscMalloc1(nloc*dim,&mat_graph->coords);CHKERRQ(ierr); 2208ab8c8b98SStefano Zampini ierr = PetscMemcpy(mat_graph->coords,coords,nloc*dim*sizeof(PetscReal));CHKERRQ(ierr); 2209ab8c8b98SStefano Zampini mat_graph->cnloc = nloc; 2210ab8c8b98SStefano Zampini mat_graph->cdim = dim; 2211ab8c8b98SStefano Zampini mat_graph->cloc = PETSC_FALSE; 2212ab8c8b98SStefano Zampini PetscFunctionReturn(0); 2213ab8c8b98SStefano Zampini } 2214ab8c8b98SStefano Zampini 2215a06fd7f2SStefano Zampini static PetscErrorCode PCPreSolveChangeRHS_BDDC(PC pc, PetscBool* change) 2216a06fd7f2SStefano Zampini { 2217a06fd7f2SStefano Zampini PetscFunctionBegin; 2218a06fd7f2SStefano Zampini *change = PETSC_TRUE; 2219a06fd7f2SStefano Zampini PetscFunctionReturn(0); 2220a06fd7f2SStefano Zampini } 2221a06fd7f2SStefano Zampini 22223425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 22233425bc38SStefano Zampini { 2224674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 2225266e20e9SStefano Zampini Vec work; 22263425bc38SStefano Zampini PC_IS* pcis; 22273425bc38SStefano Zampini PC_BDDC* pcbddc; 22283425bc38SStefano Zampini PetscErrorCode ierr; 22290c7d97c5SJed Brown 22303425bc38SStefano Zampini PetscFunctionBegin; 22313425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 22323425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 22333425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 22343425bc38SStefano Zampini 2235229984c5Sstefano_zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 2236229984c5Sstefano_zampini /* copy rhs since we may change it during PCPreSolve_BDDC */ 2237229984c5Sstefano_zampini if (!pcbddc->original_rhs) { 2238229984c5Sstefano_zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 2239229984c5Sstefano_zampini } 22406cc1294bSstefano_zampini if (mat_ctx->rhs_flip) { 22416cc1294bSstefano_zampini ierr = VecPointwiseMult(pcbddc->original_rhs,standard_rhs,mat_ctx->rhs_flip);CHKERRQ(ierr); 22426cc1294bSstefano_zampini } else { 2243229984c5Sstefano_zampini ierr = VecCopy(standard_rhs,pcbddc->original_rhs);CHKERRQ(ierr); 22446cc1294bSstefano_zampini } 2245af140850Sstefano_zampini if (mat_ctx->g2g_p) { 2246229984c5Sstefano_zampini /* interface pressure rhs */ 2247022d8d2bSstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,fetidp_flux_rhs,pcbddc->original_rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2248022d8d2bSstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,fetidp_flux_rhs,pcbddc->original_rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2249229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,standard_rhs,fetidp_flux_rhs,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2250229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,standard_rhs,fetidp_flux_rhs,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22516cc1294bSstefano_zampini if (!mat_ctx->rhs_flip) { 2252229984c5Sstefano_zampini ierr = VecScale(fetidp_flux_rhs,-1.);CHKERRQ(ierr); 2253229984c5Sstefano_zampini } 22546cc1294bSstefano_zampini } 2255c08af4c6SStefano Zampini /* 2256c08af4c6SStefano Zampini change of basis for physical rhs if needed 2257c08af4c6SStefano Zampini It also changes the rhs in case of dirichlet boundaries 2258c08af4c6SStefano Zampini */ 22593738a8e6SStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,pcbddc->original_rhs,NULL);CHKERRQ(ierr); 2260fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 22613738a8e6SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcbddc->original_rhs,pcbddc->work_change);CHKERRQ(ierr); 22623738a8e6SStefano Zampini work = pcbddc->work_change; 2263fc17d649SStefano Zampini } else { 22643738a8e6SStefano Zampini work = pcbddc->original_rhs; 2265fc17d649SStefano Zampini } 22663425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 2267266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2268266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2269fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 2270fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 2271266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2272266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2273674ae819SStefano Zampini /* Apply partition of unity */ 22743425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 2275266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 22768eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 22773425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 22783425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 22793425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 22803425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 2281266e20e9SStefano Zampini ierr = VecSet(work,0.0);CHKERRQ(ierr); 2282266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2283266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2284266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 2285266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2286266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22873425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 22883425bc38SStefano Zampini } 22893425bc38SStefano Zampini /* BDDC rhs */ 22903425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 22918eeda7d8SStefano Zampini if (pcbddc->switch_static) { 22923425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 22933425bc38SStefano Zampini } 22943425bc38SStefano Zampini /* apply BDDC */ 2295229984c5Sstefano_zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 2296dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2297266e20e9SStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 2298229984c5Sstefano_zampini 22993425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 23003425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 23013425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23023425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2303229984c5Sstefano_zampini /* Add contribution to interface pressures */ 2304229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2305229984c5Sstefano_zampini ierr = MatMult(mat_ctx->B_BB,pcis->vec1_B,mat_ctx->vP);CHKERRQ(ierr); 2306229984c5Sstefano_zampini if (pcbddc->switch_static) { 2307229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->B_BI,pcis->vec1_D,mat_ctx->vP,mat_ctx->vP);CHKERRQ(ierr); 2308229984c5Sstefano_zampini } 2309229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->l2g_p,mat_ctx->vP,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2310229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->l2g_p,mat_ctx->vP,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2311229984c5Sstefano_zampini } 23123425bc38SStefano Zampini PetscFunctionReturn(0); 23133425bc38SStefano Zampini } 23141e6b0712SBarry Smith 23153425bc38SStefano Zampini /*@ 23160f202f7eSStefano Zampini PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETI-DP linear system using the physical right-hand side 23173425bc38SStefano Zampini 23183425bc38SStefano Zampini Collective 23193425bc38SStefano Zampini 23203425bc38SStefano Zampini Input Parameters: 23210f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix object obtained by a call to PCBDDCCreateFETIDPOperators 23220f202f7eSStefano Zampini - standard_rhs - the right-hand side of the original linear system 23233425bc38SStefano Zampini 23243425bc38SStefano Zampini Output Parameters: 23250f202f7eSStefano Zampini . fetidp_flux_rhs - the right-hand side for the FETI-DP linear system 23263425bc38SStefano Zampini 23273425bc38SStefano Zampini Level: developer 23283425bc38SStefano Zampini 23293425bc38SStefano Zampini Notes: 23303425bc38SStefano Zampini 23310f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetSolution 23323425bc38SStefano Zampini @*/ 23333425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 23343425bc38SStefano Zampini { 2335674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 23363425bc38SStefano Zampini PetscErrorCode ierr; 23373425bc38SStefano Zampini 23383425bc38SStefano Zampini PetscFunctionBegin; 2339266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2340266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_rhs,VEC_CLASSID,2); 2341266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_rhs,VEC_CLASSID,3); 23423425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2343163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 23443425bc38SStefano Zampini PetscFunctionReturn(0); 23453425bc38SStefano Zampini } 23461e6b0712SBarry Smith 23473425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 23483425bc38SStefano Zampini { 2349674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 23503425bc38SStefano Zampini PC_IS* pcis; 23513425bc38SStefano Zampini PC_BDDC* pcbddc; 23523425bc38SStefano Zampini PetscErrorCode ierr; 2353229984c5Sstefano_zampini Vec work; 23543425bc38SStefano Zampini 23553425bc38SStefano Zampini PetscFunctionBegin; 23563425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 23573425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 23583425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 23593425bc38SStefano Zampini 23603425bc38SStefano Zampini /* apply B_delta^T */ 2361af140850Sstefano_zampini ierr = VecSet(pcis->vec1_B,0.);CHKERRQ(ierr); 23623425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23633425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23643425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 2365229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2366229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->l2g_p,fetidp_flux_sol,mat_ctx->vP,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2367229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->l2g_p,fetidp_flux_sol,mat_ctx->vP,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2368229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->Bt_BB,mat_ctx->vP,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 2369229984c5Sstefano_zampini } 2370229984c5Sstefano_zampini 23713425bc38SStefano Zampini /* compute rhs for BDDC application */ 23723425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 23738eeda7d8SStefano Zampini if (pcbddc->switch_static) { 23743425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 2375229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2376229984c5Sstefano_zampini ierr = VecScale(mat_ctx->vP,-1.);CHKERRQ(ierr); 2377229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->Bt_BI,mat_ctx->vP,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); 23783425bc38SStefano Zampini } 2379229984c5Sstefano_zampini } 2380229984c5Sstefano_zampini 23813425bc38SStefano Zampini /* apply BDDC */ 2382229984c5Sstefano_zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 2383dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2384229984c5Sstefano_zampini 2385229984c5Sstefano_zampini /* put values into global vector */ 2386af140850Sstefano_zampini if (pcbddc->ChangeOfBasisMatrix) work = pcbddc->work_change; 2387af140850Sstefano_zampini else work = standard_sol; 2388229984c5Sstefano_zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2389229984c5Sstefano_zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23908eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 23913425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 23923425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 239300f6b531SStefano Zampini ierr = VecAYPX(pcis->vec1_D,-1.0,mat_ctx->temp_solution_D);CHKERRQ(ierr); 239400f6b531SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); 23953425bc38SStefano Zampini } 2396229984c5Sstefano_zampini 2397229984c5Sstefano_zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2398229984c5Sstefano_zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_D,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2399266e20e9SStefano Zampini /* add p0 solution to final solution */ 2400229984c5Sstefano_zampini ierr = PCBDDCBenignGetOrSetP0(mat_ctx->pc,work,PETSC_FALSE);CHKERRQ(ierr); 2401fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2402af140850Sstefano_zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,work,standard_sol);CHKERRQ(ierr); 2403fc17d649SStefano Zampini } 2404af140850Sstefano_zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 2405af140850Sstefano_zampini if (mat_ctx->g2g_p) { 2406229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,fetidp_flux_sol,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2407229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,fetidp_flux_sol,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2408229984c5Sstefano_zampini } 24093425bc38SStefano Zampini PetscFunctionReturn(0); 24103425bc38SStefano Zampini } 24111e6b0712SBarry Smith 24123425bc38SStefano Zampini /*@ 24130f202f7eSStefano Zampini PCBDDCMatFETIDPGetSolution - Compute the physical solution using the solution of the FETI-DP linear system 24143425bc38SStefano Zampini 24153425bc38SStefano Zampini Collective 24163425bc38SStefano Zampini 24173425bc38SStefano Zampini Input Parameters: 24180f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix obtained by a call to PCBDDCCreateFETIDPOperators 24190f202f7eSStefano Zampini - fetidp_flux_sol - the solution of the FETI-DP linear system 24203425bc38SStefano Zampini 24213425bc38SStefano Zampini Output Parameters: 24220f202f7eSStefano Zampini . standard_sol - the solution defined on the physical domain 24233425bc38SStefano Zampini 24243425bc38SStefano Zampini Level: developer 24253425bc38SStefano Zampini 24263425bc38SStefano Zampini Notes: 24273425bc38SStefano Zampini 24280f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetRHS 24293425bc38SStefano Zampini @*/ 24303425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 24313425bc38SStefano Zampini { 2432674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 24333425bc38SStefano Zampini PetscErrorCode ierr; 24343425bc38SStefano Zampini 24353425bc38SStefano Zampini PetscFunctionBegin; 2436266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2437266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_sol,VEC_CLASSID,2); 2438266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_sol,VEC_CLASSID,3); 24393425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2440163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 24413425bc38SStefano Zampini PetscFunctionReturn(0); 24423425bc38SStefano Zampini } 24431e6b0712SBarry Smith 2444547c9a8eSstefano_zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, PetscBool fully_redundant, const char* prefix, Mat *fetidp_mat, PC *fetidp_pc) 24453425bc38SStefano Zampini { 2446674ae819SStefano Zampini 2447674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 24483425bc38SStefano Zampini Mat newmat; 2449674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 24503425bc38SStefano Zampini PC newpc; 2451ce94432eSBarry Smith MPI_Comm comm; 24523425bc38SStefano Zampini PetscErrorCode ierr; 24533425bc38SStefano Zampini 24543425bc38SStefano Zampini PetscFunctionBegin; 2455ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 2456*15579a77SStefano Zampini /* FETI-DP matrix */ 24573425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 24581720468bSStefano Zampini fetidpmat_ctx->fully_redundant = fully_redundant; 24593425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 2460a5bb87b3Sstefano_zampini ierr = MatCreateShell(comm,fetidpmat_ctx->n,fetidpmat_ctx->n,fetidpmat_ctx->N,fetidpmat_ctx->N,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 2461*15579a77SStefano Zampini ierr = PetscObjectSetName((PetscObject)newmat,!fetidpmat_ctx->l2g_lambda_only ? "F" : "G");CHKERRQ(ierr); 24623425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 2463edf7251bSStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT_TRANSPOSE,(void (*)(void))FETIDPMatMultTranspose);CHKERRQ(ierr); 24643425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 2465*15579a77SStefano Zampini /* propagate MatOptions */ 2466*15579a77SStefano Zampini { 2467*15579a77SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)fetidpmat_ctx->pc->data; 2468*15579a77SStefano Zampini PetscBool issym; 2469*15579a77SStefano Zampini 2470*15579a77SStefano Zampini ierr = MatGetOption(pc->mat,MAT_SYMMETRIC,&issym);CHKERRQ(ierr); 2471*15579a77SStefano Zampini if (issym || pcbddc->symmetric_primal) { 2472*15579a77SStefano Zampini ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 2473*15579a77SStefano Zampini } 2474*15579a77SStefano Zampini } 2475547c9a8eSstefano_zampini ierr = MatSetOptionsPrefix(newmat,prefix);CHKERRQ(ierr); 2476547c9a8eSstefano_zampini ierr = MatAppendOptionsPrefix(newmat,"fetidp_");CHKERRQ(ierr); 24773425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 2478*15579a77SStefano Zampini /* FETI-DP preconditioner */ 24793425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 24803425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 24813425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 2482e1214c54Sstefano_zampini ierr = PCSetOperators(newpc,newmat,newmat);CHKERRQ(ierr); 2483e1214c54Sstefano_zampini ierr = PCSetOptionsPrefix(newpc,prefix);CHKERRQ(ierr); 2484e1214c54Sstefano_zampini ierr = PCAppendOptionsPrefix(newpc,"fetidp_");CHKERRQ(ierr); 2485399ffe99SStefano Zampini ierr = PCSetErrorIfFailure(newpc,pc->erroriffailure);CHKERRQ(ierr); 2486*15579a77SStefano Zampini if (!fetidpmat_ctx->l2g_lambda_only) { /* standard FETI-DP */ 24873425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 2488*15579a77SStefano Zampini ierr = PCShellSetName(newpc,"FETI-DP multipliers");CHKERRQ(ierr); 24893425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 24903425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 2491edf7251bSStefano Zampini ierr = PCShellSetApplyTranspose(newpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 2492c45b8d2dSstefano_zampini ierr = PCShellSetView(newpc,FETIDPPCView);CHKERRQ(ierr); 24933425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 2494e1214c54Sstefano_zampini } else { 2495e1214c54Sstefano_zampini KSP *ksps; 2496e1214c54Sstefano_zampini PC lagpc; 2497e1214c54Sstefano_zampini Mat M,AM,PM; 2498e1214c54Sstefano_zampini PetscInt nn; 2499e1214c54Sstefano_zampini 2500*15579a77SStefano Zampini ierr = ISViewFromOptions(fetidpmat_ctx->lagrange,NULL,"-lag_view");CHKERRQ(ierr); 2501*15579a77SStefano Zampini ierr = ISViewFromOptions(fetidpmat_ctx->pressure,NULL,"-press_view");CHKERRQ(ierr); 2502e1214c54Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_PPmat",(PetscObject*)&M);CHKERRQ(ierr); 2503e1214c54Sstefano_zampini ierr = PCSetType(newpc,PCFIELDSPLIT);CHKERRQ(ierr); 2504e1214c54Sstefano_zampini ierr = PCFieldSplitSetIS(newpc,"lag",fetidpmat_ctx->lagrange);CHKERRQ(ierr); 2505e1214c54Sstefano_zampini ierr = PCFieldSplitSetIS(newpc,"p",fetidpmat_ctx->pressure);CHKERRQ(ierr); 2506e1214c54Sstefano_zampini ierr = PCFieldSplitSetType(newpc,PC_COMPOSITE_SCHUR);CHKERRQ(ierr); 250740c75d76SStefano Zampini ierr = PCFieldSplitSetSchurFactType(newpc,PC_FIELDSPLIT_SCHUR_FACT_DIAG);CHKERRQ(ierr); 2508e1214c54Sstefano_zampini ierr = PCFieldSplitSetSchurPre(newpc,PC_FIELDSPLIT_SCHUR_PRE_USER,M);CHKERRQ(ierr); 2509c096484dSStefano Zampini ierr = PCFieldSplitSetSchurScale(newpc,1.0);CHKERRQ(ierr); 2510*15579a77SStefano Zampini 2511*15579a77SStefano Zampini /* we need to setfromoptions and setup here to access the blocks */ 2512e1214c54Sstefano_zampini ierr = PCSetFromOptions(newpc);CHKERRQ(ierr); 2513e1214c54Sstefano_zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 2514e1214c54Sstefano_zampini 2515e1214c54Sstefano_zampini /* set the solver for the (0,0) block */ 251640c75d76SStefano Zampini ierr = PCFieldSplitGetSubKSP(newpc,&nn,&ksps);CHKERRQ(ierr); 2517e1214c54Sstefano_zampini ierr = PCCreate(comm,&lagpc);CHKERRQ(ierr); 2518e1214c54Sstefano_zampini ierr = PCSetType(lagpc,PCSHELL);CHKERRQ(ierr); 2519e1214c54Sstefano_zampini ierr = KSPGetOperators(ksps[0],&AM,&PM);CHKERRQ(ierr); 2520e1214c54Sstefano_zampini ierr = PCSetOperators(lagpc,AM,PM);CHKERRQ(ierr); 2521e1214c54Sstefano_zampini ierr = PCShellSetContext(lagpc,fetidppc_ctx);CHKERRQ(ierr); 2522e1214c54Sstefano_zampini ierr = PCShellSetApply(lagpc,FETIDPPCApply);CHKERRQ(ierr); 2523e1214c54Sstefano_zampini ierr = PCShellSetApplyTranspose(lagpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 2524e1214c54Sstefano_zampini ierr = PCShellSetView(lagpc,FETIDPPCView);CHKERRQ(ierr); 2525e1214c54Sstefano_zampini ierr = PCShellSetDestroy(lagpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 2526e1214c54Sstefano_zampini ierr = KSPSetPC(ksps[0],lagpc);CHKERRQ(ierr); 2527*15579a77SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)lagpc,(PetscObject)ksps[0],0);CHKERRQ(ierr); 2528e1214c54Sstefano_zampini ierr = PCDestroy(&lagpc);CHKERRQ(ierr); 2529e1214c54Sstefano_zampini ierr = PetscFree(ksps);CHKERRQ(ierr); 2530e1214c54Sstefano_zampini } 25313425bc38SStefano Zampini /* return pointers for objects created */ 25323425bc38SStefano Zampini *fetidp_mat = newmat; 25333425bc38SStefano Zampini *fetidp_pc = newpc; 25343425bc38SStefano Zampini PetscFunctionReturn(0); 25353425bc38SStefano Zampini } 25361e6b0712SBarry Smith 253794ef8ddeSSatish Balay /*@C 25380f202f7eSStefano Zampini PCBDDCCreateFETIDPOperators - Create FETI-DP operators 25393425bc38SStefano Zampini 25403425bc38SStefano Zampini Collective 25413425bc38SStefano Zampini 25423425bc38SStefano Zampini Input Parameters: 25431720468bSStefano Zampini + pc - the BDDC preconditioning context (setup should have been called before) 2544547c9a8eSstefano_zampini . fully_redundant - true for a fully redundant set of Lagrange multipliers 2545547c9a8eSstefano_zampini - prefix - optional options database prefix for the objects to be created (can be NULL) 254628509bceSStefano Zampini 254728509bceSStefano Zampini Output Parameters: 25480f202f7eSStefano Zampini + fetidp_mat - shell FETI-DP matrix object 25490f202f7eSStefano Zampini - fetidp_pc - shell Dirichlet preconditioner for FETI-DP matrix 255028509bceSStefano Zampini 25513425bc38SStefano Zampini Level: developer 25523425bc38SStefano Zampini 25533425bc38SStefano Zampini Notes: 25540f202f7eSStefano Zampini Currently the only operations provided for FETI-DP matrix are MatMult and MatMultTranspose 25553425bc38SStefano Zampini 25560f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCMatFETIDPGetRHS, PCBDDCMatFETIDPGetSolution 25573425bc38SStefano Zampini @*/ 2558547c9a8eSstefano_zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, PetscBool fully_redundant, const char *prefix, Mat *fetidp_mat, PC *fetidp_pc) 25593425bc38SStefano Zampini { 25603425bc38SStefano Zampini PetscErrorCode ierr; 25613425bc38SStefano Zampini 25623425bc38SStefano Zampini PetscFunctionBegin; 25633425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 25643425bc38SStefano Zampini if (pc->setupcalled) { 2565547c9a8eSstefano_zampini ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,PetscBool,const char*,Mat*,PC*),(pc,fully_redundant,prefix,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 25664247aa23Sstefano_zampini } else SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n"); 25673425bc38SStefano Zampini PetscFunctionReturn(0); 25683425bc38SStefano Zampini } 25690c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2570da1bb401SStefano Zampini /*MC 2571da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 25720c7d97c5SJed Brown 257328509bceSStefano Zampini An implementation of the BDDC preconditioner based on 257428509bceSStefano Zampini 257528509bceSStefano Zampini .vb 257628509bceSStefano Zampini [1] C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 257728509bceSStefano Zampini [2] A. Klawonn and O. B. Widlund. "Dual-Primal FETI Methods for Linear Elasticity", http://cs.nyu.edu/csweb/Research/TechReports/TR2004-855/TR2004-855.pdf 257828509bceSStefano Zampini [3] J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", http://arxiv.org/abs/0712.3977 25790f202f7eSStefano 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 258028509bceSStefano Zampini .ve 258128509bceSStefano Zampini 258228509bceSStefano Zampini The matrix to be preconditioned (Pmat) must be of type MATIS. 258328509bceSStefano Zampini 25840f202f7eSStefano Zampini Currently works with MATIS matrices with local matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers. 258528509bceSStefano Zampini 258628509bceSStefano Zampini It also works with unsymmetric and indefinite problems. 258728509bceSStefano Zampini 2588b6fdb6dfSStefano 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. 2589b6fdb6dfSStefano Zampini 2590c7017625SStefano 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). 259128509bceSStefano Zampini 25920f202f7eSStefano 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() 259330368db7SStefano Zampini Additional information on dofs can be provided by using PCBDDCSetDofsSplitting(), PCBDDCSetDirichletBoundaries(), PCBDDCSetNeumannBoundaries(), and PCBDDCSetPrimalVerticesIS() and their local counterparts. 259428509bceSStefano Zampini 25950f202f7eSStefano Zampini Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace(). Non-singular modes are retained via SVD. 259628509bceSStefano Zampini 25970f202f7eSStefano 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. 25980f202f7eSStefano Zampini User defined change of basis can be passed to PCBDDC by using PCBDDCSetChangeOfBasisMat() 259928509bceSStefano Zampini 26000f202f7eSStefano Zampini The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using a MatPartitioning object. 260128509bceSStefano Zampini 2602df4d28bfSStefano 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. 260328509bceSStefano Zampini 26040f202f7eSStefano 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. 26050f202f7eSStefano Zampini Deluxe scaling is not supported yet for FETI-DP. 26060f202f7eSStefano Zampini 26070f202f7eSStefano Zampini Options Database Keys (some of them, run with -h for a complete list): 26080f202f7eSStefano Zampini 26090f202f7eSStefano Zampini . -pc_bddc_use_vertices <true> - use or not vertices in primal space 26100f202f7eSStefano Zampini . -pc_bddc_use_edges <true> - use or not edges in primal space 26110f202f7eSStefano Zampini . -pc_bddc_use_faces <false> - use or not faces in primal space 26120f202f7eSStefano Zampini . -pc_bddc_symmetric <true> - symmetric computation of primal basis functions. Specify false for unsymmetric problems 26130f202f7eSStefano Zampini . -pc_bddc_use_change_of_basis <false> - use change of basis approach (on edges only) 26140f202f7eSStefano Zampini . -pc_bddc_use_change_on_faces <false> - use change of basis approach on faces if change of basis has been requested 26150f202f7eSStefano Zampini . -pc_bddc_switch_static <false> - switches from M_2 (default) to M_3 operator (see reference article [1]) 261628509bceSStefano Zampini . -pc_bddc_levels <0> - maximum number of levels for multilevel 26170f202f7eSStefano 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) 26185459c157SBarry 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) 26190f202f7eSStefano Zampini . -pc_bddc_use_deluxe_scaling <false> - use deluxe scaling 26200f202f7eSStefano 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) 2621bd2a564bSStefano 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) 262228509bceSStefano Zampini - -pc_bddc_check_level <0> - set verbosity level of debugging output 262328509bceSStefano Zampini 262428509bceSStefano Zampini Options for Dirichlet, Neumann or coarse solver can be set with 262528509bceSStefano Zampini .vb 262628509bceSStefano Zampini -pc_bddc_dirichlet_ 262728509bceSStefano Zampini -pc_bddc_neumann_ 262828509bceSStefano Zampini -pc_bddc_coarse_ 262928509bceSStefano Zampini .ve 26300f202f7eSStefano Zampini e.g -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg. PCBDDC uses by default KPSPREONLY and PCLU. 263128509bceSStefano Zampini 26320f202f7eSStefano Zampini When using a multilevel approach, solvers' options at the N-th level (N > 1) can be specified as 263328509bceSStefano Zampini .vb 2634312be037SStefano Zampini -pc_bddc_dirichlet_lN_ 2635312be037SStefano Zampini -pc_bddc_neumann_lN_ 2636312be037SStefano Zampini -pc_bddc_coarse_lN_ 263728509bceSStefano Zampini .ve 26380f202f7eSStefano Zampini Note that level number ranges from the finest (0) to the coarsest (N). 26390f202f7eSStefano 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. 26400f202f7eSStefano Zampini .vb 26410f202f7eSStefano Zampini -pc_bddc_coarse_pc_bddc_adaptive_threshold 5 -pc_bddc_coarse_l1_pc_bddc_redistribute 3 26420f202f7eSStefano Zampini .ve 26430f202f7eSStefano 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 2644da1bb401SStefano Zampini 2645da1bb401SStefano Zampini Level: intermediate 2646da1bb401SStefano Zampini 2647e94cfbe0SPatrick Sanan Developer Notes: 2648da1bb401SStefano Zampini 2649da1bb401SStefano Zampini Contributed by Stefano Zampini 2650da1bb401SStefano Zampini 2651da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 2652da1bb401SStefano Zampini M*/ 2653b2573a8aSBarry Smith 26548cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 2655da1bb401SStefano Zampini { 2656da1bb401SStefano Zampini PetscErrorCode ierr; 2657da1bb401SStefano Zampini PC_BDDC *pcbddc; 2658da1bb401SStefano Zampini 2659da1bb401SStefano Zampini PetscFunctionBegin; 2660b00a9115SJed Brown ierr = PetscNewLog(pc,&pcbddc);CHKERRQ(ierr); 2661da1bb401SStefano Zampini pc->data = (void*)pcbddc; 2662da1bb401SStefano Zampini 2663da1bb401SStefano Zampini /* create PCIS data structure */ 2664da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 2665da1bb401SStefano Zampini 26669326c5c6Sstefano_zampini /* create local graph structure */ 26679326c5c6Sstefano_zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 26689326c5c6Sstefano_zampini 26699326c5c6Sstefano_zampini /* BDDC nonzero defaults */ 267008a5cf49SStefano Zampini pcbddc->use_local_adj = PETSC_TRUE; 267147d04d0dSStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 267247d04d0dSStefano Zampini pcbddc->use_edges = PETSC_TRUE; 26733301b35fSStefano Zampini pcbddc->symmetric_primal = PETSC_TRUE; 267414f95afaSStefano Zampini pcbddc->vertex_size = 1; 2675c703fcc7SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 267668457ee5SStefano Zampini pcbddc->coarse_size = -1; 267785c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 267847d04d0dSStefano Zampini pcbddc->coarsening_ratio = 8; 267957de7509SStefano Zampini pcbddc->coarse_eqs_per_proc = 1; 268027b6a85dSStefano Zampini pcbddc->benign_compute_correction = PETSC_TRUE; 26811e0482f5SStefano Zampini pcbddc->nedfield = -1; 26821e0482f5SStefano Zampini pcbddc->nedglobal = PETSC_TRUE; 2683be12c134Sstefano_zampini pcbddc->graphmaxcount = PETSC_MAX_INT; 2684b96c3477SStefano Zampini pcbddc->sub_schurs_layers = -1; 2685bd2a564bSStefano Zampini pcbddc->adaptive_threshold[0] = 0.0; 2686bd2a564bSStefano Zampini pcbddc->adaptive_threshold[1] = 0.0; 2687b7eb3628SStefano Zampini 2688da1bb401SStefano Zampini /* function pointers */ 2689da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 269093bd9ae7SStefano Zampini pc->ops->applytranspose = PCApplyTranspose_BDDC; 2691da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 2692da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 2693da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 26946b78500eSPatrick Sanan pc->ops->view = PCView_BDDC; 2695da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 2696da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 2697da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 2698534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 2699534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 27009326c5c6Sstefano_zampini pc->ops->reset = PCReset_BDDC; 2701da1bb401SStefano Zampini 2702da1bb401SStefano Zampini /* composing function */ 2703a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",PCBDDCSetDiscreteGradient_BDDC);CHKERRQ(ierr); 2704a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",PCBDDCSetDivergenceMat_BDDC);CHKERRQ(ierr); 2705906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",PCBDDCSetChangeOfBasisMat_BDDC);CHKERRQ(ierr); 2706674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 270730368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",PCBDDCSetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 2708bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 27092b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr); 2710b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr); 27112b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr); 2712bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 271382ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2714bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 271582ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2716bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 271782ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2718bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 271982ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2720bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 272163602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",PCBDDCSetDofsSplittingLocal_BDDC);CHKERRQ(ierr); 2722bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 2723bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 2724bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 2725bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 2726a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",PCPreSolveChangeRHS_BDDC);CHKERRQ(ierr); 2727ab8c8b98SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_BDDC);CHKERRQ(ierr); 2728da1bb401SStefano Zampini PetscFunctionReturn(0); 2729da1bb401SStefano Zampini } 273043371fb9SStefano Zampini 273143371fb9SStefano Zampini /*@C 273243371fb9SStefano Zampini PCBDDCInitializePackage - This function initializes everything in the PCBDDC package. It is called 273343371fb9SStefano Zampini from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PCCreate_BDDC() 273443371fb9SStefano Zampini when using static libraries. 273543371fb9SStefano Zampini 273643371fb9SStefano Zampini Level: developer 273743371fb9SStefano Zampini 273843371fb9SStefano Zampini .keywords: PC, PCBDDC, initialize, package 273943371fb9SStefano Zampini .seealso: PetscInitialize() 274043371fb9SStefano Zampini @*/ 274143371fb9SStefano Zampini PetscErrorCode PCBDDCInitializePackage(void) 274243371fb9SStefano Zampini { 274343371fb9SStefano Zampini PetscErrorCode ierr; 274443371fb9SStefano Zampini int i; 274543371fb9SStefano Zampini 274643371fb9SStefano Zampini PetscFunctionBegin; 274743371fb9SStefano Zampini if (PCBDDCPackageInitialized) PetscFunctionReturn(0); 274843371fb9SStefano Zampini PCBDDCPackageInitialized = PETSC_TRUE; 274943371fb9SStefano Zampini ierr = PetscRegisterFinalize(PCBDDCFinalizePackage);CHKERRQ(ierr); 275043371fb9SStefano Zampini 275143371fb9SStefano Zampini /* general events */ 275243371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCTopo",PC_CLASSID,&PC_BDDC_Topology[0]);CHKERRQ(ierr); 275343371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCLKSP",PC_CLASSID,&PC_BDDC_LocalSolvers[0]);CHKERRQ(ierr); 275443371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCLWor",PC_CLASSID,&PC_BDDC_LocalWork[0]);CHKERRQ(ierr); 275543371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCorr",PC_CLASSID,&PC_BDDC_CorrectionSetUp[0]);CHKERRQ(ierr); 275643371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCSet",PC_CLASSID,&PC_BDDC_CoarseSetUp[0]);CHKERRQ(ierr); 275743371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCKSP",PC_CLASSID,&PC_BDDC_CoarseSolver[0]);CHKERRQ(ierr); 275843371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCAdap",PC_CLASSID,&PC_BDDC_AdaptiveSetUp[0]);CHKERRQ(ierr); 275943371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCScal",PC_CLASSID,&PC_BDDC_Scaling[0]);CHKERRQ(ierr); 276043371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCSchr",PC_CLASSID,&PC_BDDC_Schurs[0]);CHKERRQ(ierr); 276143371fb9SStefano Zampini for (i=1;i<PETSC_PCBDDC_MAXLEVELS;i++) { 276243371fb9SStefano Zampini char ename[32]; 276343371fb9SStefano Zampini 276443371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCTopo l%02d",i);CHKERRQ(ierr); 276543371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Topology[i]);CHKERRQ(ierr); 276643371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCLKSP l%02d",i);CHKERRQ(ierr); 276743371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_LocalSolvers[i]);CHKERRQ(ierr); 276843371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCLWor l%02d",i);CHKERRQ(ierr); 276943371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_LocalWork[i]);CHKERRQ(ierr); 277043371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCorr l%02d",i);CHKERRQ(ierr); 277143371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CorrectionSetUp[i]);CHKERRQ(ierr); 277243371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCSet l%02d",i);CHKERRQ(ierr); 277343371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CoarseSetUp[i]);CHKERRQ(ierr); 277443371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCKSP l%02d",i);CHKERRQ(ierr); 277543371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CoarseSolver[i]);CHKERRQ(ierr); 277643371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCAdap l%02d",i);CHKERRQ(ierr); 277743371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_AdaptiveSetUp[i]);CHKERRQ(ierr); 277843371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCScal l%02d",i);CHKERRQ(ierr); 277943371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Scaling[i]);CHKERRQ(ierr); 278043371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCSchr l%02d",i);CHKERRQ(ierr); 278143371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Schurs[i]);CHKERRQ(ierr); 278243371fb9SStefano Zampini } 278343371fb9SStefano Zampini PetscFunctionReturn(0); 278443371fb9SStefano Zampini } 278543371fb9SStefano Zampini 278643371fb9SStefano Zampini /*@C 278743371fb9SStefano Zampini PCBDDCFinalizePackage - This function frees everything from the PCBDDC package. It is 278843371fb9SStefano Zampini called from PetscFinalize() automatically. 278943371fb9SStefano Zampini 279043371fb9SStefano Zampini Level: developer 279143371fb9SStefano Zampini 279243371fb9SStefano Zampini .keywords: Petsc, destroy, package 279343371fb9SStefano Zampini .seealso: PetscFinalize() 279443371fb9SStefano Zampini @*/ 279543371fb9SStefano Zampini PetscErrorCode PCBDDCFinalizePackage(void) 279643371fb9SStefano Zampini { 279743371fb9SStefano Zampini PetscFunctionBegin; 279843371fb9SStefano Zampini PCBDDCPackageInitialized = PETSC_FALSE; 279943371fb9SStefano Zampini PetscFunctionReturn(0); 280043371fb9SStefano Zampini } 2801