153cdbc3dSStefano Zampini /* TODOLIST 2eb97c9d2SStefano Zampini 3eb97c9d2SStefano Zampini Solvers 4a0d3c3abSStefano Zampini - Add support for cholesky for coarse solver (similar to local solvers) 5eb97c9d2SStefano Zampini - Propagate ksp prefixes for solvers to mat objects? 6eb97c9d2SStefano Zampini 7eb97c9d2SStefano Zampini User interface 80f202f7eSStefano Zampini - ** DM attached to pc? 9eb97c9d2SStefano Zampini 10eb97c9d2SStefano Zampini Debugging output 11b9b85e73SStefano Zampini - * Better management of verbosity levels of debugging output 12eb97c9d2SStefano Zampini 13eb97c9d2SStefano Zampini Extra 14b9b85e73SStefano Zampini - *** Is it possible to work with PCBDDCGraph on boundary indices only (less memory consumed)? 15eb97c9d2SStefano Zampini - BDDC with MG framework? 16eb97c9d2SStefano Zampini 17eb97c9d2SStefano Zampini MATIS related operations contained in BDDC code 18eb97c9d2SStefano Zampini - Provide general case for subassembling 19eb97c9d2SStefano Zampini 2053cdbc3dSStefano Zampini */ 210c7d97c5SJed Brown 22ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 23ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 243b03a366Sstefano_zampini #include <petscblaslapack.h> 25674ae819SStefano Zampini 2643371fb9SStefano Zampini static PetscBool PCBDDCPackageInitialized = PETSC_FALSE; 2743371fb9SStefano Zampini 28f3d41395Sstefano_zampini static PetscBool cited = PETSC_FALSE; 29f3d41395Sstefano_zampini static const char citation[] = 30f3d41395Sstefano_zampini "@article{ZampiniPCBDDC,\n" 31f3d41395Sstefano_zampini "author = {Stefano Zampini},\n" 32f3d41395Sstefano_zampini "title = {{PCBDDC}: A Class of Robust Dual-Primal Methods in {PETS}c},\n" 33f3d41395Sstefano_zampini "journal = {SIAM Journal on Scientific Computing},\n" 34f3d41395Sstefano_zampini "volume = {38},\n" 35f3d41395Sstefano_zampini "number = {5},\n" 36f3d41395Sstefano_zampini "pages = {S282-S306},\n" 37f3d41395Sstefano_zampini "year = {2016},\n" 38f3d41395Sstefano_zampini "doi = {10.1137/15M1025785},\n" 39f3d41395Sstefano_zampini "URL = {http://dx.doi.org/10.1137/15M1025785},\n" 40f3d41395Sstefano_zampini "eprint = {http://dx.doi.org/10.1137/15M1025785}\n" 41f3d41395Sstefano_zampini "}\n"; 42f3d41395Sstefano_zampini 4343371fb9SStefano Zampini PetscLogEvent PC_BDDC_Topology[PETSC_PCBDDC_MAXLEVELS]; 4443371fb9SStefano Zampini PetscLogEvent PC_BDDC_LocalSolvers[PETSC_PCBDDC_MAXLEVELS]; 4543371fb9SStefano Zampini PetscLogEvent PC_BDDC_LocalWork[PETSC_PCBDDC_MAXLEVELS]; 4643371fb9SStefano Zampini PetscLogEvent PC_BDDC_CorrectionSetUp[PETSC_PCBDDC_MAXLEVELS]; 478ead10e4SStefano Zampini PetscLogEvent PC_BDDC_ApproxSetUp[PETSC_PCBDDC_MAXLEVELS]; 488ead10e4SStefano Zampini PetscLogEvent PC_BDDC_ApproxApply[PETSC_PCBDDC_MAXLEVELS]; 4943371fb9SStefano Zampini PetscLogEvent PC_BDDC_CoarseSetUp[PETSC_PCBDDC_MAXLEVELS]; 5043371fb9SStefano Zampini PetscLogEvent PC_BDDC_CoarseSolver[PETSC_PCBDDC_MAXLEVELS]; 5143371fb9SStefano Zampini PetscLogEvent PC_BDDC_AdaptiveSetUp[PETSC_PCBDDC_MAXLEVELS]; 5243371fb9SStefano Zampini PetscLogEvent PC_BDDC_Scaling[PETSC_PCBDDC_MAXLEVELS]; 5343371fb9SStefano Zampini PetscLogEvent PC_BDDC_Schurs[PETSC_PCBDDC_MAXLEVELS]; 5443371fb9SStefano Zampini 550369aaf7SStefano Zampini PetscErrorCode PCApply_BDDC(PC,Vec,Vec); 560369aaf7SStefano Zampini 574416b707SBarry Smith PetscErrorCode PCSetFromOptions_BDDC(PetscOptionItems *PetscOptionsObject,PC pc) 580c7d97c5SJed Brown { 590c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 60e569e4e1SStefano Zampini PetscInt nt,i; 610c7d97c5SJed Brown PetscErrorCode ierr; 620c7d97c5SJed Brown 630c7d97c5SJed Brown PetscFunctionBegin; 64e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"BDDC options");CHKERRQ(ierr); 658eeda7d8SStefano Zampini /* Verbose debugging */ 66a13144ffSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_check_level","Verbose output for PCBDDC (intended for debug)","none",pcbddc->dbg_flag,&pcbddc->dbg_flag,NULL);CHKERRQ(ierr); 67a13144ffSStefano Zampini /* Approximate solvers */ 68c7017625SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_dirichlet_approximate","Inform PCBDDC that we are using approximate Dirichlet solvers","none",pcbddc->NullSpace_corr[0],&pcbddc->NullSpace_corr[0],NULL);CHKERRQ(ierr); 69c7017625SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_dirichlet_approximate_scale","Inform PCBDDC that we need to scale the Dirichlet solve","none",pcbddc->NullSpace_corr[1],&pcbddc->NullSpace_corr[1],NULL);CHKERRQ(ierr); 70c7017625SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_neumann_approximate","Inform PCBDDC that we are using approximate Neumann solvers","none",pcbddc->NullSpace_corr[2],&pcbddc->NullSpace_corr[2],NULL);CHKERRQ(ierr); 71c7017625SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_neumann_approximate_scale","Inform PCBDDC that we need to scale the Neumann solve","none",pcbddc->NullSpace_corr[3],&pcbddc->NullSpace_corr[3],NULL);CHKERRQ(ierr); 726b78500eSPatrick Sanan /* Primal space customization */ 7308a5cf49SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_local_mat_graph","Use or not adjacency graph of local mat for interface analysis","none",pcbddc->use_local_adj,&pcbddc->use_local_adj,NULL);CHKERRQ(ierr); 74be12c134Sstefano_zampini ierr = PetscOptionsInt("-pc_bddc_graph_maxcount","Maximum number of shared subdomains for a connected component","none",pcbddc->graphmaxcount,&pcbddc->graphmaxcount,NULL);CHKERRQ(ierr); 751c7a958bSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_corner_selection","Activates face-based corner selection","none",pcbddc->corner_selection,&pcbddc->corner_selection,NULL);CHKERRQ(ierr); 768eeda7d8SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_vertices","Use or not corner dofs in coarse space","none",pcbddc->use_vertices,&pcbddc->use_vertices,NULL);CHKERRQ(ierr); 778eeda7d8SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_edges","Use or not edge constraints in coarse space","none",pcbddc->use_edges,&pcbddc->use_edges,NULL);CHKERRQ(ierr); 788eeda7d8SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_faces","Use or not face constraints in coarse space","none",pcbddc->use_faces,&pcbddc->use_faces,NULL);CHKERRQ(ierr); 7914f95afaSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_vertex_size","Connected components smaller or equal to vertex size will be considered as primal vertices","none",pcbddc->vertex_size,&pcbddc->vertex_size,NULL);CHKERRQ(ierr); 806d9e27e4SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_nnsp","Use near null space attached to the matrix to compute constraints","none",pcbddc->use_nnsp,&pcbddc->use_nnsp,NULL);CHKERRQ(ierr); 816d9e27e4SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_nnsp_true","Use near null space attached to the matrix to compute constraints as is","none",pcbddc->use_nnsp_true,&pcbddc->use_nnsp_true,NULL);CHKERRQ(ierr); 8214f95afaSStefano 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); 838eeda7d8SStefano Zampini /* Change of basis */ 84b9b85e73SStefano 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); 85b9b85e73SStefano 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); 86674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 87674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 88674ae819SStefano Zampini } 898eeda7d8SStefano Zampini /* Switch between M_2 (default) and M_3 preconditioners (as defined by C. Dohrmann in the ref. article) */ 908eeda7d8SStefano 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); 91e569e4e1SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_coarse_eqs_per_proc","Target number of equations per process for coarse problem redistribution (significant only at the coarsest level)","none",pcbddc->coarse_eqs_per_proc,&pcbddc->coarse_eqs_per_proc,NULL);CHKERRQ(ierr); 92e569e4e1SStefano Zampini i = pcbddc->coarsening_ratio; 93e569e4e1SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","PCBDDCSetCoarseningRatio",i,&i,NULL);CHKERRQ(ierr); 94e569e4e1SStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc,i);CHKERRQ(ierr); 95e569e4e1SStefano Zampini i = pcbddc->max_levels; 96e569e4e1SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_levels","Set maximum number of levels for multilevel","PCBDDCSetLevels",i,&i,NULL);CHKERRQ(ierr); 97e569e4e1SStefano Zampini ierr = PCBDDCSetLevels(pc,i);CHKERRQ(ierr); 98e569e4e1SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_coarse_eqs_limit","Set maximum number of equations on coarsest grid to aim for","none",pcbddc->coarse_eqs_limit,&pcbddc->coarse_eqs_limit,NULL);CHKERRQ(ierr); 99323d395dSStefano 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); 100674ae819SStefano 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); 101b96c3477SStefano 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); 102b96c3477SStefano 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); 103b96c3477SStefano 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); 104683d3df6SStefano 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); 105bf3a8328SStefano 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); 106839e9adbSstefano_zampini ierr = PetscOptionsBool("-pc_bddc_deluxe_singlemat","Collapse deluxe operators","none",pcbddc->deluxe_singlemat,&pcbddc->deluxe_singlemat,NULL);CHKERRQ(ierr); 107bf3a8328SStefano 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); 108bd2a564bSStefano Zampini nt = 2; 109bd2a564bSStefano Zampini ierr = PetscOptionsRealArray("-pc_bddc_adaptive_threshold","Thresholds to be used for adaptive selection of constraints","none",pcbddc->adaptive_threshold,&nt,NULL);CHKERRQ(ierr); 110bd2a564bSStefano Zampini if (nt == 1) pcbddc->adaptive_threshold[1] = pcbddc->adaptive_threshold[0]; 11108122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmin","Minimum number of constraints per connected components","none",pcbddc->adaptive_nmin,&pcbddc->adaptive_nmin,NULL);CHKERRQ(ierr); 11208122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmax","Maximum number of constraints per connected components","none",pcbddc->adaptive_nmax,&pcbddc->adaptive_nmax,NULL);CHKERRQ(ierr); 1133301b35fSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_symmetric","Symmetric computation of primal basis functions","none",pcbddc->symmetric_primal,&pcbddc->symmetric_primal,NULL);CHKERRQ(ierr); 114b0c7d250SStefano 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); 115b3afcdbeSStefano 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); 116e9627c49SStefano 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); 11727b6a85dSStefano 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); 118a198735bSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nonetflux","Automatic computation of no-net-flux quadrature weights","none",pcbddc->compute_nonetflux,&pcbddc->compute_nonetflux,NULL);CHKERRQ(ierr); 1194f1b2e48SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_detect_disconnected","Detects disconnected subdomains","none",pcbddc->detect_disconnected,&pcbddc->detect_disconnected,NULL);CHKERRQ(ierr); 1208361f951SStefano 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); 12170c64980SStefano 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); 1220c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 1230c7d97c5SJed Brown PetscFunctionReturn(0); 1240c7d97c5SJed Brown } 1256b78500eSPatrick Sanan 1266b78500eSPatrick Sanan static PetscErrorCode PCView_BDDC(PC pc,PetscViewer viewer) 1276b78500eSPatrick Sanan { 1286b78500eSPatrick Sanan PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 129e9627c49SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1306b78500eSPatrick Sanan PetscErrorCode ierr; 13171783a16SStefano Zampini PetscBool isascii; 132e9627c49SStefano Zampini PetscSubcomm subcomm; 133e9627c49SStefano Zampini PetscViewer subviewer; 1346b78500eSPatrick Sanan 1356b78500eSPatrick Sanan PetscFunctionBegin; 1366b78500eSPatrick Sanan ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1376b78500eSPatrick Sanan /* ASCII viewer */ 1386b78500eSPatrick Sanan if (isascii) { 1394b2aedd3SStefano Zampini PetscMPIInt color,rank,size; 140fbad9177SStefano Zampini PetscInt64 loc[7],gsum[6],gmax[6],gmin[6],totbenign; 141e9627c49SStefano Zampini PetscScalar interface_size; 142e9627c49SStefano Zampini PetscReal ratio1=0.,ratio2=0.; 143e9627c49SStefano Zampini Vec counter; 1446b78500eSPatrick Sanan 145b74ba07aSstefano_zampini if (!pc->setupcalled) { 146b74ba07aSstefano_zampini ierr = PetscViewerASCIIPrintf(viewer," Partial information available: preconditioner has not been setup yet\n");CHKERRQ(ierr); 147b74ba07aSstefano_zampini } 148efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use verbose output: %D\n",pcbddc->dbg_flag);CHKERRQ(ierr); 1496f0c0a6aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use user-defined CSR: %d\n",!!pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 1506f0c0a6aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use local mat graph: %d\n",pcbddc->use_local_adj && !pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 151e9627c49SStefano Zampini if (pcbddc->mat_graph->twodim) { 152efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Connectivity graph topological dimension: 2\n");CHKERRQ(ierr); 153e9627c49SStefano Zampini } else { 154efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Connectivity graph topological dimension: 3\n");CHKERRQ(ierr); 155e9627c49SStefano Zampini } 156aefa1729SStefano Zampini if (pcbddc->graphmaxcount != PETSC_MAX_INT) { 157efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Graph max count: %D\n",pcbddc->graphmaxcount);CHKERRQ(ierr); 158aefa1729SStefano Zampini } 15950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use vertices: %d (vertex size %D)\n",pcbddc->use_vertices,pcbddc->vertex_size);CHKERRQ(ierr); 160efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use edges: %d\n",pcbddc->use_edges);CHKERRQ(ierr); 161efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use faces: %d\n",pcbddc->use_faces);CHKERRQ(ierr); 162efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use true near null space: %d\n",pcbddc->use_nnsp_true);CHKERRQ(ierr); 163efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use QR for single constraints on cc: %d\n",pcbddc->use_qr_single);CHKERRQ(ierr); 164efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use change of basis on local edge nodes: %d\n",pcbddc->use_change_of_basis);CHKERRQ(ierr); 165efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use change of basis on local face nodes: %d\n",pcbddc->use_change_on_faces);CHKERRQ(ierr); 166efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," User defined change of basis matrix: %d\n",!!pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 167efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Has change of basis matrix: %d\n",!!pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 168efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eliminate dirichlet boundary dofs: %d\n",pcbddc->eliminate_dirdofs);CHKERRQ(ierr); 169efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Switch on static condensation ops around the interface preconditioner: %d\n",pcbddc->switch_static);CHKERRQ(ierr); 170efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use exact dirichlet trick: %d\n",pcbddc->use_exact_dirichlet_trick);CHKERRQ(ierr); 17150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Multilevel max levels: %D\n",pcbddc->max_levels);CHKERRQ(ierr); 17250e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Multilevel coarsening ratio: %D\n",pcbddc->coarsening_ratio);CHKERRQ(ierr); 173efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use estimated eigs for coarse problem: %d\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 174efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe scaling: %d\n",pcbddc->use_deluxe_scaling);CHKERRQ(ierr); 175efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe zerorows: %d\n",pcbddc->deluxe_zerorows);CHKERRQ(ierr); 176efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe singlemat: %d\n",pcbddc->deluxe_singlemat);CHKERRQ(ierr); 177efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Rebuild interface graph for Schur principal minors: %d\n",pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 17850e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Number of dofs' layers for the computation of principal minors: %D\n",pcbddc->sub_schurs_layers);CHKERRQ(ierr); 179efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use user CSR graph to compute successive layers: %d\n",pcbddc->sub_schurs_use_useradj);CHKERRQ(ierr); 180bd2a564bSStefano Zampini if (pcbddc->adaptive_threshold[1] != pcbddc->adaptive_threshold[0]) { 181bd2a564bSStefano 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); 182bd2a564bSStefano Zampini } else { 183bd2a564bSStefano 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); 184bd2a564bSStefano Zampini } 18550e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Min constraints / connected component: %D\n",pcbddc->adaptive_nmin);CHKERRQ(ierr); 18650e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Max constraints / connected component: %D\n",pcbddc->adaptive_nmax);CHKERRQ(ierr); 187efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Invert exact Schur complement for adaptive selection: %d\n",pcbddc->sub_schurs_exact_schur);CHKERRQ(ierr); 188efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Symmetric computation of primal basis functions: %d\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 18950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Num. Procs. to map coarse adjacency list: %D\n",pcbddc->coarse_adj_red);CHKERRQ(ierr); 19050e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Coarse eqs per proc (significant at the coarsest level): %D\n",pcbddc->coarse_eqs_per_proc);CHKERRQ(ierr); 1918361f951SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Detect disconnected: %d (filter %d)\n",pcbddc->detect_disconnected,pcbddc->detect_disconnected_filter);CHKERRQ(ierr); 192efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Benign subspace trick: %d (change explicit %d)\n",pcbddc->benign_saddle_point,pcbddc->benign_change_explicit);CHKERRQ(ierr); 193efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Benign subspace trick is active: %d\n",pcbddc->benign_have_null);CHKERRQ(ierr); 19415579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Algebraic computation of no-net-flux: %d\n",pcbddc->compute_nonetflux);CHKERRQ(ierr); 195b74ba07aSstefano_zampini if (!pc->setupcalled) PetscFunctionReturn(0); 1966b78500eSPatrick Sanan 197fbad9177SStefano Zampini /* compute interface size */ 198e9627c49SStefano Zampini ierr = VecSet(pcis->vec1_B,1.0);CHKERRQ(ierr); 199e9627c49SStefano Zampini ierr = MatCreateVecs(pc->pmat,&counter,0);CHKERRQ(ierr); 200e9627c49SStefano Zampini ierr = VecSet(counter,0.0);CHKERRQ(ierr); 201e9627c49SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 202e9627c49SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 203e9627c49SStefano Zampini ierr = VecSum(counter,&interface_size);CHKERRQ(ierr); 204e9627c49SStefano Zampini ierr = VecDestroy(&counter);CHKERRQ(ierr); 205fbad9177SStefano Zampini 206fbad9177SStefano Zampini /* compute some statistics on the domain decomposition */ 207e9627c49SStefano Zampini gsum[0] = 1; 208fbad9177SStefano Zampini gsum[1] = gsum[2] = gsum[3] = gsum[4] = gsum[5] = 0; 209e9627c49SStefano Zampini loc[0] = !!pcis->n; 210e9627c49SStefano Zampini loc[1] = pcis->n - pcis->n_B; 211e9627c49SStefano Zampini loc[2] = pcis->n_B; 212e9627c49SStefano Zampini loc[3] = pcbddc->local_primal_size; 213345ecf6cSStefano Zampini loc[4] = pcis->n; 214fbad9177SStefano Zampini loc[5] = pcbddc->n_local_subs > 0 ? pcbddc->n_local_subs : (pcis->n ? 1 : 0); 215fbad9177SStefano Zampini loc[6] = pcbddc->benign_n; 216fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gsum,6,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 217fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = -1; 218fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gmax,6,MPIU_INT64,MPI_MAX,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 219fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = PETSC_MAX_INT; 220fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gmin,6,MPIU_INT64,MPI_MIN,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 221fbad9177SStefano Zampini ierr = MPI_Reduce(&loc[6],&totbenign,1,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 222e9627c49SStefano Zampini if (pcbddc->coarse_size) { 223e9627c49SStefano Zampini ratio1 = pc->pmat->rmap->N/(1.*pcbddc->coarse_size); 224e9627c49SStefano Zampini ratio2 = PetscRealPart(interface_size)/pcbddc->coarse_size; 225e9627c49SStefano Zampini } 226efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"********************************** STATISTICS AT LEVEL %d **********************************\n",pcbddc->current_level);CHKERRQ(ierr); 22750e0721cSStefano 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); 22850e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Coarsening ratios: all/coarse %D interface/coarse %D\n",(PetscInt)ratio1,(PetscInt)ratio2);CHKERRQ(ierr); 22950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Active processes : %D\n",(PetscInt)gsum[0]);CHKERRQ(ierr); 23050e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Total subdomains : %D\n",(PetscInt)gsum[5]);CHKERRQ(ierr); 231345ecf6cSStefano Zampini if (pcbddc->benign_have_null) { 23250e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Benign subs : %D\n",(PetscInt)totbenign);CHKERRQ(ierr); 233345ecf6cSStefano Zampini } 23450e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Dofs type :\tMIN\tMAX\tMEAN\n");CHKERRQ(ierr); 23550e0721cSStefano 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); 23650e0721cSStefano 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); 23750e0721cSStefano 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); 23850e0721cSStefano 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); 23950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Local subs :\t%D\t%D\n" ,(PetscInt)gmin[5],(PetscInt)gmax[5]);CHKERRQ(ierr); 24015579a77SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 24115579a77SStefano Zampini 24215579a77SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 24315579a77SStefano Zampini 24415579a77SStefano Zampini /* local solvers */ 24515579a77SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscObjectComm((PetscObject)pcbddc->ksp_D),&subviewer);CHKERRQ(ierr); 24615579a77SStefano Zampini if (!rank) { 24715579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Interior solver (rank 0)\n");CHKERRQ(ierr); 24815579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 24915579a77SStefano Zampini ierr = KSPView(pcbddc->ksp_D,subviewer);CHKERRQ(ierr); 25015579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 25115579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Correction solver (rank 0)\n");CHKERRQ(ierr); 25215579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 25315579a77SStefano Zampini ierr = KSPView(pcbddc->ksp_R,subviewer);CHKERRQ(ierr); 25415579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 25515579a77SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 25615579a77SStefano Zampini } 25715579a77SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscObjectComm((PetscObject)pcbddc->ksp_D),&subviewer);CHKERRQ(ierr); 25827b6a85dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 259e9627c49SStefano Zampini 260fbad9177SStefano Zampini /* the coarse problem can be handled by a different communicator */ 261e9627c49SStefano Zampini if (pcbddc->coarse_ksp) color = 1; 262e9627c49SStefano Zampini else color = 0; 2634b2aedd3SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 264e9627c49SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)pc),&subcomm);CHKERRQ(ierr); 2654b2aedd3SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,PetscMin(size,2));CHKERRQ(ierr); 266e9627c49SStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 267e9627c49SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 268e9627c49SStefano Zampini if (color == 1) { 26915579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Coarse solver\n");CHKERRQ(ierr); 27015579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 271e9627c49SStefano Zampini ierr = KSPView(pcbddc->coarse_ksp,subviewer);CHKERRQ(ierr); 27215579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 273e9627c49SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 274e9627c49SStefano Zampini } 275e9627c49SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 276e9627c49SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 277e9627c49SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 278e9627c49SStefano Zampini } 2796b78500eSPatrick Sanan PetscFunctionReturn(0); 2806b78500eSPatrick Sanan } 281a13144ffSStefano Zampini 2821e0482f5SStefano Zampini static PetscErrorCode PCBDDCSetDiscreteGradient_BDDC(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 283a13144ffSStefano Zampini { 284a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 285a13144ffSStefano Zampini PetscErrorCode ierr; 286a13144ffSStefano Zampini 287a13144ffSStefano Zampini PetscFunctionBegin; 288a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr); 289a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 290a13144ffSStefano Zampini pcbddc->discretegradient = G; 291a13144ffSStefano Zampini pcbddc->nedorder = order > 0 ? order : -order; 292495a2a07SStefano Zampini pcbddc->nedfield = field; 2931e0482f5SStefano Zampini pcbddc->nedglobal = global; 2941e0482f5SStefano Zampini pcbddc->conforming = conforming; 295a13144ffSStefano Zampini PetscFunctionReturn(0); 296a13144ffSStefano Zampini } 297a13144ffSStefano Zampini 298a13144ffSStefano Zampini /*@ 299a13144ffSStefano Zampini PCBDDCSetDiscreteGradient - Sets the discrete gradient 300a13144ffSStefano Zampini 301a13144ffSStefano Zampini Collective on PC 302a13144ffSStefano Zampini 303a13144ffSStefano Zampini Input Parameters: 304a13144ffSStefano Zampini + pc - the preconditioning context 305a13144ffSStefano Zampini . G - the discrete gradient matrix (should be in AIJ format) 306a13144ffSStefano Zampini . order - the order of the Nedelec space (1 for the lowest order) 307495a2a07SStefano Zampini . field - the field id of the Nedelec dofs (not used if the fields have not been specified) 3081e0482f5SStefano Zampini . global - the type of global ordering for the rows of G 309a13144ffSStefano Zampini - conforming - whether the mesh is conforming or not 310a13144ffSStefano Zampini 311a13144ffSStefano Zampini Level: advanced 312a13144ffSStefano Zampini 31395452b02SPatrick Sanan Notes: 31495452b02SPatrick Sanan The discrete gradient matrix G is used to analyze the subdomain edges, and it should not contain any zero entry. 315495a2a07SStefano Zampini For variable order spaces, the order should be set to zero. 3161e0482f5SStefano Zampini If global is true, the rows of G should be given in global ordering for the whole dofs; 3171e0482f5SStefano Zampini if false, the ordering should be global for the Nedelec field. 3181e0482f5SStefano 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 3191e0482f5SStefano Zampini and geid the one for the Nedelec field. 320a13144ffSStefano Zampini 321495a2a07SStefano Zampini .seealso: PCBDDC,PCBDDCSetDofsSplitting(),PCBDDCSetDofsSplittingLocal() 322a13144ffSStefano Zampini @*/ 3231e0482f5SStefano Zampini PetscErrorCode PCBDDCSetDiscreteGradient(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 324a13144ffSStefano Zampini { 325a13144ffSStefano Zampini PetscErrorCode ierr; 326a13144ffSStefano Zampini 327a13144ffSStefano Zampini PetscFunctionBegin; 328a13144ffSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 329a13144ffSStefano Zampini PetscValidHeaderSpecific(G,MAT_CLASSID,2); 330a13144ffSStefano Zampini PetscValidLogicalCollectiveInt(pc,order,3); 3311e0482f5SStefano Zampini PetscValidLogicalCollectiveInt(pc,field,4); 3321e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,global,5); 3331e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,conforming,6); 3341e0482f5SStefano Zampini PetscCheckSameComm(pc,1,G,2); 3351e0482f5SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDiscreteGradient_C",(PC,Mat,PetscInt,PetscInt,PetscBool,PetscBool),(pc,G,order,field,global,conforming));CHKERRQ(ierr); 336a13144ffSStefano Zampini PetscFunctionReturn(0); 337a13144ffSStefano Zampini } 338a13144ffSStefano Zampini 3398ae0ca82SStefano Zampini static PetscErrorCode PCBDDCSetDivergenceMat_BDDC(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 340a198735bSStefano Zampini { 341a198735bSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 342a198735bSStefano Zampini PetscErrorCode ierr; 3436b78500eSPatrick Sanan 344a198735bSStefano Zampini PetscFunctionBegin; 345a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)divudotp);CHKERRQ(ierr); 346a198735bSStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 347a198735bSStefano Zampini pcbddc->divudotp = divudotp; 3488ae0ca82SStefano Zampini pcbddc->divudotp_trans = trans; 349a198735bSStefano Zampini pcbddc->compute_nonetflux = PETSC_TRUE; 350a198735bSStefano Zampini if (vl2l) { 351a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2l);CHKERRQ(ierr); 352fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 353a198735bSStefano Zampini pcbddc->divudotp_vl2l = vl2l; 354a198735bSStefano Zampini } 355a198735bSStefano Zampini PetscFunctionReturn(0); 356a198735bSStefano Zampini } 3573d996552SStefano Zampini 358a198735bSStefano Zampini /*@ 359a198735bSStefano Zampini PCBDDCSetDivergenceMat - Sets the linear operator representing \int_\Omega \div {\bf u} \cdot p dx 360a198735bSStefano Zampini 361a198735bSStefano Zampini Collective on PC 362a198735bSStefano Zampini 363a198735bSStefano Zampini Input Parameters: 364a198735bSStefano Zampini + pc - the preconditioning context 365a198735bSStefano Zampini . divudotp - the matrix (must be of type MATIS) 3668ae0ca82SStefano Zampini . trans - if trans if false (resp. true), then pressures are in the test (trial) space and velocities are in the trial (test) space. 36705a3bf82SStefano 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 368a198735bSStefano Zampini 369a198735bSStefano Zampini Level: advanced 370a198735bSStefano Zampini 37195452b02SPatrick Sanan Notes: 37295452b02SPatrick Sanan This auxiliary matrix is used to compute quadrature weights representing the net-flux across subdomain boundaries 37305a3bf82SStefano Zampini If vl2l is NULL, the local ordering for velocities in divudotp should match that of the preconditioning matrix 374a198735bSStefano Zampini 375a198735bSStefano Zampini .seealso: PCBDDC 376a198735bSStefano Zampini @*/ 3778ae0ca82SStefano Zampini PetscErrorCode PCBDDCSetDivergenceMat(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 378a198735bSStefano Zampini { 379a198735bSStefano Zampini PetscBool ismatis; 380a198735bSStefano Zampini PetscErrorCode ierr; 381a198735bSStefano Zampini 382a198735bSStefano Zampini PetscFunctionBegin; 383a198735bSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 384a198735bSStefano Zampini PetscValidHeaderSpecific(divudotp,MAT_CLASSID,2); 385a198735bSStefano Zampini PetscCheckSameComm(pc,1,divudotp,2); 3868ae0ca82SStefano Zampini PetscValidLogicalCollectiveBool(pc,trans,3); 3871b24a7afSStefano Zampini if (vl2l) PetscValidHeaderSpecific(vl2l,IS_CLASSID,4); 388a198735bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)divudotp,MATIS,&ismatis);CHKERRQ(ierr); 389a198735bSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Divergence matrix needs to be of type MATIS"); 3908ae0ca82SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDivergenceMat_C",(PC,Mat,PetscBool,IS),(pc,divudotp,trans,vl2l));CHKERRQ(ierr); 391a198735bSStefano Zampini PetscFunctionReturn(0); 392a198735bSStefano Zampini } 3932d505d7fSStefano Zampini 3941dd7afcfSStefano Zampini static PetscErrorCode PCBDDCSetChangeOfBasisMat_BDDC(PC pc, Mat change, PetscBool interior) 395b9b85e73SStefano Zampini { 396b9b85e73SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 397b9b85e73SStefano Zampini PetscErrorCode ierr; 398b9b85e73SStefano Zampini 399b9b85e73SStefano Zampini PetscFunctionBegin; 400b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)change);CHKERRQ(ierr); 40156282151SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 402b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = change; 4031dd7afcfSStefano Zampini pcbddc->change_interior = interior; 404b9b85e73SStefano Zampini PetscFunctionReturn(0); 405b9b85e73SStefano Zampini } 406b9b85e73SStefano Zampini /*@ 407906d46d4SStefano Zampini PCBDDCSetChangeOfBasisMat - Set user defined change of basis for dofs 408b9b85e73SStefano Zampini 409b9b85e73SStefano Zampini Collective on PC 410b9b85e73SStefano Zampini 411b9b85e73SStefano Zampini Input Parameters: 412b9b85e73SStefano Zampini + pc - the preconditioning context 4131dd7afcfSStefano Zampini . change - the change of basis matrix 4141dd7afcfSStefano Zampini - interior - whether or not the change of basis modifies interior dofs 415b9b85e73SStefano Zampini 416b9b85e73SStefano Zampini Level: intermediate 417b9b85e73SStefano Zampini 418b9b85e73SStefano Zampini Notes: 419b9b85e73SStefano Zampini 420b9b85e73SStefano Zampini .seealso: PCBDDC 421b9b85e73SStefano Zampini @*/ 4221dd7afcfSStefano Zampini PetscErrorCode PCBDDCSetChangeOfBasisMat(PC pc, Mat change, PetscBool interior) 423b9b85e73SStefano Zampini { 424b9b85e73SStefano Zampini PetscErrorCode ierr; 425b9b85e73SStefano Zampini 426b9b85e73SStefano Zampini PetscFunctionBegin; 427b9b85e73SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 428b9b85e73SStefano Zampini PetscValidHeaderSpecific(change,MAT_CLASSID,2); 429906d46d4SStefano Zampini PetscCheckSameComm(pc,1,change,2); 430906d46d4SStefano Zampini if (pc->mat) { 431906d46d4SStefano Zampini PetscInt rows_c,cols_c,rows,cols; 432906d46d4SStefano Zampini ierr = MatGetSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 433906d46d4SStefano Zampini ierr = MatGetSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 434e0fe2d75SToby 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); 435e0fe2d75SToby 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); 436906d46d4SStefano Zampini ierr = MatGetLocalSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 437906d46d4SStefano Zampini ierr = MatGetLocalSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 438e0fe2d75SToby 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); 439e0fe2d75SToby 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); 440906d46d4SStefano Zampini } 4411dd7afcfSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetChangeOfBasisMat_C",(PC,Mat,PetscBool),(pc,change,interior));CHKERRQ(ierr); 442b9b85e73SStefano Zampini PetscFunctionReturn(0); 443b9b85e73SStefano Zampini } 4442d505d7fSStefano Zampini 44530368db7SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesIS_BDDC(PC pc, IS PrimalVertices) 44630368db7SStefano Zampini { 44730368db7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 44856282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 44930368db7SStefano Zampini PetscErrorCode ierr; 45030368db7SStefano Zampini 45130368db7SStefano Zampini PetscFunctionBegin; 45256282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 45356282151SStefano Zampini if (pcbddc->user_primal_vertices) { 45456282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices,&isequal);CHKERRQ(ierr); 45556282151SStefano Zampini } 45630368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 45730368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 45830368db7SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 45956282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 46030368db7SStefano Zampini PetscFunctionReturn(0); 46130368db7SStefano Zampini } 462ab8c8b98SStefano Zampini 46330368db7SStefano Zampini /*@ 46430368db7SStefano Zampini PCBDDCSetPrimalVerticesIS - Set additional user defined primal vertices in PCBDDC 46530368db7SStefano Zampini 46630368db7SStefano Zampini Collective 46730368db7SStefano Zampini 46830368db7SStefano Zampini Input Parameters: 46930368db7SStefano Zampini + pc - the preconditioning context 47030368db7SStefano Zampini - PrimalVertices - index set of primal vertices in global numbering (can be empty) 47130368db7SStefano Zampini 47230368db7SStefano Zampini Level: intermediate 47330368db7SStefano Zampini 47430368db7SStefano Zampini Notes: 47530368db7SStefano Zampini Any process can list any global node 47630368db7SStefano Zampini 4773100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCGetPrimalVerticesIS(), PCBDDCSetPrimalVerticesLocalIS(), PCBDDCGetPrimalVerticesLocalIS() 47830368db7SStefano Zampini @*/ 47930368db7SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesIS(PC pc, IS PrimalVertices) 48030368db7SStefano Zampini { 48130368db7SStefano Zampini PetscErrorCode ierr; 48230368db7SStefano Zampini 48330368db7SStefano Zampini PetscFunctionBegin; 48430368db7SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 48530368db7SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 48630368db7SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 48730368db7SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 48830368db7SStefano Zampini PetscFunctionReturn(0); 48930368db7SStefano Zampini } 4902d505d7fSStefano Zampini 4913100ebe3SStefano Zampini static PetscErrorCode PCBDDCGetPrimalVerticesIS_BDDC(PC pc, IS *is) 4923100ebe3SStefano Zampini { 4933100ebe3SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4943100ebe3SStefano Zampini 4953100ebe3SStefano Zampini PetscFunctionBegin; 4963100ebe3SStefano Zampini *is = pcbddc->user_primal_vertices; 4973100ebe3SStefano Zampini PetscFunctionReturn(0); 4983100ebe3SStefano Zampini } 4993100ebe3SStefano Zampini 5003100ebe3SStefano Zampini /*@ 5013100ebe3SStefano Zampini PCBDDCGetPrimalVerticesIS - Get user defined primal vertices set with PCBDDCSetPrimalVerticesIS() 5023100ebe3SStefano Zampini 5033100ebe3SStefano Zampini Collective 5043100ebe3SStefano Zampini 5053100ebe3SStefano Zampini Input Parameters: 5063100ebe3SStefano Zampini . pc - the preconditioning context 5073100ebe3SStefano Zampini 5083100ebe3SStefano Zampini Output Parameters: 5093100ebe3SStefano Zampini . is - index set of primal vertices in global numbering (NULL if not set) 5103100ebe3SStefano Zampini 5113100ebe3SStefano Zampini Level: intermediate 5123100ebe3SStefano Zampini 5133100ebe3SStefano Zampini Notes: 5143100ebe3SStefano Zampini 5153100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCSetPrimalVerticesIS(), PCBDDCSetPrimalVerticesLocalIS(), PCBDDCGetPrimalVerticesLocalIS() 5163100ebe3SStefano Zampini @*/ 5173100ebe3SStefano Zampini PetscErrorCode PCBDDCGetPrimalVerticesIS(PC pc, IS *is) 5183100ebe3SStefano Zampini { 5193100ebe3SStefano Zampini PetscErrorCode ierr; 5203100ebe3SStefano Zampini 5213100ebe3SStefano Zampini PetscFunctionBegin; 5223100ebe3SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5233100ebe3SStefano Zampini PetscValidPointer(is,2); 5243100ebe3SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetPrimalVerticesIS_C",(PC,IS*),(pc,is));CHKERRQ(ierr); 5253100ebe3SStefano Zampini PetscFunctionReturn(0); 5263100ebe3SStefano Zampini } 5273100ebe3SStefano Zampini 528674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 529674ae819SStefano Zampini { 530674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 53156282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 532674ae819SStefano Zampini PetscErrorCode ierr; 5331e6b0712SBarry Smith 534674ae819SStefano Zampini PetscFunctionBegin; 53556282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 53656282151SStefano Zampini if (pcbddc->user_primal_vertices_local) { 53756282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices_local,&isequal);CHKERRQ(ierr); 53856282151SStefano Zampini } 539674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 54030368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 54130368db7SStefano Zampini pcbddc->user_primal_vertices_local = PrimalVertices; 54256282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 543674ae819SStefano Zampini PetscFunctionReturn(0); 544674ae819SStefano Zampini } 5453100ebe3SStefano Zampini 546674ae819SStefano Zampini /*@ 54728509bceSStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC 548674ae819SStefano Zampini 54917eb1463SStefano Zampini Collective 550674ae819SStefano Zampini 551674ae819SStefano Zampini Input Parameters: 552674ae819SStefano Zampini + pc - the preconditioning context 55317eb1463SStefano Zampini - PrimalVertices - index set of primal vertices in local numbering (can be empty) 554674ae819SStefano Zampini 555674ae819SStefano Zampini Level: intermediate 556674ae819SStefano Zampini 557674ae819SStefano Zampini Notes: 558674ae819SStefano Zampini 5593100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCSetPrimalVerticesIS(), PCBDDCGetPrimalVerticesIS(), PCBDDCGetPrimalVerticesLocalIS() 560674ae819SStefano Zampini @*/ 561674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 562674ae819SStefano Zampini { 563674ae819SStefano Zampini PetscErrorCode ierr; 564674ae819SStefano Zampini 565674ae819SStefano Zampini PetscFunctionBegin; 566674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 567674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 56817eb1463SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 569674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 570674ae819SStefano Zampini PetscFunctionReturn(0); 571674ae819SStefano Zampini } 5722d505d7fSStefano Zampini 5733100ebe3SStefano Zampini static PetscErrorCode PCBDDCGetPrimalVerticesLocalIS_BDDC(PC pc, IS *is) 5743100ebe3SStefano Zampini { 5753100ebe3SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5763100ebe3SStefano Zampini 5773100ebe3SStefano Zampini PetscFunctionBegin; 5783100ebe3SStefano Zampini *is = pcbddc->user_primal_vertices_local; 5793100ebe3SStefano Zampini PetscFunctionReturn(0); 5803100ebe3SStefano Zampini } 5813100ebe3SStefano Zampini 5823100ebe3SStefano Zampini /*@ 5833100ebe3SStefano Zampini PCBDDCGetPrimalVerticesLocalIS - Get user defined primal vertices set with PCBDDCSetPrimalVerticesLocalIS() 5843100ebe3SStefano Zampini 5853100ebe3SStefano Zampini Collective 5863100ebe3SStefano Zampini 5873100ebe3SStefano Zampini Input Parameters: 5883100ebe3SStefano Zampini . pc - the preconditioning context 5893100ebe3SStefano Zampini 5903100ebe3SStefano Zampini Output Parameters: 5913100ebe3SStefano Zampini . is - index set of primal vertices in local numbering (NULL if not set) 5923100ebe3SStefano Zampini 5933100ebe3SStefano Zampini Level: intermediate 5943100ebe3SStefano Zampini 5953100ebe3SStefano Zampini Notes: 5963100ebe3SStefano Zampini 5973100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCSetPrimalVerticesIS(), PCBDDCGetPrimalVerticesIS(), PCBDDCSetPrimalVerticesLocalIS() 5983100ebe3SStefano Zampini @*/ 5993100ebe3SStefano Zampini PetscErrorCode PCBDDCGetPrimalVerticesLocalIS(PC pc, IS *is) 6003100ebe3SStefano Zampini { 6013100ebe3SStefano Zampini PetscErrorCode ierr; 6023100ebe3SStefano Zampini 6033100ebe3SStefano Zampini PetscFunctionBegin; 6043100ebe3SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6053100ebe3SStefano Zampini PetscValidPointer(is,2); 6063100ebe3SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetPrimalVerticesLocalIS_C",(PC,IS*),(pc,is));CHKERRQ(ierr); 6073100ebe3SStefano Zampini PetscFunctionReturn(0); 6083100ebe3SStefano Zampini } 6093100ebe3SStefano Zampini 6104fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 6114fad6a16SStefano Zampini { 6124fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6134fad6a16SStefano Zampini 6144fad6a16SStefano Zampini PetscFunctionBegin; 6154fad6a16SStefano Zampini pcbddc->coarsening_ratio = k; 6164fad6a16SStefano Zampini PetscFunctionReturn(0); 6174fad6a16SStefano Zampini } 6181e6b0712SBarry Smith 6194fad6a16SStefano Zampini /*@ 62028509bceSStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel 6214fad6a16SStefano Zampini 6224fad6a16SStefano Zampini Logically collective on PC 6234fad6a16SStefano Zampini 6244fad6a16SStefano Zampini Input Parameters: 6254fad6a16SStefano Zampini + pc - the preconditioning context 62628509bceSStefano Zampini - k - coarsening ratio (H/h at the coarser level) 6274fad6a16SStefano Zampini 6280f202f7eSStefano Zampini Options Database Keys: 6290f202f7eSStefano Zampini . -pc_bddc_coarsening_ratio 6304fad6a16SStefano Zampini 6314fad6a16SStefano Zampini Level: intermediate 6324fad6a16SStefano Zampini 6334fad6a16SStefano Zampini Notes: 6340f202f7eSStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level 6354fad6a16SStefano Zampini 6360f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetLevels() 6374fad6a16SStefano Zampini @*/ 6384fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 6394fad6a16SStefano Zampini { 6404fad6a16SStefano Zampini PetscErrorCode ierr; 6414fad6a16SStefano Zampini 6424fad6a16SStefano Zampini PetscFunctionBegin; 6434fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6442b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,k,2); 6454fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 6464fad6a16SStefano Zampini PetscFunctionReturn(0); 6474fad6a16SStefano Zampini } 6482b510759SStefano Zampini 649b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */ 650b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg) 651b8ffe317SStefano Zampini { 652b8ffe317SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 653b8ffe317SStefano Zampini 654b8ffe317SStefano Zampini PetscFunctionBegin; 65585c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = flg; 656b8ffe317SStefano Zampini PetscFunctionReturn(0); 657b8ffe317SStefano Zampini } 658b8ffe317SStefano Zampini 659b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg) 6602b510759SStefano Zampini { 6612b510759SStefano Zampini PetscErrorCode ierr; 6622b510759SStefano Zampini 6632b510759SStefano Zampini PetscFunctionBegin; 6642b510759SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 665b8ffe317SStefano Zampini PetscValidLogicalCollectiveBool(pc,flg,2); 666b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr); 6672b510759SStefano Zampini PetscFunctionReturn(0); 6682b510759SStefano Zampini } 6691e6b0712SBarry Smith 6702b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level) 6714fad6a16SStefano Zampini { 6724fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6734fad6a16SStefano Zampini 6744fad6a16SStefano Zampini PetscFunctionBegin; 6752b510759SStefano Zampini pcbddc->current_level = level; 6764fad6a16SStefano Zampini PetscFunctionReturn(0); 6774fad6a16SStefano Zampini } 6781e6b0712SBarry Smith 679b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 680b8ffe317SStefano Zampini { 681b8ffe317SStefano Zampini PetscErrorCode ierr; 682b8ffe317SStefano Zampini 683b8ffe317SStefano Zampini PetscFunctionBegin; 684b8ffe317SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 685b8ffe317SStefano Zampini PetscValidLogicalCollectiveInt(pc,level,2); 686b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr); 687b8ffe317SStefano Zampini PetscFunctionReturn(0); 688b8ffe317SStefano Zampini } 689b8ffe317SStefano Zampini 6902b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels) 6912b510759SStefano Zampini { 6922b510759SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6932b510759SStefano Zampini 6942b510759SStefano Zampini PetscFunctionBegin; 6956080607fSStefano Zampini if (levels > PETSC_PCBDDC_MAXLEVELS-1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Maximum number of additional levels for BDDC is %d",PETSC_PCBDDC_MAXLEVELS-1); 6962b510759SStefano Zampini pcbddc->max_levels = levels; 6972b510759SStefano Zampini PetscFunctionReturn(0); 6982b510759SStefano Zampini } 6992b510759SStefano Zampini 7004fad6a16SStefano Zampini /*@ 70137ebbdf7SStefano Zampini PCBDDCSetLevels - Sets the maximum number of additional levels allowed for multilevel BDDC 7024fad6a16SStefano Zampini 7034fad6a16SStefano Zampini Logically collective on PC 7044fad6a16SStefano Zampini 7054fad6a16SStefano Zampini Input Parameters: 7064fad6a16SStefano Zampini + pc - the preconditioning context 70737ebbdf7SStefano Zampini - levels - the maximum number of levels 7084fad6a16SStefano Zampini 7090f202f7eSStefano Zampini Options Database Keys: 7100f202f7eSStefano Zampini . -pc_bddc_levels 7114fad6a16SStefano Zampini 7124fad6a16SStefano Zampini Level: intermediate 7134fad6a16SStefano Zampini 7144fad6a16SStefano Zampini Notes: 71537ebbdf7SStefano Zampini The default value is 0, that gives the classical two-levels BDDC 7164fad6a16SStefano Zampini 7170f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetCoarseningRatio() 7184fad6a16SStefano Zampini @*/ 7192b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels) 7204fad6a16SStefano Zampini { 7214fad6a16SStefano Zampini PetscErrorCode ierr; 7224fad6a16SStefano Zampini 7234fad6a16SStefano Zampini PetscFunctionBegin; 7244fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 7252b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,levels,2); 7262b510759SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr); 7274fad6a16SStefano Zampini PetscFunctionReturn(0); 7284fad6a16SStefano Zampini } 7291e6b0712SBarry Smith 7303b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 7313b03a366Sstefano_zampini { 7323b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 73356282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 7343b03a366Sstefano_zampini PetscErrorCode ierr; 7353b03a366Sstefano_zampini 7363b03a366Sstefano_zampini PetscFunctionBegin; 73756282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 73856282151SStefano Zampini if (pcbddc->DirichletBoundaries) { 73956282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundaries,&isequal);CHKERRQ(ierr); 74056282151SStefano Zampini } 741785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 742785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 7433b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 74436e030ebSStefano Zampini pcbddc->DirichletBoundaries = DirichletBoundaries; 74556282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7463b03a366Sstefano_zampini PetscFunctionReturn(0); 7473b03a366Sstefano_zampini } 7481e6b0712SBarry Smith 7493b03a366Sstefano_zampini /*@ 75028509bceSStefano Zampini PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem. 7513b03a366Sstefano_zampini 752785d1243SStefano Zampini Collective 7533b03a366Sstefano_zampini 7543b03a366Sstefano_zampini Input Parameters: 7553b03a366Sstefano_zampini + pc - the preconditioning context 756785d1243SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries 7573b03a366Sstefano_zampini 7583b03a366Sstefano_zampini Level: intermediate 7593b03a366Sstefano_zampini 7600f202f7eSStefano Zampini Notes: 7610f202f7eSStefano Zampini Provide the information if you used MatZeroRows/Columns routines. Any process can list any global node 7623b03a366Sstefano_zampini 7630f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundariesLocal(), MatZeroRows(), MatZeroRowsColumns() 7643b03a366Sstefano_zampini @*/ 7653b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 7663b03a366Sstefano_zampini { 7673b03a366Sstefano_zampini PetscErrorCode ierr; 7683b03a366Sstefano_zampini 7693b03a366Sstefano_zampini PetscFunctionBegin; 7703b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 771674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 772785d1243SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 7733b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 7743b03a366Sstefano_zampini PetscFunctionReturn(0); 7753b03a366Sstefano_zampini } 7761e6b0712SBarry Smith 77782ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries) 7783b03a366Sstefano_zampini { 7793b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 78056282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 7813b03a366Sstefano_zampini PetscErrorCode ierr; 7823b03a366Sstefano_zampini 7833b03a366Sstefano_zampini PetscFunctionBegin; 78456282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 78556282151SStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 78656282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundariesLocal,&isequal);CHKERRQ(ierr); 78756282151SStefano Zampini } 788785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 789785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 7903b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 791785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = DirichletBoundaries; 79256282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7933b03a366Sstefano_zampini PetscFunctionReturn(0); 7943b03a366Sstefano_zampini } 7953b03a366Sstefano_zampini 7963b03a366Sstefano_zampini /*@ 79782ba6b80SStefano Zampini PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering. 7983b03a366Sstefano_zampini 799785d1243SStefano Zampini Collective 8003b03a366Sstefano_zampini 8013b03a366Sstefano_zampini Input Parameters: 8023b03a366Sstefano_zampini + pc - the preconditioning context 80382ba6b80SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering) 8043b03a366Sstefano_zampini 8053b03a366Sstefano_zampini Level: intermediate 8063b03a366Sstefano_zampini 8073b03a366Sstefano_zampini Notes: 8083b03a366Sstefano_zampini 8090f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundaries(), MatZeroRows(), MatZeroRowsColumns() 8103b03a366Sstefano_zampini @*/ 81182ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries) 8123b03a366Sstefano_zampini { 8133b03a366Sstefano_zampini PetscErrorCode ierr; 8143b03a366Sstefano_zampini 8153b03a366Sstefano_zampini PetscFunctionBegin; 8163b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 8173b03a366Sstefano_zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 81882ba6b80SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 81982ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 8203b03a366Sstefano_zampini PetscFunctionReturn(0); 8213b03a366Sstefano_zampini } 8223b03a366Sstefano_zampini 82353cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 8240c7d97c5SJed Brown { 8250c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 82656282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 82753cdbc3dSStefano Zampini PetscErrorCode ierr; 8280c7d97c5SJed Brown 8290c7d97c5SJed Brown PetscFunctionBegin; 83056282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 83156282151SStefano Zampini if (pcbddc->NeumannBoundaries) { 83256282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundaries,&isequal);CHKERRQ(ierr); 83356282151SStefano Zampini } 834785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 835785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 83653cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 83736e030ebSStefano Zampini pcbddc->NeumannBoundaries = NeumannBoundaries; 83856282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 8390c7d97c5SJed Brown PetscFunctionReturn(0); 8400c7d97c5SJed Brown } 8411e6b0712SBarry Smith 84257527edcSJed Brown /*@ 84328509bceSStefano Zampini PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem. 84457527edcSJed Brown 845785d1243SStefano Zampini Collective 84657527edcSJed Brown 84757527edcSJed Brown Input Parameters: 84857527edcSJed Brown + pc - the preconditioning context 849785d1243SStefano Zampini - NeumannBoundaries - parallel IS defining the Neumann boundaries 85057527edcSJed Brown 85157527edcSJed Brown Level: intermediate 85257527edcSJed Brown 8530f202f7eSStefano Zampini Notes: 8540f202f7eSStefano Zampini Any process can list any global node 85557527edcSJed Brown 8560f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundariesLocal() 85757527edcSJed Brown @*/ 85853cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 8590c7d97c5SJed Brown { 8600c7d97c5SJed Brown PetscErrorCode ierr; 8610c7d97c5SJed Brown 8620c7d97c5SJed Brown PetscFunctionBegin; 8630c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 864674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 865785d1243SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 86653cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 86753cdbc3dSStefano Zampini PetscFunctionReturn(0); 86853cdbc3dSStefano Zampini } 8691e6b0712SBarry Smith 87082ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries) 8710c7d97c5SJed Brown { 8720c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 87356282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 8740c7d97c5SJed Brown PetscErrorCode ierr; 8750c7d97c5SJed Brown 8760c7d97c5SJed Brown PetscFunctionBegin; 87756282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 87856282151SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 87956282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundariesLocal,&isequal);CHKERRQ(ierr); 88056282151SStefano Zampini } 881785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 882785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 8830c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 884785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = NeumannBoundaries; 88556282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 8860c7d97c5SJed Brown PetscFunctionReturn(0); 8870c7d97c5SJed Brown } 8880c7d97c5SJed Brown 8890c7d97c5SJed Brown /*@ 89082ba6b80SStefano Zampini PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering. 8910c7d97c5SJed Brown 892785d1243SStefano Zampini Collective 8930c7d97c5SJed Brown 8940c7d97c5SJed Brown Input Parameters: 8950c7d97c5SJed Brown + pc - the preconditioning context 89682ba6b80SStefano Zampini - NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering) 8970c7d97c5SJed Brown 8980c7d97c5SJed Brown Level: intermediate 8990c7d97c5SJed Brown 9000c7d97c5SJed Brown Notes: 9010c7d97c5SJed Brown 9020f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundaries() 9030c7d97c5SJed Brown @*/ 90482ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries) 9050c7d97c5SJed Brown { 9060c7d97c5SJed Brown PetscErrorCode ierr; 9070c7d97c5SJed Brown 9080c7d97c5SJed Brown PetscFunctionBegin; 9090c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 9100c7d97c5SJed Brown PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 91182ba6b80SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 91282ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 91353cdbc3dSStefano Zampini PetscFunctionReturn(0); 91453cdbc3dSStefano Zampini } 91553cdbc3dSStefano Zampini 916da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 917da1bb401SStefano Zampini { 918da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 919da1bb401SStefano Zampini 920da1bb401SStefano Zampini PetscFunctionBegin; 921da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 922da1bb401SStefano Zampini PetscFunctionReturn(0); 923da1bb401SStefano Zampini } 9241e6b0712SBarry Smith 925da1bb401SStefano Zampini /*@ 926785d1243SStefano Zampini PCBDDCGetDirichletBoundaries - Get parallel IS for Dirichlet boundaries 927da1bb401SStefano Zampini 928785d1243SStefano Zampini Collective 929785d1243SStefano Zampini 930785d1243SStefano Zampini Input Parameters: 931785d1243SStefano Zampini . pc - the preconditioning context 932785d1243SStefano Zampini 933785d1243SStefano Zampini Output Parameters: 934785d1243SStefano Zampini . DirichletBoundaries - index set defining the Dirichlet boundaries 935785d1243SStefano Zampini 936785d1243SStefano Zampini Level: intermediate 937785d1243SStefano Zampini 9380f202f7eSStefano Zampini Notes: 9390f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetDirichletBoundaries 940785d1243SStefano Zampini 941785d1243SStefano Zampini .seealso: PCBDDC 942785d1243SStefano Zampini @*/ 943785d1243SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 944785d1243SStefano Zampini { 945785d1243SStefano Zampini PetscErrorCode ierr; 946785d1243SStefano Zampini 947785d1243SStefano Zampini PetscFunctionBegin; 948785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 949785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 950785d1243SStefano Zampini PetscFunctionReturn(0); 951785d1243SStefano Zampini } 952785d1243SStefano Zampini 953785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries) 954785d1243SStefano Zampini { 955785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 956785d1243SStefano Zampini 957785d1243SStefano Zampini PetscFunctionBegin; 958785d1243SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundariesLocal; 959785d1243SStefano Zampini PetscFunctionReturn(0); 960785d1243SStefano Zampini } 961785d1243SStefano Zampini 962da1bb401SStefano Zampini /*@ 96382ba6b80SStefano Zampini PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering) 964da1bb401SStefano Zampini 965785d1243SStefano Zampini Collective 966da1bb401SStefano Zampini 967da1bb401SStefano Zampini Input Parameters: 96828509bceSStefano Zampini . pc - the preconditioning context 969da1bb401SStefano Zampini 970da1bb401SStefano Zampini Output Parameters: 97128509bceSStefano Zampini . DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 972da1bb401SStefano Zampini 973da1bb401SStefano Zampini Level: intermediate 974da1bb401SStefano Zampini 975da1bb401SStefano Zampini Notes: 9760f202f7eSStefano 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). 9770f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 978da1bb401SStefano Zampini 979da1bb401SStefano Zampini .seealso: PCBDDC 980da1bb401SStefano Zampini @*/ 98182ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries) 982da1bb401SStefano Zampini { 983da1bb401SStefano Zampini PetscErrorCode ierr; 984da1bb401SStefano Zampini 985da1bb401SStefano Zampini PetscFunctionBegin; 986da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 98782ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 988da1bb401SStefano Zampini PetscFunctionReturn(0); 989da1bb401SStefano Zampini } 9901e6b0712SBarry Smith 99153cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 99253cdbc3dSStefano Zampini { 99353cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 99453cdbc3dSStefano Zampini 99553cdbc3dSStefano Zampini PetscFunctionBegin; 99653cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 99753cdbc3dSStefano Zampini PetscFunctionReturn(0); 99853cdbc3dSStefano Zampini } 9991e6b0712SBarry Smith 100053cdbc3dSStefano Zampini /*@ 1001785d1243SStefano Zampini PCBDDCGetNeumannBoundaries - Get parallel IS for Neumann boundaries 100253cdbc3dSStefano Zampini 1003785d1243SStefano Zampini Collective 1004785d1243SStefano Zampini 1005785d1243SStefano Zampini Input Parameters: 1006785d1243SStefano Zampini . pc - the preconditioning context 1007785d1243SStefano Zampini 1008785d1243SStefano Zampini Output Parameters: 1009785d1243SStefano Zampini . NeumannBoundaries - index set defining the Neumann boundaries 1010785d1243SStefano Zampini 1011785d1243SStefano Zampini Level: intermediate 1012785d1243SStefano Zampini 10130f202f7eSStefano Zampini Notes: 10140f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetNeumannBoundaries 1015785d1243SStefano Zampini 1016785d1243SStefano Zampini .seealso: PCBDDC 1017785d1243SStefano Zampini @*/ 1018785d1243SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 1019785d1243SStefano Zampini { 1020785d1243SStefano Zampini PetscErrorCode ierr; 1021785d1243SStefano Zampini 1022785d1243SStefano Zampini PetscFunctionBegin; 1023785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1024785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 1025785d1243SStefano Zampini PetscFunctionReturn(0); 1026785d1243SStefano Zampini } 1027785d1243SStefano Zampini 1028785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries) 1029785d1243SStefano Zampini { 1030785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1031785d1243SStefano Zampini 1032785d1243SStefano Zampini PetscFunctionBegin; 1033785d1243SStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundariesLocal; 1034785d1243SStefano Zampini PetscFunctionReturn(0); 1035785d1243SStefano Zampini } 1036785d1243SStefano Zampini 103753cdbc3dSStefano Zampini /*@ 103882ba6b80SStefano Zampini PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering) 103953cdbc3dSStefano Zampini 1040785d1243SStefano Zampini Collective 104153cdbc3dSStefano Zampini 104253cdbc3dSStefano Zampini Input Parameters: 104328509bceSStefano Zampini . pc - the preconditioning context 104453cdbc3dSStefano Zampini 104553cdbc3dSStefano Zampini Output Parameters: 104628509bceSStefano Zampini . NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 104753cdbc3dSStefano Zampini 104853cdbc3dSStefano Zampini Level: intermediate 104953cdbc3dSStefano Zampini 105053cdbc3dSStefano Zampini Notes: 10510f202f7eSStefano 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). 10520f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 105353cdbc3dSStefano Zampini 105453cdbc3dSStefano Zampini .seealso: PCBDDC 105553cdbc3dSStefano Zampini @*/ 105682ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries) 105753cdbc3dSStefano Zampini { 105853cdbc3dSStefano Zampini PetscErrorCode ierr; 105953cdbc3dSStefano Zampini 106053cdbc3dSStefano Zampini PetscFunctionBegin; 106153cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 106282ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 10630c7d97c5SJed Brown PetscFunctionReturn(0); 10640c7d97c5SJed Brown } 10651e6b0712SBarry Smith 10661a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 106736e030ebSStefano Zampini { 106836e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1069da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 107056282151SStefano Zampini PetscBool same_data = PETSC_FALSE; 1071da1bb401SStefano Zampini PetscErrorCode ierr; 107236e030ebSStefano Zampini 107336e030ebSStefano Zampini PetscFunctionBegin; 10748687889aSStefano Zampini if (!nvtxs) { 107504194a47SStefano Zampini if (copymode == PETSC_OWN_POINTER) { 107604194a47SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 107704194a47SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 107804194a47SStefano Zampini } 10798687889aSStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 10808687889aSStefano Zampini PetscFunctionReturn(0); 10818687889aSStefano Zampini } 108266da6bd7Sstefano_zampini if (mat_graph->nvtxs == nvtxs && mat_graph->freecsr) { /* we own the data */ 108356282151SStefano Zampini if (mat_graph->xadj == xadj && mat_graph->adjncy == adjncy) same_data = PETSC_TRUE; 108456282151SStefano Zampini if (!same_data && mat_graph->xadj[nvtxs] == xadj[nvtxs]) { 1085580bdb30SBarry Smith ierr = PetscArraycmp(xadj,mat_graph->xadj,nvtxs+1,&same_data);CHKERRQ(ierr); 10862d505d7fSStefano Zampini if (same_data) { 1087580bdb30SBarry Smith ierr = PetscArraycmp(adjncy,mat_graph->adjncy,xadj[nvtxs],&same_data);CHKERRQ(ierr); 10882d505d7fSStefano Zampini } 108956282151SStefano Zampini } 109056282151SStefano Zampini } 109156282151SStefano Zampini if (!same_data) { 1092674ae819SStefano Zampini /* free old CSR */ 1093674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 1094674ae819SStefano Zampini /* get CSR into graph structure */ 1095da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 1096854ce69bSBarry Smith ierr = PetscMalloc1(nvtxs+1,&mat_graph->xadj);CHKERRQ(ierr); 1097785e854fSJed Brown ierr = PetscMalloc1(xadj[nvtxs],&mat_graph->adjncy);CHKERRQ(ierr); 1098580bdb30SBarry Smith ierr = PetscArraycpy(mat_graph->xadj,xadj,nvtxs+1);CHKERRQ(ierr); 1099580bdb30SBarry Smith ierr = PetscArraycpy(mat_graph->adjncy,adjncy,xadj[nvtxs]);CHKERRQ(ierr); 1100a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 1101da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 11021a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 11031a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 1104a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 1105a1dbd327SStefano Zampini } else if (copymode == PETSC_USE_POINTER) { 1106a1dbd327SStefano Zampini mat_graph->xadj = (PetscInt*)xadj; 1107a1dbd327SStefano Zampini mat_graph->adjncy = (PetscInt*)adjncy; 1108a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_FALSE; 1109e0fe2d75SToby Isaac } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %D",copymode); 1110575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 111156282151SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 111256282151SStefano Zampini } 111336e030ebSStefano Zampini PetscFunctionReturn(0); 111436e030ebSStefano Zampini } 11151e6b0712SBarry Smith 111636e030ebSStefano Zampini /*@ 111754fffbccSStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local degrees of freedom. 111836e030ebSStefano Zampini 111936e030ebSStefano Zampini Not collective 112036e030ebSStefano Zampini 112136e030ebSStefano Zampini Input Parameters: 112254fffbccSStefano Zampini + pc - the preconditioning context. 112354fffbccSStefano Zampini . nvtxs - number of local vertices of the graph (i.e., the number of local dofs). 112454fffbccSStefano Zampini . xadj, adjncy - the connectivity of the dofs in CSR format. 112554fffbccSStefano Zampini - copymode - supported modes are PETSC_COPY_VALUES, PETSC_USE_POINTER or PETSC_OWN_POINTER. 112636e030ebSStefano Zampini 112736e030ebSStefano Zampini Level: intermediate 112836e030ebSStefano Zampini 112995452b02SPatrick Sanan Notes: 113095452b02SPatrick Sanan A dof is considered connected with all local dofs if xadj[dof+1]-xadj[dof] == 1 and adjncy[xadj[dof]] is negative. 113136e030ebSStefano Zampini 113228509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode 113336e030ebSStefano Zampini @*/ 11341a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 113536e030ebSStefano Zampini { 1136575ad6abSStefano Zampini void (*f)(void) = 0; 113736e030ebSStefano Zampini PetscErrorCode ierr; 113836e030ebSStefano Zampini 113936e030ebSStefano Zampini PetscFunctionBegin; 114036e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 11418687889aSStefano Zampini if (nvtxs) { 1142674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 11431633d1f0SStefano Zampini if (xadj[nvtxs]) PetscValidIntPointer(adjncy,4); 11448687889aSStefano Zampini } 11451a83f524SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 1146575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 1147575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 1148575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 1149575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 1150575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 1151da1bb401SStefano Zampini } 115236e030ebSStefano Zampini PetscFunctionReturn(0); 115336e030ebSStefano Zampini } 11541e6b0712SBarry Smith 115563602bcaSStefano Zampini static PetscErrorCode PCBDDCSetDofsSplittingLocal_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 115663602bcaSStefano Zampini { 115763602bcaSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 115863602bcaSStefano Zampini PetscInt i; 115956282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 116063602bcaSStefano Zampini PetscErrorCode ierr; 116163602bcaSStefano Zampini 116263602bcaSStefano Zampini PetscFunctionBegin; 116356282151SStefano Zampini if (pcbddc->n_ISForDofsLocal == n_is) { 116456282151SStefano Zampini for (i=0;i<n_is;i++) { 116556282151SStefano Zampini PetscBool isequalt; 116656282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofsLocal[i],&isequalt);CHKERRQ(ierr); 116756282151SStefano Zampini if (!isequalt) break; 116856282151SStefano Zampini } 116956282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 117056282151SStefano Zampini } 117156282151SStefano Zampini for (i=0;i<n_is;i++) { 117256282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 117356282151SStefano Zampini } 117463602bcaSStefano Zampini /* Destroy ISes if they were already set */ 117563602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 117663602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 117763602bcaSStefano Zampini } 117863602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 117963602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 118063602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 118163602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 118263602bcaSStefano Zampini } 118363602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 118463602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 118563602bcaSStefano Zampini /* allocate space then set */ 1186d02579f5SStefano Zampini if (n_is) { 1187d02579f5SStefano Zampini ierr = PetscMalloc1(n_is,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1188d02579f5SStefano Zampini } 118963602bcaSStefano Zampini for (i=0;i<n_is;i++) { 119063602bcaSStefano Zampini pcbddc->ISForDofsLocal[i] = ISForDofs[i]; 119163602bcaSStefano Zampini } 119263602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = n_is; 119363602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 119456282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 119563602bcaSStefano Zampini PetscFunctionReturn(0); 119663602bcaSStefano Zampini } 119763602bcaSStefano Zampini 119863602bcaSStefano Zampini /*@ 119963602bcaSStefano Zampini PCBDDCSetDofsSplittingLocal - Set index sets defining fields of the local subdomain matrix 120063602bcaSStefano Zampini 120163602bcaSStefano Zampini Collective 120263602bcaSStefano Zampini 120363602bcaSStefano Zampini Input Parameters: 120463602bcaSStefano Zampini + pc - the preconditioning context 12050f202f7eSStefano Zampini . n_is - number of index sets defining the fields 12060f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in local ordering 120763602bcaSStefano Zampini 120863602bcaSStefano Zampini Level: intermediate 120963602bcaSStefano Zampini 12100f202f7eSStefano Zampini Notes: 12110f202f7eSStefano Zampini n_is should be the same among processes. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 121263602bcaSStefano Zampini 121363602bcaSStefano Zampini .seealso: PCBDDC 121463602bcaSStefano Zampini @*/ 121563602bcaSStefano Zampini PetscErrorCode PCBDDCSetDofsSplittingLocal(PC pc,PetscInt n_is, IS ISForDofs[]) 121663602bcaSStefano Zampini { 121763602bcaSStefano Zampini PetscInt i; 121863602bcaSStefano Zampini PetscErrorCode ierr; 121963602bcaSStefano Zampini 122063602bcaSStefano Zampini PetscFunctionBegin; 122163602bcaSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 122263602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 122363602bcaSStefano Zampini for (i=0;i<n_is;i++) { 122463602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 122563602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 122663602bcaSStefano Zampini } 1227e71e7a71SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplittingLocal_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 122863602bcaSStefano Zampini PetscFunctionReturn(0); 122963602bcaSStefano Zampini } 123063602bcaSStefano Zampini 12319c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 12329c0446d6SStefano Zampini { 12339c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 12349c0446d6SStefano Zampini PetscInt i; 123556282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 12369c0446d6SStefano Zampini PetscErrorCode ierr; 12379c0446d6SStefano Zampini 12389c0446d6SStefano Zampini PetscFunctionBegin; 123956282151SStefano Zampini if (pcbddc->n_ISForDofs == n_is) { 124056282151SStefano Zampini for (i=0;i<n_is;i++) { 124156282151SStefano Zampini PetscBool isequalt; 124256282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofs[i],&isequalt);CHKERRQ(ierr); 124356282151SStefano Zampini if (!isequalt) break; 124456282151SStefano Zampini } 124556282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 124656282151SStefano Zampini } 124756282151SStefano Zampini for (i=0;i<n_is;i++) { 124856282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 124956282151SStefano Zampini } 1250da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 12519c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 12529c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 12539c0446d6SStefano Zampini } 1254d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 125563602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 125663602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 125763602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 125863602bcaSStefano Zampini } 125963602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 126063602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 1261da1bb401SStefano Zampini /* allocate space then set */ 1262d02579f5SStefano Zampini if (n_is) { 1263785e854fSJed Brown ierr = PetscMalloc1(n_is,&pcbddc->ISForDofs);CHKERRQ(ierr); 1264d02579f5SStefano Zampini } 12659c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 1266da1bb401SStefano Zampini pcbddc->ISForDofs[i] = ISForDofs[i]; 12679c0446d6SStefano Zampini } 12689c0446d6SStefano Zampini pcbddc->n_ISForDofs = n_is; 126963602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 127056282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 12719c0446d6SStefano Zampini PetscFunctionReturn(0); 12729c0446d6SStefano Zampini } 12731e6b0712SBarry Smith 12749c0446d6SStefano Zampini /*@ 127563602bcaSStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of the global matrix 12769c0446d6SStefano Zampini 127763602bcaSStefano Zampini Collective 12789c0446d6SStefano Zampini 12799c0446d6SStefano Zampini Input Parameters: 12809c0446d6SStefano Zampini + pc - the preconditioning context 12810f202f7eSStefano Zampini . n_is - number of index sets defining the fields 12820f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in global ordering 12839c0446d6SStefano Zampini 12849c0446d6SStefano Zampini Level: intermediate 12859c0446d6SStefano Zampini 12860f202f7eSStefano Zampini Notes: 12870f202f7eSStefano Zampini Any process can list any global node. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 12889c0446d6SStefano Zampini 12899c0446d6SStefano Zampini .seealso: PCBDDC 12909c0446d6SStefano Zampini @*/ 12919c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 12929c0446d6SStefano Zampini { 12932b510759SStefano Zampini PetscInt i; 12949c0446d6SStefano Zampini PetscErrorCode ierr; 12959c0446d6SStefano Zampini 12969c0446d6SStefano Zampini PetscFunctionBegin; 12979c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 129863602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 12992b510759SStefano Zampini for (i=0;i<n_is;i++) { 130063602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 1301a011d5a7Sstefano_zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 13022b510759SStefano Zampini } 13039c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 13049c0446d6SStefano Zampini PetscFunctionReturn(0); 13059c0446d6SStefano Zampini } 1306906d46d4SStefano Zampini 1307534831adSStefano Zampini /* 1308534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 1309534831adSStefano Zampini guess if a transformation of basis approach has been selected. 13109c0446d6SStefano Zampini 1311534831adSStefano Zampini Input Parameter: 1312534831adSStefano Zampini + pc - the preconditioner contex 1313534831adSStefano Zampini 1314534831adSStefano Zampini Application Interface Routine: PCPreSolve() 1315534831adSStefano Zampini 1316534831adSStefano Zampini Notes: 1317534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 1318534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1319534831adSStefano Zampini */ 1320534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1321534831adSStefano Zampini { 1322534831adSStefano Zampini PetscErrorCode ierr; 1323534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1324534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 13253972b0daSStefano Zampini Vec used_vec; 13264df7a6bfSStefano Zampini PetscBool iscg = PETSC_FALSE, save_rhs = PETSC_TRUE, benign_correction_computed; 1327534831adSStefano Zampini 1328534831adSStefano Zampini PetscFunctionBegin; 13291f4df5f7SStefano Zampini /* if we are working with CG, one dirichlet solve can be avoided during Krylov iterations */ 133085c4d303SStefano Zampini if (ksp) { 13314df7a6bfSStefano Zampini PetscBool isgroppcg, ispipecg, ispipelcg, ispipecgrr; 13324df7a6bfSStefano Zampini 133385c4d303SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr); 133427b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPGROPPCG,&isgroppcg);CHKERRQ(ierr); 133527b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECG,&ispipecg);CHKERRQ(ierr); 13364df7a6bfSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECG,&ispipelcg);CHKERRQ(ierr); 1337f94e96cbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECGRR,&ispipecgrr);CHKERRQ(ierr); 13384df7a6bfSStefano Zampini iscg = (PetscBool)(iscg || isgroppcg || ispipecg || ispipelcg || ispipecgrr); 13393bf6e316SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static || !iscg || pc->mat != pc->pmat) { 134085c4d303SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 134185c4d303SStefano Zampini } 134285c4d303SStefano Zampini } 13433bf6e316SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static || pc->mat != pc->pmat) { 1344fc17d649SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 1345fc17d649SStefano Zampini } 13461f4df5f7SStefano Zampini 134785c4d303SStefano Zampini /* Creates parallel work vectors used in presolve */ 134862a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 134962a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 135062a6ff1dSStefano Zampini } 135162a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 135262a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 135362a6ff1dSStefano Zampini } 13548d00608fSStefano Zampini 135527b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_FALSE; 13563972b0daSStefano Zampini if (x) { 13573972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 13583972b0daSStefano Zampini used_vec = x; 13598d00608fSStefano Zampini } else { /* it can only happen when calling PCBDDCMatFETIDPGetRHS */ 13603972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 13613972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 13623972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 136327b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 1364266e20e9SStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 1365266e20e9SStefano Zampini save_rhs = PETSC_FALSE; 1366266e20e9SStefano Zampini pcbddc->eliminate_dirdofs = PETSC_TRUE; 13673972b0daSStefano Zampini } 13688efcfb23SStefano Zampini 13698efcfb23SStefano Zampini /* hack into ksp data structure since PCPreSolve comes earlier than setting to zero the guess in src/ksp/ksp/interface/itfunc.c */ 13703972b0daSStefano Zampini if (ksp) { 1371a0cb1b98SStefano Zampini /* store the flag for the initial guess since it will be restored back during PCPostSolve_BDDC */ 13728efcfb23SStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 13738efcfb23SStefano Zampini if (!pcbddc->ksp_guess_nonzero) { 13743972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 13753972b0daSStefano Zampini } 13763972b0daSStefano Zampini } 13773308cffdSStefano Zampini 13788d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 13793972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 138070c64980SStefano Zampini if (rhs && pcbddc->eliminate_dirdofs) { 13813975b054SStefano Zampini IS dirIS = NULL; 13823975b054SStefano Zampini 1383a07ea27aSStefano Zampini /* DirichletBoundariesLocal may not be consistent among neighbours; gets a dirichlet dofs IS from graph (may be cached) */ 13843975b054SStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 13853975b054SStefano Zampini if (dirIS) { 1386906d46d4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1387785d1243SStefano Zampini PetscInt dirsize,i,*is_indices; 13882b095fd8SStefano Zampini PetscScalar *array_x; 13892b095fd8SStefano Zampini const PetscScalar *array_diagonal; 1390785d1243SStefano Zampini 13913972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 13923972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 1393e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1394e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1395e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1396e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 139782ba6b80SStefano Zampini ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr); 13983972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 13992b095fd8SStefano Zampini ierr = VecGetArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 14003972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 14012fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 14023972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 14032b095fd8SStefano Zampini ierr = VecRestoreArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 14043972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 1405e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1406e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 14078d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 14081b968477SStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 14098efcfb23SStefano Zampini } 1410a07ea27aSStefano Zampini } 1411b76ba322SStefano Zampini 14128efcfb23SStefano Zampini /* remove the computed solution or the initial guess from the rhs */ 14138d00608fSStefano Zampini if (pcbddc->rhs_change || (ksp && pcbddc->ksp_guess_nonzero) ) { 141427b6a85dSStefano Zampini /* save the original rhs */ 141527b6a85dSStefano Zampini if (save_rhs) { 141627b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 141727b6a85dSStefano Zampini save_rhs = PETSC_FALSE; 14188d00608fSStefano Zampini } 14198d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 14203972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 142127b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,used_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 14223972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 14238efcfb23SStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 142427b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 14257acc28cbSStefano Zampini if (ksp) { 14267acc28cbSStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_FALSE);CHKERRQ(ierr); 14277acc28cbSStefano Zampini } 14283308cffdSStefano Zampini } 14298efcfb23SStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 1430b76ba322SStefano Zampini 1431fc17d649SStefano Zampini /* compute initial vector in benign space if needed 143227b6a85dSStefano Zampini and remove non-benign solution from the rhs */ 143327b6a85dSStefano Zampini benign_correction_computed = PETSC_FALSE; 143408af2428SStefano Zampini if (rhs && pcbddc->benign_compute_correction && (pcbddc->benign_have_null || pcbddc->benign_apply_coarse_only)) { 14351f4df5f7SStefano Zampini /* compute u^*_h using ideas similar to those in Xuemin Tu's PhD thesis (see Section 4.8.1) 14361f4df5f7SStefano Zampini Recursively apply BDDC in the multilevel case */ 14370369aaf7SStefano Zampini if (!pcbddc->benign_vec) { 14380369aaf7SStefano Zampini ierr = VecDuplicate(rhs,&pcbddc->benign_vec);CHKERRQ(ierr); 14390369aaf7SStefano Zampini } 1440c69e9cc1SStefano Zampini /* keep applying coarse solver unless we no longer have benign subdomains */ 1441c69e9cc1SStefano Zampini pcbddc->benign_apply_coarse_only = pcbddc->benign_have_null ? PETSC_TRUE : PETSC_FALSE; 144227b6a85dSStefano Zampini if (!pcbddc->benign_skip_correction) { 14431dd7afcfSStefano Zampini ierr = PCApply_BDDC(pc,rhs,pcbddc->benign_vec);CHKERRQ(ierr); 14443bca92a6SStefano Zampini benign_correction_computed = PETSC_TRUE; 14451f4df5f7SStefano Zampini if (pcbddc->temp_solution_used) { 14461f4df5f7SStefano Zampini ierr = VecAXPY(pcbddc->temp_solution,1.0,pcbddc->benign_vec);CHKERRQ(ierr); 14471f4df5f7SStefano Zampini } 14481f4df5f7SStefano Zampini ierr = VecScale(pcbddc->benign_vec,-1.0);CHKERRQ(ierr); 144927b6a85dSStefano Zampini /* store the original rhs if not done earlier */ 145027b6a85dSStefano Zampini if (save_rhs) { 145127b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 145292e3dcfbSStefano Zampini } 145327b6a85dSStefano Zampini if (pcbddc->rhs_change) { 14540369aaf7SStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,rhs,rhs);CHKERRQ(ierr); 145527b6a85dSStefano Zampini } else { 145627b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 145727b6a85dSStefano Zampini } 14580369aaf7SStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 145927b6a85dSStefano Zampini } 146027b6a85dSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_FALSE; 14614df7a6bfSStefano Zampini } else { 14624df7a6bfSStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 14630369aaf7SStefano Zampini } 14642d4c4fecSStefano Zampini 14652d4c4fecSStefano Zampini /* dbg output */ 1466a198735bSStefano Zampini if (pcbddc->dbg_flag && benign_correction_computed) { 14671f4df5f7SStefano Zampini Vec v; 1468c69e9cc1SStefano Zampini 14691f4df5f7SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&v);CHKERRQ(ierr); 1470c69e9cc1SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 14711f4df5f7SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,v);CHKERRQ(ierr); 1472c69e9cc1SStefano Zampini } else { 1473c69e9cc1SStefano Zampini ierr = VecCopy(rhs,v);CHKERRQ(ierr); 1474c69e9cc1SStefano Zampini } 14751f4df5f7SStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,v,PETSC_TRUE);CHKERRQ(ierr); 1476e0fe2d75SToby Isaac ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"LEVEL %D: is the correction benign?\n",pcbddc->current_level);CHKERRQ(ierr); 1477c69e9cc1SStefano Zampini ierr = PetscScalarView(pcbddc->benign_n,pcbddc->benign_p0,pcbddc->dbg_viewer);CHKERRQ(ierr); 1478c69e9cc1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 14791f4df5f7SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 14801f4df5f7SStefano Zampini } 14810369aaf7SStefano Zampini 14820369aaf7SStefano Zampini /* set initial guess if using PCG */ 14838ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 14840369aaf7SStefano Zampini if (x && pcbddc->use_exact_dirichlet_trick) { 14850369aaf7SStefano Zampini ierr = VecSet(x,0.0);CHKERRQ(ierr); 14861dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 148727b6a85dSStefano Zampini if (benign_correction_computed) { /* we have already saved the changed rhs */ 14888860a134SJunchao Zhang ierr = VecLockReadPop(pcis->vec1_global);CHKERRQ(ierr); 14891dd7afcfSStefano Zampini } else { 14901dd7afcfSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,pcis->vec1_global);CHKERRQ(ierr); 14911dd7afcfSStefano Zampini } 14921dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14931dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14941dd7afcfSStefano Zampini } else { 14950369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14960369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14971dd7afcfSStefano Zampini } 14980369aaf7SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 1499c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 15001dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 15011dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.);CHKERRQ(ierr); 15021dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15031dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15041dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x);CHKERRQ(ierr); 15051dd7afcfSStefano Zampini } else { 15060369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15070369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15081dd7afcfSStefano Zampini } 15090369aaf7SStefano Zampini if (ksp) { 15100369aaf7SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 15110369aaf7SStefano Zampini } 15128ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_TRUE; 1513266e20e9SStefano Zampini } else if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior && benign_correction_computed && pcbddc->use_exact_dirichlet_trick) { 15148860a134SJunchao Zhang ierr = VecLockReadPop(pcis->vec1_global);CHKERRQ(ierr); 15150369aaf7SStefano Zampini } 1516534831adSStefano Zampini PetscFunctionReturn(0); 1517534831adSStefano Zampini } 1518906d46d4SStefano Zampini 1519534831adSStefano Zampini /* 1520534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 1521534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 1522534831adSStefano Zampini 1523534831adSStefano Zampini Input Parameter: 1524534831adSStefano Zampini + pc - the preconditioner contex 1525534831adSStefano Zampini 1526534831adSStefano Zampini Application Interface Routine: PCPostSolve() 1527534831adSStefano Zampini 1528534831adSStefano Zampini Notes: 1529534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 1530534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1531534831adSStefano Zampini */ 1532534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1533534831adSStefano Zampini { 1534534831adSStefano Zampini PetscErrorCode ierr; 1535534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1536534831adSStefano Zampini 1537534831adSStefano Zampini PetscFunctionBegin; 15383972b0daSStefano Zampini /* add solution removed in presolve */ 15396bcfc461SStefano Zampini if (x && pcbddc->rhs_change) { 154027b6a85dSStefano Zampini if (pcbddc->temp_solution_used) { 15413425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 1542af140850Sstefano_zampini } else if (pcbddc->benign_compute_correction && pcbddc->benign_vec) { 154327b6a85dSStefano Zampini ierr = VecAXPY(x,-1.0,pcbddc->benign_vec);CHKERRQ(ierr); 15443425bc38SStefano Zampini } 1545af140850Sstefano_zampini /* restore to original state (not for FETI-DP) */ 1546af140850Sstefano_zampini if (ksp) pcbddc->temp_solution_used = PETSC_FALSE; 154727b6a85dSStefano Zampini } 154827b6a85dSStefano Zampini 1549266e20e9SStefano Zampini /* restore rhs to its original state (not needed for FETI-DP) */ 15508d00608fSStefano Zampini if (rhs && pcbddc->rhs_change) { 155127b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 15528d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 1553af140850Sstefano_zampini } 15548efcfb23SStefano Zampini /* restore ksp guess state */ 15558efcfb23SStefano Zampini if (ksp) { 15568efcfb23SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 15578ae0ca82SStefano Zampini /* reset flag for exact dirichlet trick */ 15588ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 1559af140850Sstefano_zampini } 1560534831adSStefano Zampini PetscFunctionReturn(0); 1561534831adSStefano Zampini } 1562af140850Sstefano_zampini 15630c7d97c5SJed Brown /* 15640c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 15650c7d97c5SJed Brown by setting data structures and options. 15660c7d97c5SJed Brown 15670c7d97c5SJed Brown Input Parameter: 156853cdbc3dSStefano Zampini + pc - the preconditioner context 15690c7d97c5SJed Brown 15700c7d97c5SJed Brown Application Interface Routine: PCSetUp() 15710c7d97c5SJed Brown 15720c7d97c5SJed Brown Notes: 15730c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 15740c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 15750c7d97c5SJed Brown */ 157653cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 15770c7d97c5SJed Brown { 15780c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1579c703fcc7SStefano Zampini PCBDDCSubSchurs sub_schurs; 15805e8657edSStefano Zampini Mat_IS* matis; 158108122e43SStefano Zampini MatNullSpace nearnullspace; 158235509ce9Sstefano_zampini Mat lA; 158335509ce9Sstefano_zampini IS lP,zerodiag = NULL; 158491e8d312SStefano Zampini PetscInt nrows,ncols; 158586bfa4cfSStefano Zampini PetscMPIInt size; 1586c703fcc7SStefano Zampini PetscBool computesubschurs; 15878de1fae6SStefano Zampini PetscBool computeconstraintsmatrix; 15883b03f7bbSStefano Zampini PetscBool new_nearnullspace_provided,ismatis,rl; 1589c703fcc7SStefano Zampini PetscErrorCode ierr; 15900c7d97c5SJed Brown 15910c7d97c5SJed Brown PetscFunctionBegin; 15925e8657edSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATIS,&ismatis);CHKERRQ(ierr); 15936c4ed002SBarry Smith if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner requires matrix of type MATIS"); 159491e8d312SStefano Zampini ierr = MatGetSize(pc->pmat,&nrows,&ncols);CHKERRQ(ierr); 15956c4ed002SBarry Smith if (nrows != ncols) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PCBDDC preconditioner requires a square preconditioning matrix"); 159686bfa4cfSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 159786bfa4cfSStefano Zampini 15985e8657edSStefano Zampini matis = (Mat_IS*)pc->pmat->data; 1599f4ddd8eeSStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other future nonoverlapping preconditioners */ 16003b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 160171582508SStefano Zampini Also, BDDC builds its own KSP for the Dirichlet problem */ 16023b03f7bbSStefano Zampini rl = pcbddc->recompute_topography; 16033b03f7bbSStefano Zampini if (!pc->setupcalled || pc->flag == DIFFERENT_NONZERO_PATTERN) rl = PETSC_TRUE; 16043b03f7bbSStefano Zampini ierr = MPIU_Allreduce(&rl,&pcbddc->recompute_topography,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1605c83e1ba7SStefano Zampini if (pcbddc->recompute_topography) { 1606c83e1ba7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 1607c83e1ba7SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1608c83e1ba7SStefano Zampini } else { 16098de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_FALSE; 1610c83e1ba7SStefano Zampini } 1611b087196eSStefano Zampini 1612b087196eSStefano Zampini /* check parameters' compatibility */ 1613b7ab4a40SStefano Zampini if (!pcbddc->use_deluxe_scaling) pcbddc->deluxe_zerorows = PETSC_FALSE; 1614bd2a564bSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_threshold[0] != 0.0 || pcbddc->adaptive_threshold[1] != 0.0); 161586bfa4cfSStefano Zampini pcbddc->use_deluxe_scaling = (PetscBool)(pcbddc->use_deluxe_scaling && size > 1); 161686bfa4cfSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_selection && size > 1); 1617bf3a8328SStefano Zampini pcbddc->adaptive_userdefined = (PetscBool)(pcbddc->adaptive_selection && pcbddc->adaptive_userdefined); 1618862806e4SStefano Zampini if (pcbddc->adaptive_selection) pcbddc->use_faces = PETSC_TRUE; 1619862806e4SStefano Zampini 16205a95e1ceSStefano Zampini computesubschurs = (PetscBool)(pcbddc->adaptive_selection || pcbddc->use_deluxe_scaling); 162116909a7fSStefano Zampini 162271582508SStefano Zampini /* activate all connected components if the netflux has been requested */ 1623bb05f991SStefano Zampini if (pcbddc->compute_nonetflux) { 1624bb05f991SStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 1625bb05f991SStefano Zampini pcbddc->use_edges = PETSC_TRUE; 1626bb05f991SStefano Zampini pcbddc->use_faces = PETSC_TRUE; 1627bb05f991SStefano Zampini } 1628bb05f991SStefano Zampini 1629f4ddd8eeSStefano Zampini /* Get stdout for dbg */ 163070cf5478SStefano Zampini if (pcbddc->dbg_flag) { 163170cf5478SStefano Zampini if (!pcbddc->dbg_viewer) { 163258a03d70SStefano Zampini pcbddc->dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pc)); 1633f4ddd8eeSStefano Zampini } 1634d9869140SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 163558a03d70SStefano Zampini ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1636f4ddd8eeSStefano Zampini } 1637f4ddd8eeSStefano Zampini 1638c703fcc7SStefano Zampini /* process topology information */ 163943371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Topology[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 164071582508SStefano Zampini if (pcbddc->recompute_topography) { 164171582508SStefano Zampini ierr = PCBDDCComputeLocalTopologyInfo(pc);CHKERRQ(ierr); 1642c703fcc7SStefano Zampini if (pcbddc->discretegradient) { 1643a13144ffSStefano Zampini ierr = PCBDDCNedelecSupport(pc);CHKERRQ(ierr); 1644a13144ffSStefano Zampini } 1645c703fcc7SStefano Zampini } 16464f819b78SStefano Zampini if (pcbddc->corner_selected) pcbddc->use_vertices = PETSC_TRUE; 1647a13144ffSStefano Zampini 1648c703fcc7SStefano Zampini /* change basis if requested by the user */ 16495e8657edSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 16505e8657edSStefano Zampini /* use_change_of_basis flag is used to automatically compute a change of basis from constraints */ 16515e8657edSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 16525e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 16535e8657edSStefano Zampini } else { 1654b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 16555e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 16565e8657edSStefano Zampini pcbddc->local_mat = matis->A; 1657d16cbb6bSStefano Zampini } 1658d16cbb6bSStefano Zampini 16594f1b2e48SStefano Zampini /* 1660c703fcc7SStefano Zampini Compute change of basis on local pressures (aka zerodiag dofs) with the benign trick 16614f1b2e48SStefano Zampini This should come earlier then PCISSetUp for extracting the correct subdomain matrices 16624f1b2e48SStefano Zampini */ 16631dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 1664d16cbb6bSStefano Zampini if (pcbddc->benign_saddle_point) { 16659f47a83aSStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 16669f47a83aSStefano Zampini 166705b28244SStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->use_change_of_basis || !computesubschurs) pcbddc->benign_change_explicit = PETSC_TRUE; 16683b03f7bbSStefano Zampini /* detect local saddle point and change the basis in pcbddc->local_mat */ 16693b03f7bbSStefano Zampini ierr = PCBDDCBenignDetectSaddlePoint(pc,(PetscBool)(!pcbddc->recompute_topography),&zerodiag);CHKERRQ(ierr); 1670a3df083aSStefano Zampini /* pop B0 mat from local mat */ 1671c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 16721dd7afcfSStefano Zampini /* give pcis a hint to not reuse submatrices during PCISCreate */ 16731dd7afcfSStefano Zampini if (pc->flag == SAME_NONZERO_PATTERN && pcis->reusesubmatrices == PETSC_TRUE) { 16741dd7afcfSStefano Zampini if (pcbddc->benign_n && (pcbddc->benign_change_explicit || pcbddc->dbg_flag)) { 16751dd7afcfSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 16761dd7afcfSStefano Zampini } else { 1677a3df083aSStefano Zampini pcis->reusesubmatrices = PETSC_TRUE; 16781dd7afcfSStefano Zampini } 1679a3df083aSStefano Zampini } else { 16809f47a83aSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 1681674ae819SStefano Zampini } 1682a3df083aSStefano Zampini } 168327b6a85dSStefano Zampini 16848037d520SStefano Zampini /* propagate relevant information */ 168506a4e24aSStefano Zampini if (matis->A->symmetric_set) { 168606a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 168706a4e24aSStefano Zampini } 168806a4e24aSStefano Zampini if (matis->A->spd_set) { 168906a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SPD,matis->A->spd);CHKERRQ(ierr); 169006a4e24aSStefano Zampini } 1691e496cd5dSStefano Zampini 16925e8657edSStefano Zampini /* Set up all the "iterative substructuring" common block without computing solvers */ 16935e8657edSStefano Zampini { 16945e8657edSStefano Zampini Mat temp_mat; 16955e8657edSStefano Zampini 16965e8657edSStefano Zampini temp_mat = matis->A; 16975e8657edSStefano Zampini matis->A = pcbddc->local_mat; 1698d9869140SStefano Zampini ierr = PCISSetUp(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 16995e8657edSStefano Zampini pcbddc->local_mat = matis->A; 17005e8657edSStefano Zampini matis->A = temp_mat; 17015e8657edSStefano Zampini } 1702684f6988SStefano Zampini 170381d14e9dSStefano Zampini /* Analyze interface */ 170464ac59b8SStefano Zampini if (!pcbddc->graphanalyzed) { 1705674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 17068de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1707345ecf6cSStefano Zampini if (pcbddc->adaptive_selection && !pcbddc->use_deluxe_scaling && !pcbddc->mat_graph->twodim) { 17084247aa23Sstefano_zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot compute the adaptive primal space for a problem with 3D edges without deluxe scaling"); 1709345ecf6cSStefano Zampini } 1710a198735bSStefano Zampini if (pcbddc->compute_nonetflux) { 1711669cc0f4SStefano Zampini MatNullSpace nnfnnsp; 1712669cc0f4SStefano Zampini 171321ef3d20SStefano Zampini if (!pcbddc->divudotp) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Missing divudotp operator"); 17148ae0ca82SStefano Zampini ierr = PCBDDCComputeNoNetFlux(pc->pmat,pcbddc->divudotp,pcbddc->divudotp_trans,pcbddc->divudotp_vl2l,pcbddc->mat_graph,&nnfnnsp);CHKERRQ(ierr); 171571582508SStefano Zampini /* TODO what if a nearnullspace is already attached? */ 17168037d520SStefano Zampini if (nnfnnsp) { 1717669cc0f4SStefano Zampini ierr = MatSetNearNullSpace(pc->pmat,nnfnnsp);CHKERRQ(ierr); 1718669cc0f4SStefano Zampini ierr = MatNullSpaceDestroy(&nnfnnsp);CHKERRQ(ierr); 1719669cc0f4SStefano Zampini } 1720674ae819SStefano Zampini } 17218037d520SStefano Zampini } 172243371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Topology[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 1723fb8d54d4SStefano Zampini 17245408967cSStefano Zampini /* check existence of a divergence free extension, i.e. 17255408967cSStefano Zampini b(v_I,p_0) = 0 for all v_I (raise error if not). 17265408967cSStefano Zampini Also, check that PCBDDCBenignGetOrSetP0 works */ 1727ff1f7e73Sstefano_zampini if (pcbddc->benign_saddle_point && pcbddc->dbg_flag > 1) { 17285408967cSStefano Zampini ierr = PCBDDCBenignCheck(pc,zerodiag);CHKERRQ(ierr); 172909f581a4SStefano Zampini } 17304f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 173106f24817SStefano Zampini 1732b96c3477SStefano Zampini /* Setup local dirichlet solver ksp_D and sub_schurs solvers */ 1733c703fcc7SStefano Zampini if (computesubschurs && pcbddc->recompute_topography) { 173408122e43SStefano Zampini ierr = PCBDDCInitSubSchurs(pc);CHKERRQ(ierr); 1735b1b3d7a2SStefano Zampini } 17369d54b7f4SStefano Zampini /* SetUp Scaling operator (scaling matrices could be needed in SubSchursSetUp)*/ 17379d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) { 17389d54b7f4SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 17399d54b7f4SStefano Zampini } 1740c703fcc7SStefano Zampini 1741c703fcc7SStefano Zampini /* finish setup solvers and do adaptive selection of constraints */ 1742b334f244SStefano Zampini sub_schurs = pcbddc->sub_schurs; 1743b334f244SStefano Zampini if (sub_schurs && sub_schurs->schur_explicit) { 17442070dbb6SStefano Zampini if (computesubschurs) { 174508122e43SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 17462070dbb6SStefano Zampini } 1747d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 1748d5574798SStefano Zampini } else { 1749d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 17502070dbb6SStefano Zampini if (computesubschurs) { 1751d5574798SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 1752d5574798SStefano Zampini } 17532070dbb6SStefano Zampini } 175408122e43SStefano Zampini if (pcbddc->adaptive_selection) { 175508122e43SStefano Zampini ierr = PCBDDCAdaptiveSelection(pc);CHKERRQ(ierr); 17568de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1757b7eb3628SStefano Zampini } 1758684f6988SStefano Zampini 1759f4ddd8eeSStefano Zampini /* infer if NullSpace object attached to Mat via MatSetNearNullSpace has changed */ 1760fb8d54d4SStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1761f4ddd8eeSStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullspace);CHKERRQ(ierr); 1762f4ddd8eeSStefano Zampini if (pcbddc->onearnullspace) { /* already used nearnullspace */ 1763f4ddd8eeSStefano Zampini if (!nearnullspace) { /* near null space attached to mat has been destroyed */ 1764f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1765f4ddd8eeSStefano Zampini } else { 1766f4ddd8eeSStefano Zampini /* determine if the two nullspaces are different (should be lightweight) */ 1767f4ddd8eeSStefano Zampini if (nearnullspace != pcbddc->onearnullspace) { 1768f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1769165b64e2SStefano Zampini } else { /* maybe the user has changed the content of the nearnullspace so check vectors ObjectStateId */ 1770f4ddd8eeSStefano Zampini PetscInt i; 1771165b64e2SStefano Zampini const Vec *nearnullvecs; 1772165b64e2SStefano Zampini PetscObjectState state; 1773165b64e2SStefano Zampini PetscInt nnsp_size; 1774165b64e2SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullspace,NULL,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1775f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1776f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&state);CHKERRQ(ierr); 1777165b64e2SStefano Zampini if (pcbddc->onearnullvecs_state[i] != state) { 1778f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1779f4ddd8eeSStefano Zampini break; 1780f4ddd8eeSStefano Zampini } 1781f4ddd8eeSStefano Zampini } 1782f4ddd8eeSStefano Zampini } 1783f4ddd8eeSStefano Zampini } 1784f4ddd8eeSStefano Zampini } else { 1785f4ddd8eeSStefano Zampini if (!nearnullspace) { /* both nearnullspaces are null */ 1786f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1787f4ddd8eeSStefano Zampini } else { /* nearnullspace attached later */ 1788f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1789f4ddd8eeSStefano Zampini } 1790f4ddd8eeSStefano Zampini } 1791f4ddd8eeSStefano Zampini 1792f4ddd8eeSStefano Zampini /* Setup constraints and related work vectors */ 1793727cdba6SStefano Zampini /* reset primal space flags */ 179443371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_LocalWork[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 1795f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 1796727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 17978de1fae6SStefano Zampini if (computeconstraintsmatrix || new_nearnullspace_provided) { 1798727cdba6SStefano Zampini /* It also sets the primal space flags */ 1799674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 18009543d0ffSStefano Zampini } 1801e7b262bdSStefano Zampini /* Allocate needed local vectors (which depends on quantities defined during ConstraintsSetUp) */ 1802f4ddd8eeSStefano Zampini ierr = PCBDDCSetUpLocalWorkVectors(pc);CHKERRQ(ierr); 18035e8657edSStefano Zampini 18045e8657edSStefano Zampini if (pcbddc->use_change_of_basis) { 18055e8657edSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 18065e8657edSStefano Zampini 18075e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 18084f1b2e48SStefano Zampini if (pcbddc->benign_change) { 18091dd7afcfSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 1810c263805aSStefano Zampini /* pop B0 from pcbddc->local_mat */ 1811c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 1812c263805aSStefano Zampini } 18135e8657edSStefano Zampini /* get submatrices */ 18145e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 18155e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 18165e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 18177dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 18187dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 18197dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 18203975b054SStefano Zampini /* set flag in pcis to not reuse submatrices during PCISCreate */ 18213975b054SStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 18229c6a02ceSStefano Zampini } else if (!pcbddc->user_ChangeOfBasisMatrix && !pcbddc->benign_change) { 1823b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 18245e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 18255e8657edSStefano Zampini pcbddc->local_mat = matis->A; 18265e8657edSStefano Zampini } 182735509ce9Sstefano_zampini 182835509ce9Sstefano_zampini /* interface pressure block row for B_C */ 182935509ce9Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lP" ,(PetscObject*)&lP);CHKERRQ(ierr); 183035509ce9Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject*)&lA);CHKERRQ(ierr); 183135509ce9Sstefano_zampini if (lA && lP) { 183235509ce9Sstefano_zampini PC_IS* pcis = (PC_IS*)pc->data; 183335509ce9Sstefano_zampini Mat B_BI,B_BB,Bt_BI,Bt_BB; 183435509ce9Sstefano_zampini PetscBool issym; 183535509ce9Sstefano_zampini ierr = MatIsSymmetric(lA,PETSC_SMALL,&issym);CHKERRQ(ierr); 18366cc1294bSstefano_zampini if (issym) { 18377dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_I_local,MAT_INITIAL_MATRIX,&B_BI);CHKERRQ(ierr); 18387dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_B_local,MAT_INITIAL_MATRIX,&B_BB);CHKERRQ(ierr); 183935509ce9Sstefano_zampini ierr = MatCreateTranspose(B_BI,&Bt_BI);CHKERRQ(ierr); 184035509ce9Sstefano_zampini ierr = MatCreateTranspose(B_BB,&Bt_BB);CHKERRQ(ierr); 184135509ce9Sstefano_zampini } else { 18427dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_I_local,MAT_INITIAL_MATRIX,&B_BI);CHKERRQ(ierr); 18437dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_B_local,MAT_INITIAL_MATRIX,&B_BB);CHKERRQ(ierr); 18447dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,pcis->is_I_local,lP,MAT_INITIAL_MATRIX,&Bt_BI);CHKERRQ(ierr); 18457dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,pcis->is_B_local,lP,MAT_INITIAL_MATRIX,&Bt_BB);CHKERRQ(ierr); 184635509ce9Sstefano_zampini } 184735509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_B_BI",(PetscObject)B_BI);CHKERRQ(ierr); 184835509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_B_BB",(PetscObject)B_BB);CHKERRQ(ierr); 184935509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_Bt_BI",(PetscObject)Bt_BI);CHKERRQ(ierr); 185035509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_Bt_BB",(PetscObject)Bt_BB);CHKERRQ(ierr); 185135509ce9Sstefano_zampini ierr = MatDestroy(&B_BI);CHKERRQ(ierr); 185235509ce9Sstefano_zampini ierr = MatDestroy(&B_BB);CHKERRQ(ierr); 185335509ce9Sstefano_zampini ierr = MatDestroy(&Bt_BI);CHKERRQ(ierr); 185435509ce9Sstefano_zampini ierr = MatDestroy(&Bt_BB);CHKERRQ(ierr); 185535509ce9Sstefano_zampini } 185643371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_LocalWork[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 185735509ce9Sstefano_zampini 1858b96c3477SStefano Zampini /* SetUp coarse and local Neumann solvers */ 185999cc7994SStefano Zampini ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr); 1860b96c3477SStefano Zampini /* SetUp Scaling operator */ 18619d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1862674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 18630c7d97c5SJed Brown } 1864c703fcc7SStefano Zampini 18651dd7afcfSStefano Zampini /* mark topography as done */ 186656282151SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 18670369aaf7SStefano Zampini 18681dd7afcfSStefano Zampini /* wrap pcis->A_IB and pcis->A_BI if we did not change explicitly the variables on the pressures */ 18691dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_FALSE);CHKERRQ(ierr); 18701dd7afcfSStefano Zampini 187158a03d70SStefano Zampini if (pcbddc->dbg_flag) { 187258a03d70SStefano Zampini ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1873d9869140SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 18742b510759SStefano Zampini } 18750c7d97c5SJed Brown PetscFunctionReturn(0); 18760c7d97c5SJed Brown } 18770c7d97c5SJed Brown 18780c7d97c5SJed Brown /* 187950efa1b5SStefano Zampini PCApply_BDDC - Applies the BDDC operator to a vector. 18800c7d97c5SJed Brown 18810c7d97c5SJed Brown Input Parameters: 18820f202f7eSStefano Zampini + pc - the preconditioner context 18830f202f7eSStefano Zampini - r - input vector (global) 18840c7d97c5SJed Brown 18850c7d97c5SJed Brown Output Parameter: 18860c7d97c5SJed Brown . z - output vector (global) 18870c7d97c5SJed Brown 18880c7d97c5SJed Brown Application Interface Routine: PCApply() 18890c7d97c5SJed Brown */ 189053cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 18910c7d97c5SJed Brown { 18920c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 18930c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1894b3338236SStefano Zampini Mat lA = NULL; 1895b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 18960c7d97c5SJed Brown PetscErrorCode ierr; 18973b03a366Sstefano_zampini const PetscScalar one = 1.0; 18983b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 18992617d88aSStefano Zampini const PetscScalar zero = 0.0; 19000c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 19010c7d97c5SJed Brown NN interface preconditioner changed to BDDC 1902b097fa66SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static == PETSC_TRUE) */ 19030c7d97c5SJed Brown 19040c7d97c5SJed Brown PetscFunctionBegin; 1905f3d41395Sstefano_zampini ierr = PetscCitationsRegister(citation,&cited);CHKERRQ(ierr); 1906b3338236SStefano Zampini if (pcbddc->switch_static) { 1907b3338236SStefano Zampini ierr = MatISGetLocalMat(pc->useAmat ? pc->mat : pc->pmat,&lA);CHKERRQ(ierr); 1908b3338236SStefano Zampini } 1909b3338236SStefano Zampini 19101dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 19111dd7afcfSStefano Zampini Vec swap; 191227b6a85dSStefano Zampini 191327b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 19141dd7afcfSStefano Zampini swap = pcbddc->work_change; 19151dd7afcfSStefano Zampini pcbddc->work_change = r; 19161dd7afcfSStefano Zampini r = swap; 19171dd7afcfSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 19189cc2a9b1Sstefano_zampini if (pcbddc->benign_apply_coarse_only && pcbddc->use_exact_dirichlet_trick && pcbddc->change_interior) { 19191dd7afcfSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 19208860a134SJunchao Zhang ierr = VecLockReadPush(pcis->vec1_global);CHKERRQ(ierr); 19211dd7afcfSStefano Zampini } 19221dd7afcfSStefano Zampini } 192327b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 1924015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1925efc2fbd9SStefano Zampini } 19268ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 1927b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 19280c7d97c5SJed Brown /* First Dirichlet solve */ 19290c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19300c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19310c7d97c5SJed Brown /* 19320c7d97c5SJed Brown Assembling right hand side for BDDC operator 1933b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 1934674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 19350c7d97c5SJed Brown */ 1936b097fa66SStefano Zampini if (n_D) { 1937b097fa66SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 1938c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 19390c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 194016909a7fSStefano Zampini if (pcbddc->switch_static) { 194116909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 194216909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 194316909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 194416909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 1945b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 194616909a7fSStefano Zampini } else { 194716909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 1948b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 194916909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 195016909a7fSStefano Zampini } 195116909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 195216909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 195316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 195416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 195516909a7fSStefano Zampini } else { 1956b097fa66SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 195716909a7fSStefano Zampini } 1958b097fa66SStefano Zampini } else { 1959b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1960b097fa66SStefano Zampini } 19610c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19620c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1963674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 1964b76ba322SStefano Zampini } else { 19654fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 1966674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 1967b76ba322SStefano Zampini } 19684fee134fSStefano Zampini } 1969b76ba322SStefano Zampini 19702617d88aSStefano Zampini /* Apply interface preconditioner 19712617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1972dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 19732617d88aSStefano Zampini 1974674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 1975674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 19760c7d97c5SJed Brown 19773b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 19780c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19790c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1980b097fa66SStefano Zampini if (n_B) { 198116909a7fSStefano Zampini if (pcbddc->switch_static) { 198216909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 198316909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 198416909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 198516909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 198616909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 1987b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 198816909a7fSStefano Zampini } else { 198916909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 1990b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 199116909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 199216909a7fSStefano Zampini } 199316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 199416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 199516909a7fSStefano Zampini } else { 19960c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 199716909a7fSStefano Zampini } 199816909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 199916909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 2000b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 200116909a7fSStefano Zampini } else { 200216909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 2003b3338236SStefano Zampini ierr = MatMult(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 200416909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 200516909a7fSStefano Zampini } 2006b097fa66SStefano Zampini } 2007df187020SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 2008c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec4_D);CHKERRQ(ierr); 2009efc2fbd9SStefano Zampini 20108ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2011b097fa66SStefano Zampini if (pcbddc->switch_static) { 2012b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 2013b097fa66SStefano Zampini } else { 2014b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 2015b097fa66SStefano Zampini } 20160c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20170c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2018b097fa66SStefano Zampini } else { 2019b097fa66SStefano Zampini if (pcbddc->switch_static) { 2020b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 2021b097fa66SStefano Zampini } else { 2022b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 2023b097fa66SStefano Zampini } 2024b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2025b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2026b097fa66SStefano Zampini } 202727b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 20281dd7afcfSStefano Zampini if (pcbddc->benign_apply_coarse_only) { 2029580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->benign_p0,pcbddc->benign_n);CHKERRQ(ierr); 20301dd7afcfSStefano Zampini } 2031015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 2032efc2fbd9SStefano Zampini } 20331f4df5f7SStefano Zampini 20341dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2035f913dca9SStefano Zampini pcbddc->work_change = r; 20361dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 20371dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 20381dd7afcfSStefano Zampini } 20390c7d97c5SJed Brown PetscFunctionReturn(0); 20400c7d97c5SJed Brown } 204150efa1b5SStefano Zampini 204250efa1b5SStefano Zampini /* 204350efa1b5SStefano Zampini PCApplyTranspose_BDDC - Applies the transpose of the BDDC operator to a vector. 204450efa1b5SStefano Zampini 204550efa1b5SStefano Zampini Input Parameters: 20460f202f7eSStefano Zampini + pc - the preconditioner context 20470f202f7eSStefano Zampini - r - input vector (global) 204850efa1b5SStefano Zampini 204950efa1b5SStefano Zampini Output Parameter: 205050efa1b5SStefano Zampini . z - output vector (global) 205150efa1b5SStefano Zampini 205250efa1b5SStefano Zampini Application Interface Routine: PCApplyTranspose() 205350efa1b5SStefano Zampini */ 205450efa1b5SStefano Zampini PetscErrorCode PCApplyTranspose_BDDC(PC pc,Vec r,Vec z) 205550efa1b5SStefano Zampini { 205650efa1b5SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 205750efa1b5SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 2058b3338236SStefano Zampini Mat lA = NULL; 2059b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 206050efa1b5SStefano Zampini PetscErrorCode ierr; 206150efa1b5SStefano Zampini const PetscScalar one = 1.0; 206250efa1b5SStefano Zampini const PetscScalar m_one = -1.0; 206350efa1b5SStefano Zampini const PetscScalar zero = 0.0; 206450efa1b5SStefano Zampini 206550efa1b5SStefano Zampini PetscFunctionBegin; 2066f3d41395Sstefano_zampini ierr = PetscCitationsRegister(citation,&cited);CHKERRQ(ierr); 2067b3338236SStefano Zampini if (pcbddc->switch_static) { 2068b3338236SStefano Zampini ierr = MatISGetLocalMat(pc->useAmat ? pc->mat : pc->pmat,&lA);CHKERRQ(ierr); 2069b3338236SStefano Zampini } 20701dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 20711dd7afcfSStefano Zampini Vec swap; 207227b6a85dSStefano Zampini 207327b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 20741dd7afcfSStefano Zampini swap = pcbddc->work_change; 20751dd7afcfSStefano Zampini pcbddc->work_change = r; 20761dd7afcfSStefano Zampini r = swap; 207727b6a85dSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 20788ae0ca82SStefano Zampini if (pcbddc->benign_apply_coarse_only && pcbddc->exact_dirichlet_trick_app && pcbddc->change_interior) { 207927b6a85dSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 20808860a134SJunchao Zhang ierr = VecLockReadPush(pcis->vec1_global);CHKERRQ(ierr); 20811dd7afcfSStefano Zampini } 208227b6a85dSStefano Zampini } 208327b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 2084537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 2085537c1cdfSStefano Zampini } 20868ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2087b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 208850efa1b5SStefano Zampini /* First Dirichlet solve */ 208950efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 209050efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 209150efa1b5SStefano Zampini /* 209250efa1b5SStefano Zampini Assembling right hand side for BDDC operator 2093b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 209450efa1b5SStefano Zampini - pcis->vec1_B the interface part of the global vector z 209550efa1b5SStefano Zampini */ 2096b097fa66SStefano Zampini if (n_D) { 2097b097fa66SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 2098c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 209950efa1b5SStefano Zampini ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 210016909a7fSStefano Zampini if (pcbddc->switch_static) { 210116909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 210216909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 210316909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 210416909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 2105b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 210616909a7fSStefano Zampini } else { 210716909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 2108b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 210916909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 211016909a7fSStefano Zampini } 211116909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 211216909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 211316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 211416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 211516909a7fSStefano Zampini } else { 2116b097fa66SStefano Zampini ierr = MatMultTranspose(pcis->A_IB,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 211716909a7fSStefano Zampini } 2118b097fa66SStefano Zampini } else { 2119b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 2120b097fa66SStefano Zampini } 212150efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 212250efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 212350efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 212450efa1b5SStefano Zampini } else { 212550efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 212650efa1b5SStefano Zampini } 212750efa1b5SStefano Zampini 212850efa1b5SStefano Zampini /* Apply interface preconditioner 212950efa1b5SStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 2130dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_TRUE);CHKERRQ(ierr); 213150efa1b5SStefano Zampini 213250efa1b5SStefano Zampini /* Apply transpose of partition of unity operator */ 213350efa1b5SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 213450efa1b5SStefano Zampini 213550efa1b5SStefano Zampini /* Second Dirichlet solve and assembling of output */ 213650efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 213750efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2138b097fa66SStefano Zampini if (n_B) { 213916909a7fSStefano Zampini if (pcbddc->switch_static) { 214016909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 214116909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 214216909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 214316909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 214416909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 2145b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 214616909a7fSStefano Zampini } else { 214716909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 2148b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 214916909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 215016909a7fSStefano Zampini } 215116909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 215216909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 215316909a7fSStefano Zampini } else { 215450efa1b5SStefano Zampini ierr = MatMultTranspose(pcis->A_BI,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 215516909a7fSStefano Zampini } 215616909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 215716909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 2158b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 215916909a7fSStefano Zampini } else { 216016909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 2161b3338236SStefano Zampini ierr = MatMultTranspose(lA,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 216216909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 216316909a7fSStefano Zampini } 2164b097fa66SStefano Zampini } 2165b0147a47SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 2166c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec4_D);CHKERRQ(ierr); 21678ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2168b097fa66SStefano Zampini if (pcbddc->switch_static) { 2169b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 2170b097fa66SStefano Zampini } else { 2171b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 2172b097fa66SStefano Zampini } 217350efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 217450efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2175b097fa66SStefano Zampini } else { 2176b097fa66SStefano Zampini if (pcbddc->switch_static) { 2177b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 2178b097fa66SStefano Zampini } else { 2179b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 2180b097fa66SStefano Zampini } 2181b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2182b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2183b097fa66SStefano Zampini } 218427b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 2185537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 2186537c1cdfSStefano Zampini } 21871dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2188f913dca9SStefano Zampini pcbddc->work_change = r; 21891dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 21901dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 21911dd7afcfSStefano Zampini } 219250efa1b5SStefano Zampini PetscFunctionReturn(0); 219350efa1b5SStefano Zampini } 2194674ae819SStefano Zampini 21959326c5c6Sstefano_zampini PetscErrorCode PCReset_BDDC(PC pc) 2196da1bb401SStefano Zampini { 2197da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 21989326c5c6Sstefano_zampini PC_IS *pcis = (PC_IS*)pc->data; 21999326c5c6Sstefano_zampini KSP kspD,kspR,kspC; 2200da1bb401SStefano Zampini PetscErrorCode ierr; 2201da1bb401SStefano Zampini 2202da1bb401SStefano Zampini PetscFunctionBegin; 2203674ae819SStefano Zampini /* free BDDC custom data */ 2204674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 2205674ae819SStefano Zampini /* destroy objects related to topography */ 2206674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 220734a97f8cSStefano Zampini /* destroy objects for scaling operator */ 2208674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 2209674ae819SStefano Zampini /* free solvers stuff */ 2210674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 221162a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 221262a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 221362a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 22141dd7afcfSStefano Zampini /* free data created by PCIS */ 22151dd7afcfSStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 22169326c5c6Sstefano_zampini 22179326c5c6Sstefano_zampini /* restore defaults */ 22189326c5c6Sstefano_zampini kspD = pcbddc->ksp_D; 22199326c5c6Sstefano_zampini kspR = pcbddc->ksp_R; 22209326c5c6Sstefano_zampini kspC = pcbddc->coarse_ksp; 22219326c5c6Sstefano_zampini ierr = PetscMemzero(pc->data,sizeof(*pcbddc));CHKERRQ(ierr); 22229326c5c6Sstefano_zampini pcis->n_neigh = -1; 22239326c5c6Sstefano_zampini pcis->scaling_factor = 1.0; 22249326c5c6Sstefano_zampini pcis->reusesubmatrices = PETSC_TRUE; 22259326c5c6Sstefano_zampini pcbddc->use_local_adj = PETSC_TRUE; 22269326c5c6Sstefano_zampini pcbddc->use_vertices = PETSC_TRUE; 22279326c5c6Sstefano_zampini pcbddc->use_edges = PETSC_TRUE; 22289326c5c6Sstefano_zampini pcbddc->symmetric_primal = PETSC_TRUE; 22299326c5c6Sstefano_zampini pcbddc->vertex_size = 1; 22309326c5c6Sstefano_zampini pcbddc->recompute_topography = PETSC_TRUE; 22319326c5c6Sstefano_zampini pcbddc->coarse_size = -1; 22329326c5c6Sstefano_zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 22339326c5c6Sstefano_zampini pcbddc->coarsening_ratio = 8; 22349326c5c6Sstefano_zampini pcbddc->coarse_eqs_per_proc = 1; 22359326c5c6Sstefano_zampini pcbddc->benign_compute_correction = PETSC_TRUE; 22369326c5c6Sstefano_zampini pcbddc->nedfield = -1; 22379326c5c6Sstefano_zampini pcbddc->nedglobal = PETSC_TRUE; 22389326c5c6Sstefano_zampini pcbddc->graphmaxcount = PETSC_MAX_INT; 22399326c5c6Sstefano_zampini pcbddc->sub_schurs_layers = -1; 22409326c5c6Sstefano_zampini pcbddc->ksp_D = kspD; 22419326c5c6Sstefano_zampini pcbddc->ksp_R = kspR; 22429326c5c6Sstefano_zampini pcbddc->coarse_ksp = kspC; 22439326c5c6Sstefano_zampini PetscFunctionReturn(0); 22449326c5c6Sstefano_zampini } 22459326c5c6Sstefano_zampini 22469326c5c6Sstefano_zampini PetscErrorCode PCDestroy_BDDC(PC pc) 22479326c5c6Sstefano_zampini { 22489326c5c6Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 22499326c5c6Sstefano_zampini PetscErrorCode ierr; 22509326c5c6Sstefano_zampini 22519326c5c6Sstefano_zampini PetscFunctionBegin; 22529326c5c6Sstefano_zampini ierr = PCReset_BDDC(pc);CHKERRQ(ierr); 22539326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 22549326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 22559326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 2256a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",NULL);CHKERRQ(ierr); 2257a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",NULL);CHKERRQ(ierr); 2258906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",NULL);CHKERRQ(ierr); 2259674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 226030368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",NULL);CHKERRQ(ierr); 2261bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 22622b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr); 2263b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr); 22642b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr); 2265bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 226682ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2267bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 226882ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2269bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 227082ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2271bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 2272785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2273bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 227463602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",NULL);CHKERRQ(ierr); 2275bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 2276bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 2277bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 2278bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 2279a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",NULL);CHKERRQ(ierr); 2280ab8c8b98SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",NULL);CHKERRQ(ierr); 2281674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 2282da1bb401SStefano Zampini PetscFunctionReturn(0); 2283da1bb401SStefano Zampini } 22841e6b0712SBarry Smith 2285ab8c8b98SStefano Zampini static PetscErrorCode PCSetCoordinates_BDDC(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 2286ab8c8b98SStefano Zampini { 2287ab8c8b98SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2288ab8c8b98SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 2289ab8c8b98SStefano Zampini PetscErrorCode ierr; 2290ab8c8b98SStefano Zampini 2291ab8c8b98SStefano Zampini PetscFunctionBegin; 2292ab8c8b98SStefano Zampini ierr = PetscFree(mat_graph->coords);CHKERRQ(ierr); 2293ab8c8b98SStefano Zampini ierr = PetscMalloc1(nloc*dim,&mat_graph->coords);CHKERRQ(ierr); 2294580bdb30SBarry Smith ierr = PetscArraycpy(mat_graph->coords,coords,nloc*dim);CHKERRQ(ierr); 2295ab8c8b98SStefano Zampini mat_graph->cnloc = nloc; 2296ab8c8b98SStefano Zampini mat_graph->cdim = dim; 2297ab8c8b98SStefano Zampini mat_graph->cloc = PETSC_FALSE; 22984f819b78SStefano Zampini /* flg setup */ 22994f819b78SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 23004f819b78SStefano Zampini pcbddc->corner_selected = PETSC_FALSE; 2301ab8c8b98SStefano Zampini PetscFunctionReturn(0); 2302ab8c8b98SStefano Zampini } 2303ab8c8b98SStefano Zampini 2304a06fd7f2SStefano Zampini static PetscErrorCode PCPreSolveChangeRHS_BDDC(PC pc, PetscBool* change) 2305a06fd7f2SStefano Zampini { 2306a06fd7f2SStefano Zampini PetscFunctionBegin; 2307a06fd7f2SStefano Zampini *change = PETSC_TRUE; 2308a06fd7f2SStefano Zampini PetscFunctionReturn(0); 2309a06fd7f2SStefano Zampini } 2310a06fd7f2SStefano Zampini 23113425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 23123425bc38SStefano Zampini { 2313674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 2314266e20e9SStefano Zampini Vec work; 23153425bc38SStefano Zampini PC_IS* pcis; 23163425bc38SStefano Zampini PC_BDDC* pcbddc; 23173425bc38SStefano Zampini PetscErrorCode ierr; 23180c7d97c5SJed Brown 23193425bc38SStefano Zampini PetscFunctionBegin; 23203425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 23213425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 23223425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 23233425bc38SStefano Zampini 2324229984c5Sstefano_zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 2325229984c5Sstefano_zampini /* copy rhs since we may change it during PCPreSolve_BDDC */ 2326229984c5Sstefano_zampini if (!pcbddc->original_rhs) { 2327229984c5Sstefano_zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 2328229984c5Sstefano_zampini } 23296cc1294bSstefano_zampini if (mat_ctx->rhs_flip) { 23306cc1294bSstefano_zampini ierr = VecPointwiseMult(pcbddc->original_rhs,standard_rhs,mat_ctx->rhs_flip);CHKERRQ(ierr); 23316cc1294bSstefano_zampini } else { 2332229984c5Sstefano_zampini ierr = VecCopy(standard_rhs,pcbddc->original_rhs);CHKERRQ(ierr); 23336cc1294bSstefano_zampini } 2334af140850Sstefano_zampini if (mat_ctx->g2g_p) { 2335229984c5Sstefano_zampini /* interface pressure rhs */ 2336022d8d2bSstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,fetidp_flux_rhs,pcbddc->original_rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2337022d8d2bSstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,fetidp_flux_rhs,pcbddc->original_rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2338229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,standard_rhs,fetidp_flux_rhs,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2339229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,standard_rhs,fetidp_flux_rhs,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23406cc1294bSstefano_zampini if (!mat_ctx->rhs_flip) { 2341229984c5Sstefano_zampini ierr = VecScale(fetidp_flux_rhs,-1.);CHKERRQ(ierr); 2342229984c5Sstefano_zampini } 23436cc1294bSstefano_zampini } 2344c08af4c6SStefano Zampini /* 2345c08af4c6SStefano Zampini change of basis for physical rhs if needed 2346c08af4c6SStefano Zampini It also changes the rhs in case of dirichlet boundaries 2347c08af4c6SStefano Zampini */ 23483738a8e6SStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,pcbddc->original_rhs,NULL);CHKERRQ(ierr); 2349fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 23503738a8e6SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcbddc->original_rhs,pcbddc->work_change);CHKERRQ(ierr); 23513738a8e6SStefano Zampini work = pcbddc->work_change; 2352fc17d649SStefano Zampini } else { 23533738a8e6SStefano Zampini work = pcbddc->original_rhs; 2354fc17d649SStefano Zampini } 23553425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 2356266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2357266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2358fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 2359fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 2360266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2361266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2362674ae819SStefano Zampini /* Apply partition of unity */ 23633425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 2364266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 23658eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 23663425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 23673425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 2368c0decd05SBarry Smith /* Cannot propagate up error in KSPSolve() because there is no access to the PC */ 23693425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 23703425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 2371266e20e9SStefano Zampini ierr = VecSet(work,0.0);CHKERRQ(ierr); 2372266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2373266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2374266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 2375266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2376266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23773425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 23783425bc38SStefano Zampini } 23793425bc38SStefano Zampini /* BDDC rhs */ 23803425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 23818eeda7d8SStefano Zampini if (pcbddc->switch_static) { 23823425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 23833425bc38SStefano Zampini } 23843425bc38SStefano Zampini /* apply BDDC */ 2385580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->benign_p0,pcbddc->benign_n);CHKERRQ(ierr); 2386dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2387580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->benign_p0,pcbddc->benign_n);CHKERRQ(ierr); 2388229984c5Sstefano_zampini 23893425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 23903425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 23913425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23923425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2393229984c5Sstefano_zampini /* Add contribution to interface pressures */ 2394229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2395229984c5Sstefano_zampini ierr = MatMult(mat_ctx->B_BB,pcis->vec1_B,mat_ctx->vP);CHKERRQ(ierr); 2396229984c5Sstefano_zampini if (pcbddc->switch_static) { 2397229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->B_BI,pcis->vec1_D,mat_ctx->vP,mat_ctx->vP);CHKERRQ(ierr); 2398229984c5Sstefano_zampini } 2399229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->l2g_p,mat_ctx->vP,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2400229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->l2g_p,mat_ctx->vP,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2401229984c5Sstefano_zampini } 24023425bc38SStefano Zampini PetscFunctionReturn(0); 24033425bc38SStefano Zampini } 24041e6b0712SBarry Smith 24053425bc38SStefano Zampini /*@ 24060f202f7eSStefano Zampini PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETI-DP linear system using the physical right-hand side 24073425bc38SStefano Zampini 24083425bc38SStefano Zampini Collective 24093425bc38SStefano Zampini 24103425bc38SStefano Zampini Input Parameters: 24110f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix object obtained by a call to PCBDDCCreateFETIDPOperators 24120f202f7eSStefano Zampini - standard_rhs - the right-hand side of the original linear system 24133425bc38SStefano Zampini 24143425bc38SStefano Zampini Output Parameters: 24150f202f7eSStefano Zampini . fetidp_flux_rhs - the right-hand side for the FETI-DP linear system 24163425bc38SStefano Zampini 24173425bc38SStefano Zampini Level: developer 24183425bc38SStefano Zampini 24193425bc38SStefano Zampini Notes: 24203425bc38SStefano Zampini 24210f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetSolution 24223425bc38SStefano Zampini @*/ 24233425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 24243425bc38SStefano Zampini { 2425674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 24263425bc38SStefano Zampini PetscErrorCode ierr; 24273425bc38SStefano Zampini 24283425bc38SStefano Zampini PetscFunctionBegin; 2429266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2430266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_rhs,VEC_CLASSID,2); 2431266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_rhs,VEC_CLASSID,3); 24323425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2433163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 24343425bc38SStefano Zampini PetscFunctionReturn(0); 24353425bc38SStefano Zampini } 24361e6b0712SBarry Smith 24373425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 24383425bc38SStefano Zampini { 2439674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 24403425bc38SStefano Zampini PC_IS* pcis; 24413425bc38SStefano Zampini PC_BDDC* pcbddc; 24423425bc38SStefano Zampini PetscErrorCode ierr; 2443229984c5Sstefano_zampini Vec work; 24443425bc38SStefano Zampini 24453425bc38SStefano Zampini PetscFunctionBegin; 24463425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 24473425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 24483425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 24493425bc38SStefano Zampini 24503425bc38SStefano Zampini /* apply B_delta^T */ 2451af140850Sstefano_zampini ierr = VecSet(pcis->vec1_B,0.);CHKERRQ(ierr); 24523425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24533425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24543425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 2455229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2456229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->l2g_p,fetidp_flux_sol,mat_ctx->vP,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2457229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->l2g_p,fetidp_flux_sol,mat_ctx->vP,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2458229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->Bt_BB,mat_ctx->vP,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 2459229984c5Sstefano_zampini } 2460229984c5Sstefano_zampini 24613425bc38SStefano Zampini /* compute rhs for BDDC application */ 24623425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 24638eeda7d8SStefano Zampini if (pcbddc->switch_static) { 24643425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 2465229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2466229984c5Sstefano_zampini ierr = VecScale(mat_ctx->vP,-1.);CHKERRQ(ierr); 2467229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->Bt_BI,mat_ctx->vP,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); 24683425bc38SStefano Zampini } 2469229984c5Sstefano_zampini } 2470229984c5Sstefano_zampini 24713425bc38SStefano Zampini /* apply BDDC */ 2472580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->benign_p0,pcbddc->benign_n);CHKERRQ(ierr); 2473dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2474229984c5Sstefano_zampini 2475229984c5Sstefano_zampini /* put values into global vector */ 2476af140850Sstefano_zampini if (pcbddc->ChangeOfBasisMatrix) work = pcbddc->work_change; 2477af140850Sstefano_zampini else work = standard_sol; 2478229984c5Sstefano_zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2479229984c5Sstefano_zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24808eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 24813425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 24823425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 248300f6b531SStefano Zampini ierr = VecAYPX(pcis->vec1_D,-1.0,mat_ctx->temp_solution_D);CHKERRQ(ierr); 248400f6b531SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); 2485c0decd05SBarry Smith /* Cannot propagate up error in KSPSolve() because there is no access to the PC */ 24863425bc38SStefano Zampini } 2487229984c5Sstefano_zampini 2488229984c5Sstefano_zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2489229984c5Sstefano_zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_D,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2490266e20e9SStefano Zampini /* add p0 solution to final solution */ 2491229984c5Sstefano_zampini ierr = PCBDDCBenignGetOrSetP0(mat_ctx->pc,work,PETSC_FALSE);CHKERRQ(ierr); 2492fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2493af140850Sstefano_zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,work,standard_sol);CHKERRQ(ierr); 2494fc17d649SStefano Zampini } 2495af140850Sstefano_zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 2496af140850Sstefano_zampini if (mat_ctx->g2g_p) { 2497229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,fetidp_flux_sol,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2498229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,fetidp_flux_sol,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2499229984c5Sstefano_zampini } 25003425bc38SStefano Zampini PetscFunctionReturn(0); 25013425bc38SStefano Zampini } 25021e6b0712SBarry Smith 25035a1e936bSStefano Zampini static PetscErrorCode PCView_BDDCIPC(PC pc, PetscViewer viewer) 25045a1e936bSStefano Zampini { 25055a1e936bSStefano Zampini PetscErrorCode ierr; 25065a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25075a1e936bSStefano Zampini PetscBool isascii; 25085a1e936bSStefano Zampini 25095a1e936bSStefano Zampini PetscFunctionBegin; 25105a1e936bSStefano Zampini ierr = PCShellGetContext(pc,(void **)&bddcipc_ctx);CHKERRQ(ierr); 25115a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 25125a1e936bSStefano Zampini if (isascii) { 25135a1e936bSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"BDDC interface preconditioner\n");CHKERRQ(ierr); 25145a1e936bSStefano Zampini } 25155a1e936bSStefano Zampini ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 25165a1e936bSStefano Zampini ierr = PCView(bddcipc_ctx->bddc,viewer);CHKERRQ(ierr); 25175a1e936bSStefano Zampini ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 25185a1e936bSStefano Zampini PetscFunctionReturn(0); 25195a1e936bSStefano Zampini } 25205a1e936bSStefano Zampini 25215a1e936bSStefano Zampini static PetscErrorCode PCSetUp_BDDCIPC(PC pc) 25225a1e936bSStefano Zampini { 25235a1e936bSStefano Zampini PetscErrorCode ierr; 25245a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25255a1e936bSStefano Zampini PetscBool isbddc; 25265a1e936bSStefano Zampini Vec vv; 25275a1e936bSStefano Zampini IS is; 25285a1e936bSStefano Zampini PC_IS *pcis; 25295a1e936bSStefano Zampini 25305a1e936bSStefano Zampini PetscFunctionBegin; 25315a1e936bSStefano Zampini ierr = PCShellGetContext(pc,(void **)&bddcipc_ctx);CHKERRQ(ierr); 25325a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)bddcipc_ctx->bddc,PCBDDC,&isbddc);CHKERRQ(ierr); 25335a1e936bSStefano Zampini if (!isbddc) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid type %s. Must be of type bddc",((PetscObject)bddcipc_ctx->bddc)->type_name); 25345a1e936bSStefano Zampini ierr = PCSetUp(bddcipc_ctx->bddc);CHKERRQ(ierr); 25355a1e936bSStefano Zampini 25365a1e936bSStefano Zampini /* create interface scatter */ 25375a1e936bSStefano Zampini pcis = (PC_IS*)(bddcipc_ctx->bddc->data); 25385a1e936bSStefano Zampini ierr = VecScatterDestroy(&bddcipc_ctx->g2l);CHKERRQ(ierr); 25395a1e936bSStefano Zampini ierr = MatCreateVecs(pc->pmat,&vv,NULL);CHKERRQ(ierr); 25405a1e936bSStefano Zampini ierr = ISRenumber(pcis->is_B_global,NULL,NULL,&is);CHKERRQ(ierr); 25419448b7f1SJunchao Zhang ierr = VecScatterCreate(vv,is,pcis->vec1_B,NULL,&bddcipc_ctx->g2l);CHKERRQ(ierr); 25425a1e936bSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 25435a1e936bSStefano Zampini ierr = VecDestroy(&vv);CHKERRQ(ierr); 25445a1e936bSStefano Zampini PetscFunctionReturn(0); 25455a1e936bSStefano Zampini } 25465a1e936bSStefano Zampini 25475a1e936bSStefano Zampini static PetscErrorCode PCApply_BDDCIPC(PC pc, Vec r, Vec x) 25485a1e936bSStefano Zampini { 25495a1e936bSStefano Zampini PetscErrorCode ierr; 25505a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25515a1e936bSStefano Zampini PC_IS *pcis; 25525a1e936bSStefano Zampini VecScatter tmps; 25535a1e936bSStefano Zampini 25545a1e936bSStefano Zampini PetscFunctionBegin; 25555a1e936bSStefano Zampini ierr = PCShellGetContext(pc,(void **)&bddcipc_ctx);CHKERRQ(ierr); 25565a1e936bSStefano Zampini pcis = (PC_IS*)(bddcipc_ctx->bddc->data); 25575a1e936bSStefano Zampini tmps = pcis->global_to_B; 25585a1e936bSStefano Zampini pcis->global_to_B = bddcipc_ctx->g2l; 25595a1e936bSStefano Zampini ierr = PCBDDCScalingRestriction(bddcipc_ctx->bddc,r,pcis->vec1_B);CHKERRQ(ierr); 25605a1e936bSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(bddcipc_ctx->bddc,PETSC_FALSE);CHKERRQ(ierr); 25615a1e936bSStefano Zampini ierr = PCBDDCScalingExtension(bddcipc_ctx->bddc,pcis->vec1_B,x);CHKERRQ(ierr); 25625a1e936bSStefano Zampini pcis->global_to_B = tmps; 25635a1e936bSStefano Zampini PetscFunctionReturn(0); 25645a1e936bSStefano Zampini } 25655a1e936bSStefano Zampini 25665a1e936bSStefano Zampini static PetscErrorCode PCApplyTranspose_BDDCIPC(PC pc, Vec r, Vec x) 25675a1e936bSStefano Zampini { 25685a1e936bSStefano Zampini PetscErrorCode ierr; 25695a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25705a1e936bSStefano Zampini PC_IS *pcis; 25715a1e936bSStefano Zampini VecScatter tmps; 25725a1e936bSStefano Zampini 25735a1e936bSStefano Zampini PetscFunctionBegin; 25745a1e936bSStefano Zampini ierr = PCShellGetContext(pc,(void **)&bddcipc_ctx);CHKERRQ(ierr); 25755a1e936bSStefano Zampini pcis = (PC_IS*)(bddcipc_ctx->bddc->data); 25765a1e936bSStefano Zampini tmps = pcis->global_to_B; 25775a1e936bSStefano Zampini pcis->global_to_B = bddcipc_ctx->g2l; 25785a1e936bSStefano Zampini ierr = PCBDDCScalingRestriction(bddcipc_ctx->bddc,r,pcis->vec1_B);CHKERRQ(ierr); 25795a1e936bSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(bddcipc_ctx->bddc,PETSC_TRUE);CHKERRQ(ierr); 25805a1e936bSStefano Zampini ierr = PCBDDCScalingExtension(bddcipc_ctx->bddc,pcis->vec1_B,x);CHKERRQ(ierr); 25815a1e936bSStefano Zampini pcis->global_to_B = tmps; 25825a1e936bSStefano Zampini PetscFunctionReturn(0); 25835a1e936bSStefano Zampini } 25845a1e936bSStefano Zampini 25855a1e936bSStefano Zampini static PetscErrorCode PCDestroy_BDDCIPC(PC pc) 25865a1e936bSStefano Zampini { 25875a1e936bSStefano Zampini PetscErrorCode ierr; 25885a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25895a1e936bSStefano Zampini 25905a1e936bSStefano Zampini PetscFunctionBegin; 25915a1e936bSStefano Zampini ierr = PCShellGetContext(pc,(void **)&bddcipc_ctx);CHKERRQ(ierr); 25925a1e936bSStefano Zampini ierr = PCDestroy(&bddcipc_ctx->bddc);CHKERRQ(ierr); 25935a1e936bSStefano Zampini ierr = VecScatterDestroy(&bddcipc_ctx->g2l);CHKERRQ(ierr); 25945a1e936bSStefano Zampini ierr = PetscFree(bddcipc_ctx);CHKERRQ(ierr); 25955a1e936bSStefano Zampini PetscFunctionReturn(0); 25965a1e936bSStefano Zampini } 25975a1e936bSStefano Zampini 25983425bc38SStefano Zampini /*@ 25990f202f7eSStefano Zampini PCBDDCMatFETIDPGetSolution - Compute the physical solution using the solution of the FETI-DP linear system 26003425bc38SStefano Zampini 26013425bc38SStefano Zampini Collective 26023425bc38SStefano Zampini 26033425bc38SStefano Zampini Input Parameters: 26040f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix obtained by a call to PCBDDCCreateFETIDPOperators 26050f202f7eSStefano Zampini - fetidp_flux_sol - the solution of the FETI-DP linear system 26063425bc38SStefano Zampini 26073425bc38SStefano Zampini Output Parameters: 26080f202f7eSStefano Zampini . standard_sol - the solution defined on the physical domain 26093425bc38SStefano Zampini 26103425bc38SStefano Zampini Level: developer 26113425bc38SStefano Zampini 26123425bc38SStefano Zampini Notes: 26133425bc38SStefano Zampini 26140f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetRHS 26153425bc38SStefano Zampini @*/ 26163425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 26173425bc38SStefano Zampini { 2618674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 26193425bc38SStefano Zampini PetscErrorCode ierr; 26203425bc38SStefano Zampini 26213425bc38SStefano Zampini PetscFunctionBegin; 2622266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2623266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_sol,VEC_CLASSID,2); 2624266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_sol,VEC_CLASSID,3); 26253425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2626163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 26273425bc38SStefano Zampini PetscFunctionReturn(0); 26283425bc38SStefano Zampini } 26291e6b0712SBarry Smith 2630547c9a8eSstefano_zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, PetscBool fully_redundant, const char* prefix, Mat *fetidp_mat, PC *fetidp_pc) 26313425bc38SStefano Zampini { 2632674ae819SStefano Zampini 2633674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 26343425bc38SStefano Zampini Mat newmat; 2635674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 26363425bc38SStefano Zampini PC newpc; 2637ce94432eSBarry Smith MPI_Comm comm; 26383425bc38SStefano Zampini PetscErrorCode ierr; 26393425bc38SStefano Zampini 26403425bc38SStefano Zampini PetscFunctionBegin; 2641ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 264215579a77SStefano Zampini /* FETI-DP matrix */ 26433425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 26441720468bSStefano Zampini fetidpmat_ctx->fully_redundant = fully_redundant; 26453425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 2646a5bb87b3Sstefano_zampini ierr = MatCreateShell(comm,fetidpmat_ctx->n,fetidpmat_ctx->n,fetidpmat_ctx->N,fetidpmat_ctx->N,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 264715579a77SStefano Zampini ierr = PetscObjectSetName((PetscObject)newmat,!fetidpmat_ctx->l2g_lambda_only ? "F" : "G");CHKERRQ(ierr); 26483425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 2649edf7251bSStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT_TRANSPOSE,(void (*)(void))FETIDPMatMultTranspose);CHKERRQ(ierr); 26503425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 265115579a77SStefano Zampini /* propagate MatOptions */ 265215579a77SStefano Zampini { 265315579a77SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)fetidpmat_ctx->pc->data; 265415579a77SStefano Zampini PetscBool issym; 265515579a77SStefano Zampini 265615579a77SStefano Zampini ierr = MatGetOption(pc->mat,MAT_SYMMETRIC,&issym);CHKERRQ(ierr); 265715579a77SStefano Zampini if (issym || pcbddc->symmetric_primal) { 265815579a77SStefano Zampini ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 265915579a77SStefano Zampini } 266015579a77SStefano Zampini } 2661547c9a8eSstefano_zampini ierr = MatSetOptionsPrefix(newmat,prefix);CHKERRQ(ierr); 2662547c9a8eSstefano_zampini ierr = MatAppendOptionsPrefix(newmat,"fetidp_");CHKERRQ(ierr); 26633425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 266415579a77SStefano Zampini /* FETI-DP preconditioner */ 26653425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 26663425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 26673425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 2668e1214c54Sstefano_zampini ierr = PCSetOperators(newpc,newmat,newmat);CHKERRQ(ierr); 2669e1214c54Sstefano_zampini ierr = PCSetOptionsPrefix(newpc,prefix);CHKERRQ(ierr); 2670e1214c54Sstefano_zampini ierr = PCAppendOptionsPrefix(newpc,"fetidp_");CHKERRQ(ierr); 2671399ffe99SStefano Zampini ierr = PCSetErrorIfFailure(newpc,pc->erroriffailure);CHKERRQ(ierr); 267215579a77SStefano Zampini if (!fetidpmat_ctx->l2g_lambda_only) { /* standard FETI-DP */ 26733425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 267415579a77SStefano Zampini ierr = PCShellSetName(newpc,"FETI-DP multipliers");CHKERRQ(ierr); 26753425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 26763425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 2677edf7251bSStefano Zampini ierr = PCShellSetApplyTranspose(newpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 2678c45b8d2dSstefano_zampini ierr = PCShellSetView(newpc,FETIDPPCView);CHKERRQ(ierr); 26793425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 26805a1e936bSStefano Zampini } else { /* saddle-point FETI-DP */ 26815a1e936bSStefano Zampini Mat M; 26825a1e936bSStefano Zampini PetscInt psize; 26835a1e936bSStefano Zampini PetscBool fake = PETSC_FALSE, isfieldsplit; 2684e1214c54Sstefano_zampini 268515579a77SStefano Zampini ierr = ISViewFromOptions(fetidpmat_ctx->lagrange,NULL,"-lag_view");CHKERRQ(ierr); 268615579a77SStefano Zampini ierr = ISViewFromOptions(fetidpmat_ctx->pressure,NULL,"-press_view");CHKERRQ(ierr); 2687e1214c54Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_PPmat",(PetscObject*)&M);CHKERRQ(ierr); 2688e1214c54Sstefano_zampini ierr = PCSetType(newpc,PCFIELDSPLIT);CHKERRQ(ierr); 2689e1214c54Sstefano_zampini ierr = PCFieldSplitSetIS(newpc,"lag",fetidpmat_ctx->lagrange);CHKERRQ(ierr); 2690e1214c54Sstefano_zampini ierr = PCFieldSplitSetIS(newpc,"p",fetidpmat_ctx->pressure);CHKERRQ(ierr); 2691e1214c54Sstefano_zampini ierr = PCFieldSplitSetType(newpc,PC_COMPOSITE_SCHUR);CHKERRQ(ierr); 269240c75d76SStefano Zampini ierr = PCFieldSplitSetSchurFactType(newpc,PC_FIELDSPLIT_SCHUR_FACT_DIAG);CHKERRQ(ierr); 26935a1e936bSStefano Zampini ierr = ISGetSize(fetidpmat_ctx->pressure,&psize);CHKERRQ(ierr); 26945a1e936bSStefano Zampini if (psize != M->rmap->N) { 26955a1e936bSStefano Zampini Mat M2; 26965a1e936bSStefano Zampini PetscInt lpsize; 26975a1e936bSStefano Zampini 26985a1e936bSStefano Zampini fake = PETSC_TRUE; 26995a1e936bSStefano Zampini ierr = ISGetLocalSize(fetidpmat_ctx->pressure,&lpsize);CHKERRQ(ierr); 27005a1e936bSStefano Zampini ierr = MatCreate(comm,&M2);CHKERRQ(ierr); 27015a1e936bSStefano Zampini ierr = MatSetType(M2,MATAIJ);CHKERRQ(ierr); 27025a1e936bSStefano Zampini ierr = MatSetSizes(M2,lpsize,lpsize,psize,psize);CHKERRQ(ierr); 27035a1e936bSStefano Zampini ierr = MatSetUp(M2);CHKERRQ(ierr); 27045a1e936bSStefano Zampini ierr = MatAssemblyBegin(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27055a1e936bSStefano Zampini ierr = MatAssemblyEnd(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27065a1e936bSStefano Zampini ierr = PCFieldSplitSetSchurPre(newpc,PC_FIELDSPLIT_SCHUR_PRE_USER,M2);CHKERRQ(ierr); 27075a1e936bSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 27085a1e936bSStefano Zampini } else { 2709e1214c54Sstefano_zampini ierr = PCFieldSplitSetSchurPre(newpc,PC_FIELDSPLIT_SCHUR_PRE_USER,M);CHKERRQ(ierr); 27105a1e936bSStefano Zampini } 2711c096484dSStefano Zampini ierr = PCFieldSplitSetSchurScale(newpc,1.0);CHKERRQ(ierr); 271215579a77SStefano Zampini 271315579a77SStefano Zampini /* we need to setfromoptions and setup here to access the blocks */ 2714e1214c54Sstefano_zampini ierr = PCSetFromOptions(newpc);CHKERRQ(ierr); 2715e1214c54Sstefano_zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 2716e1214c54Sstefano_zampini 27175a1e936bSStefano Zampini /* user may have changed the type (e.g. -fetidp_pc_type none) */ 27185a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)newpc,PCFIELDSPLIT,&isfieldsplit);CHKERRQ(ierr); 27195a1e936bSStefano Zampini if (isfieldsplit) { 27205a1e936bSStefano Zampini KSP *ksps; 27215a1e936bSStefano Zampini PC ppc,lagpc; 27225a1e936bSStefano Zampini PetscInt nn; 2723064a4176SStefano Zampini PetscBool ismatis,matisok = PETSC_FALSE,check = PETSC_FALSE; 27245a1e936bSStefano Zampini 2725e1214c54Sstefano_zampini /* set the solver for the (0,0) block */ 27265a1e936bSStefano Zampini ierr = PCFieldSplitSchurGetSubKSP(newpc,&nn,&ksps);CHKERRQ(ierr); 27275a1e936bSStefano Zampini if (!nn) { /* not of type PC_COMPOSITE_SCHUR */ 272840c75d76SStefano Zampini ierr = PCFieldSplitGetSubKSP(newpc,&nn,&ksps);CHKERRQ(ierr); 27295a1e936bSStefano Zampini if (!fake) { /* pass pmat to the pressure solver */ 27305a1e936bSStefano Zampini Mat F; 27315a1e936bSStefano Zampini 27325a1e936bSStefano Zampini ierr = KSPGetOperators(ksps[1],&F,NULL);CHKERRQ(ierr); 27335a1e936bSStefano Zampini ierr = KSPSetOperators(ksps[1],F,M);CHKERRQ(ierr); 27345a1e936bSStefano Zampini } 27355a1e936bSStefano Zampini } else { 27365a1e936bSStefano Zampini PetscBool issym; 27375a1e936bSStefano Zampini Mat S; 27385a1e936bSStefano Zampini 27395a1e936bSStefano Zampini ierr = PCFieldSplitSchurGetS(newpc,&S);CHKERRQ(ierr); 27405a1e936bSStefano Zampini 27415a1e936bSStefano Zampini ierr = MatGetOption(newmat,MAT_SYMMETRIC,&issym);CHKERRQ(ierr); 27425a1e936bSStefano Zampini if (issym) { 27435a1e936bSStefano Zampini ierr = MatSetOption(S,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 27445a1e936bSStefano Zampini } 27455a1e936bSStefano Zampini } 27465a1e936bSStefano Zampini ierr = KSPGetPC(ksps[0],&lagpc);CHKERRQ(ierr); 2747e1214c54Sstefano_zampini ierr = PCSetType(lagpc,PCSHELL);CHKERRQ(ierr); 27485a1e936bSStefano Zampini ierr = PCShellSetName(lagpc,"FETI-DP multipliers");CHKERRQ(ierr); 2749e1214c54Sstefano_zampini ierr = PCShellSetContext(lagpc,fetidppc_ctx);CHKERRQ(ierr); 2750e1214c54Sstefano_zampini ierr = PCShellSetApply(lagpc,FETIDPPCApply);CHKERRQ(ierr); 2751e1214c54Sstefano_zampini ierr = PCShellSetApplyTranspose(lagpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 2752e1214c54Sstefano_zampini ierr = PCShellSetView(lagpc,FETIDPPCView);CHKERRQ(ierr); 2753e1214c54Sstefano_zampini ierr = PCShellSetDestroy(lagpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 27545a1e936bSStefano Zampini 27555a1e936bSStefano Zampini /* Olof's idea: interface Schur complement preconditioner for the mass matrix */ 27565a1e936bSStefano Zampini ierr = KSPGetPC(ksps[1],&ppc);CHKERRQ(ierr); 27575a1e936bSStefano Zampini if (fake) { 27585a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 2759ff11fd76SStefano Zampini PetscContainer c; 27605a1e936bSStefano Zampini 27615a1e936bSStefano Zampini matisok = PETSC_TRUE; 27625a1e936bSStefano Zampini 27635a1e936bSStefano Zampini /* create inner BDDC solver */ 27645a1e936bSStefano Zampini ierr = PetscNew(&bddcipc_ctx);CHKERRQ(ierr); 27655a1e936bSStefano Zampini ierr = PCCreate(comm,&bddcipc_ctx->bddc);CHKERRQ(ierr); 27665a1e936bSStefano Zampini ierr = PCSetType(bddcipc_ctx->bddc,PCBDDC);CHKERRQ(ierr); 27675a1e936bSStefano Zampini ierr = PCSetOperators(bddcipc_ctx->bddc,M,M);CHKERRQ(ierr); 2768ff11fd76SStefano Zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_pCSR",(PetscObject*)&c);CHKERRQ(ierr); 2769ff11fd76SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)M,MATIS,&ismatis);CHKERRQ(ierr); 2770ff11fd76SStefano Zampini if (c && ismatis) { 2771ff11fd76SStefano Zampini Mat lM; 2772ff11fd76SStefano Zampini PetscInt *csr,n; 2773ff11fd76SStefano Zampini 2774ff11fd76SStefano Zampini ierr = MatISGetLocalMat(M,&lM);CHKERRQ(ierr); 2775ff11fd76SStefano Zampini ierr = MatGetSize(lM,&n,NULL);CHKERRQ(ierr); 2776ff11fd76SStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&csr);CHKERRQ(ierr); 2777ff11fd76SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(bddcipc_ctx->bddc,n,csr,csr + (n + 1),PETSC_COPY_VALUES);CHKERRQ(ierr); 2778ff11fd76SStefano Zampini ierr = MatISRestoreLocalMat(M,&lM);CHKERRQ(ierr); 2779ff11fd76SStefano Zampini } 27805a1e936bSStefano Zampini ierr = PCSetOptionsPrefix(bddcipc_ctx->bddc,((PetscObject)ksps[1])->prefix);CHKERRQ(ierr); 27815a1e936bSStefano Zampini ierr = PCSetErrorIfFailure(bddcipc_ctx->bddc,pc->erroriffailure);CHKERRQ(ierr); 27825a1e936bSStefano Zampini ierr = PCSetFromOptions(bddcipc_ctx->bddc);CHKERRQ(ierr); 27835a1e936bSStefano Zampini 27845a1e936bSStefano Zampini /* wrap the interface application */ 27855a1e936bSStefano Zampini ierr = PCSetType(ppc,PCSHELL);CHKERRQ(ierr); 27865a1e936bSStefano Zampini ierr = PCShellSetName(ppc,"FETI-DP pressure");CHKERRQ(ierr); 27875a1e936bSStefano Zampini ierr = PCShellSetContext(ppc,bddcipc_ctx);CHKERRQ(ierr); 27885a1e936bSStefano Zampini ierr = PCShellSetSetUp(ppc,PCSetUp_BDDCIPC);CHKERRQ(ierr); 27895a1e936bSStefano Zampini ierr = PCShellSetApply(ppc,PCApply_BDDCIPC);CHKERRQ(ierr); 27905a1e936bSStefano Zampini ierr = PCShellSetApplyTranspose(ppc,PCApplyTranspose_BDDCIPC);CHKERRQ(ierr); 27915a1e936bSStefano Zampini ierr = PCShellSetView(ppc,PCView_BDDCIPC);CHKERRQ(ierr); 27925a1e936bSStefano Zampini ierr = PCShellSetDestroy(ppc,PCDestroy_BDDCIPC);CHKERRQ(ierr); 27935a1e936bSStefano Zampini } 27945a1e936bSStefano Zampini 27955a1e936bSStefano Zampini /* determine if we need to assemble M to construct a preconditioner */ 27965a1e936bSStefano Zampini if (!matisok) { 27975a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)M,MATIS,&ismatis);CHKERRQ(ierr); 27985a1e936bSStefano Zampini ierr = PetscObjectTypeCompareAny((PetscObject)ppc,&matisok,PCBDDC,PCJACOBI,PCNONE,PCMG,"");CHKERRQ(ierr); 27995a1e936bSStefano Zampini if (ismatis && !matisok) { 28005a1e936bSStefano Zampini ierr = MatConvert(M,MATAIJ,MAT_INPLACE_MATRIX,&M);CHKERRQ(ierr); 28015a1e936bSStefano Zampini } 28025a1e936bSStefano Zampini } 2803064a4176SStefano Zampini 2804064a4176SStefano Zampini /* run the subproblems to check convergence */ 2805064a4176SStefano Zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)newmat)->prefix,"-check_saddlepoint",&check,NULL);CHKERRQ(ierr); 2806064a4176SStefano Zampini if (check) { 2807064a4176SStefano Zampini PetscInt i; 2808064a4176SStefano Zampini 2809064a4176SStefano Zampini for (i=0;i<nn;i++) { 2810064a4176SStefano Zampini KSP kspC; 2811064a4176SStefano Zampini PC pc; 2812064a4176SStefano Zampini Mat F,pF; 2813064a4176SStefano Zampini Vec x,y; 2814064a4176SStefano Zampini PetscBool isschur,prec = PETSC_TRUE; 2815064a4176SStefano Zampini 2816064a4176SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)ksps[i]),&kspC);CHKERRQ(ierr); 2817064a4176SStefano Zampini ierr = KSPSetOptionsPrefix(kspC,((PetscObject)ksps[i])->prefix);CHKERRQ(ierr); 2818064a4176SStefano Zampini ierr = KSPAppendOptionsPrefix(kspC,"check_");CHKERRQ(ierr); 2819064a4176SStefano Zampini ierr = KSPGetOperators(ksps[i],&F,&pF);CHKERRQ(ierr); 2820064a4176SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)F,MATSCHURCOMPLEMENT,&isschur);CHKERRQ(ierr); 2821064a4176SStefano Zampini if (isschur) { 2822064a4176SStefano Zampini KSP kspS,kspS2; 2823064a4176SStefano Zampini Mat A00,pA00,A10,A01,A11; 2824064a4176SStefano Zampini char prefix[256]; 2825064a4176SStefano Zampini 2826064a4176SStefano Zampini ierr = MatSchurComplementGetKSP(F,&kspS);CHKERRQ(ierr); 2827064a4176SStefano Zampini ierr = MatSchurComplementGetSubMatrices(F,&A00,&pA00,&A01,&A10,&A11);CHKERRQ(ierr); 2828064a4176SStefano Zampini ierr = MatCreateSchurComplement(A00,pA00,A01,A10,A11,&F);CHKERRQ(ierr); 2829064a4176SStefano Zampini ierr = MatSchurComplementGetKSP(F,&kspS2);CHKERRQ(ierr); 2830064a4176SStefano Zampini ierr = PetscSNPrintf(prefix,sizeof(prefix),"%sschur_",((PetscObject)kspC)->prefix);CHKERRQ(ierr); 2831064a4176SStefano Zampini ierr = KSPSetOptionsPrefix(kspS2,prefix);CHKERRQ(ierr); 2832064a4176SStefano Zampini ierr = KSPGetPC(kspS2,&pc);CHKERRQ(ierr); 2833064a4176SStefano Zampini ierr = PCSetType(pc,PCKSP);CHKERRQ(ierr); 2834064a4176SStefano Zampini ierr = PCKSPSetKSP(pc,kspS);CHKERRQ(ierr); 2835064a4176SStefano Zampini ierr = KSPSetFromOptions(kspS2);CHKERRQ(ierr); 2836064a4176SStefano Zampini ierr = KSPGetPC(kspS2,&pc);CHKERRQ(ierr); 2837064a4176SStefano Zampini ierr = PCSetUseAmat(pc,PETSC_TRUE);CHKERRQ(ierr); 2838064a4176SStefano Zampini } else { 2839064a4176SStefano Zampini ierr = PetscObjectReference((PetscObject)F);CHKERRQ(ierr); 2840064a4176SStefano Zampini } 2841064a4176SStefano Zampini ierr = KSPSetFromOptions(kspC);CHKERRQ(ierr); 2842064a4176SStefano Zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)kspC)->prefix,"-preconditioned",&prec,NULL);CHKERRQ(ierr); 2843064a4176SStefano Zampini if (prec) { 2844064a4176SStefano Zampini ierr = KSPGetPC(ksps[i],&pc);CHKERRQ(ierr); 2845064a4176SStefano Zampini ierr = KSPSetPC(kspC,pc);CHKERRQ(ierr); 2846064a4176SStefano Zampini } 2847064a4176SStefano Zampini ierr = KSPSetOperators(kspC,F,pF);CHKERRQ(ierr); 2848064a4176SStefano Zampini ierr = MatCreateVecs(F,&x,&y);CHKERRQ(ierr); 2849064a4176SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 2850064a4176SStefano Zampini ierr = MatMult(F,x,y);CHKERRQ(ierr); 2851064a4176SStefano Zampini ierr = KSPSolve(kspC,y,x);CHKERRQ(ierr); 2852c0decd05SBarry Smith ierr = KSPCheckSolve(kspC,pc,x);CHKERRQ(ierr); 2853064a4176SStefano Zampini ierr = KSPDestroy(&kspC);CHKERRQ(ierr); 2854064a4176SStefano Zampini ierr = MatDestroy(&F);CHKERRQ(ierr); 2855064a4176SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2856064a4176SStefano Zampini ierr = VecDestroy(&y);CHKERRQ(ierr); 2857064a4176SStefano Zampini } 2858064a4176SStefano Zampini } 2859e1214c54Sstefano_zampini ierr = PetscFree(ksps);CHKERRQ(ierr); 2860e1214c54Sstefano_zampini } 28615a1e936bSStefano Zampini } 28623425bc38SStefano Zampini /* return pointers for objects created */ 28633425bc38SStefano Zampini *fetidp_mat = newmat; 28643425bc38SStefano Zampini *fetidp_pc = newpc; 28653425bc38SStefano Zampini PetscFunctionReturn(0); 28663425bc38SStefano Zampini } 28671e6b0712SBarry Smith 286894ef8ddeSSatish Balay /*@C 28690f202f7eSStefano Zampini PCBDDCCreateFETIDPOperators - Create FETI-DP operators 28703425bc38SStefano Zampini 28713425bc38SStefano Zampini Collective 28723425bc38SStefano Zampini 28733425bc38SStefano Zampini Input Parameters: 28741720468bSStefano Zampini + pc - the BDDC preconditioning context (setup should have been called before) 2875547c9a8eSstefano_zampini . fully_redundant - true for a fully redundant set of Lagrange multipliers 2876547c9a8eSstefano_zampini - prefix - optional options database prefix for the objects to be created (can be NULL) 287728509bceSStefano Zampini 287828509bceSStefano Zampini Output Parameters: 28790f202f7eSStefano Zampini + fetidp_mat - shell FETI-DP matrix object 28800f202f7eSStefano Zampini - fetidp_pc - shell Dirichlet preconditioner for FETI-DP matrix 288128509bceSStefano Zampini 28823425bc38SStefano Zampini Level: developer 28833425bc38SStefano Zampini 28843425bc38SStefano Zampini Notes: 28850f202f7eSStefano Zampini Currently the only operations provided for FETI-DP matrix are MatMult and MatMultTranspose 28863425bc38SStefano Zampini 28870f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCMatFETIDPGetRHS, PCBDDCMatFETIDPGetSolution 28883425bc38SStefano Zampini @*/ 2889547c9a8eSstefano_zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, PetscBool fully_redundant, const char *prefix, Mat *fetidp_mat, PC *fetidp_pc) 28903425bc38SStefano Zampini { 28913425bc38SStefano Zampini PetscErrorCode ierr; 28923425bc38SStefano Zampini 28933425bc38SStefano Zampini PetscFunctionBegin; 28943425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 28953425bc38SStefano Zampini if (pc->setupcalled) { 2896547c9a8eSstefano_zampini ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,PetscBool,const char*,Mat*,PC*),(pc,fully_redundant,prefix,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 28976080607fSStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"You must call PCSetup_BDDC() first"); 28983425bc38SStefano Zampini PetscFunctionReturn(0); 28993425bc38SStefano Zampini } 29000c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2901da1bb401SStefano Zampini /*MC 2902da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 29030c7d97c5SJed Brown 290428509bceSStefano Zampini An implementation of the BDDC preconditioner based on 290528509bceSStefano Zampini 290628509bceSStefano Zampini .vb 290728509bceSStefano Zampini [1] C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 2908a8d69d7bSBarry Smith [2] A. Klawonn and O. B. Widlund. "Dual-Primal FETI Methods for Linear Elasticity", https://cs.nyu.edu/dynamic/reports/?year=all 2909a8d69d7bSBarry Smith [3] J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", https://arxiv.org/abs/0712.3977 29100f202f7eSStefano 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 291128509bceSStefano Zampini .ve 291228509bceSStefano Zampini 291328509bceSStefano Zampini The matrix to be preconditioned (Pmat) must be of type MATIS. 291428509bceSStefano Zampini 29150f202f7eSStefano Zampini Currently works with MATIS matrices with local matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers. 291628509bceSStefano Zampini 291728509bceSStefano Zampini It also works with unsymmetric and indefinite problems. 291828509bceSStefano Zampini 2919b6fdb6dfSStefano 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. 2920b6fdb6dfSStefano Zampini 2921c7017625SStefano 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). 292228509bceSStefano Zampini 29230f202f7eSStefano 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() 292430368db7SStefano Zampini Additional information on dofs can be provided by using PCBDDCSetDofsSplitting(), PCBDDCSetDirichletBoundaries(), PCBDDCSetNeumannBoundaries(), and PCBDDCSetPrimalVerticesIS() and their local counterparts. 292528509bceSStefano Zampini 29260f202f7eSStefano Zampini Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace(). Non-singular modes are retained via SVD. 292728509bceSStefano Zampini 29280f202f7eSStefano 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. 29290f202f7eSStefano Zampini User defined change of basis can be passed to PCBDDC by using PCBDDCSetChangeOfBasisMat() 293028509bceSStefano Zampini 29310f202f7eSStefano Zampini The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using a MatPartitioning object. 293228509bceSStefano Zampini 2933df4d28bfSStefano 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. 293428509bceSStefano Zampini 29350f202f7eSStefano 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. 29360f202f7eSStefano Zampini Deluxe scaling is not supported yet for FETI-DP. 29370f202f7eSStefano Zampini 29380f202f7eSStefano Zampini Options Database Keys (some of them, run with -h for a complete list): 29390f202f7eSStefano Zampini 2940a2b725a8SWilliam Gropp + -pc_bddc_use_vertices <true> - use or not vertices in primal space 29410f202f7eSStefano Zampini . -pc_bddc_use_edges <true> - use or not edges in primal space 29420f202f7eSStefano Zampini . -pc_bddc_use_faces <false> - use or not faces in primal space 29430f202f7eSStefano Zampini . -pc_bddc_symmetric <true> - symmetric computation of primal basis functions. Specify false for unsymmetric problems 29440f202f7eSStefano Zampini . -pc_bddc_use_change_of_basis <false> - use change of basis approach (on edges only) 29450f202f7eSStefano Zampini . -pc_bddc_use_change_on_faces <false> - use change of basis approach on faces if change of basis has been requested 29460f202f7eSStefano Zampini . -pc_bddc_switch_static <false> - switches from M_2 (default) to M_3 operator (see reference article [1]) 294728509bceSStefano Zampini . -pc_bddc_levels <0> - maximum number of levels for multilevel 29480f202f7eSStefano 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) 29495459c157SBarry 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) 29500f202f7eSStefano Zampini . -pc_bddc_use_deluxe_scaling <false> - use deluxe scaling 2951*71f2caa7Sprj- . -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) 2952bd2a564bSStefano 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) 295328509bceSStefano Zampini - -pc_bddc_check_level <0> - set verbosity level of debugging output 295428509bceSStefano Zampini 295528509bceSStefano Zampini Options for Dirichlet, Neumann or coarse solver can be set with 295628509bceSStefano Zampini .vb 295728509bceSStefano Zampini -pc_bddc_dirichlet_ 295828509bceSStefano Zampini -pc_bddc_neumann_ 295928509bceSStefano Zampini -pc_bddc_coarse_ 296028509bceSStefano Zampini .ve 2961f9ff08acSPierre Jolivet e.g. -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg. PCBDDC uses by default KSPPREONLY and PCLU. 296228509bceSStefano Zampini 29630f202f7eSStefano Zampini When using a multilevel approach, solvers' options at the N-th level (N > 1) can be specified as 296428509bceSStefano Zampini .vb 2965312be037SStefano Zampini -pc_bddc_dirichlet_lN_ 2966312be037SStefano Zampini -pc_bddc_neumann_lN_ 2967312be037SStefano Zampini -pc_bddc_coarse_lN_ 296828509bceSStefano Zampini .ve 29690f202f7eSStefano Zampini Note that level number ranges from the finest (0) to the coarsest (N). 29700f202f7eSStefano 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. 29710f202f7eSStefano Zampini .vb 29720f202f7eSStefano Zampini -pc_bddc_coarse_pc_bddc_adaptive_threshold 5 -pc_bddc_coarse_l1_pc_bddc_redistribute 3 29730f202f7eSStefano Zampini .ve 29740f202f7eSStefano 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 2975da1bb401SStefano Zampini 2976da1bb401SStefano Zampini Level: intermediate 2977da1bb401SStefano Zampini 2978e94cfbe0SPatrick Sanan Developer Notes: 2979da1bb401SStefano Zampini 2980da1bb401SStefano Zampini Contributed by Stefano Zampini 2981da1bb401SStefano Zampini 2982da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 2983da1bb401SStefano Zampini M*/ 2984b2573a8aSBarry Smith 29858cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 2986da1bb401SStefano Zampini { 2987da1bb401SStefano Zampini PetscErrorCode ierr; 2988da1bb401SStefano Zampini PC_BDDC *pcbddc; 2989da1bb401SStefano Zampini 2990da1bb401SStefano Zampini PetscFunctionBegin; 2991b00a9115SJed Brown ierr = PetscNewLog(pc,&pcbddc);CHKERRQ(ierr); 2992da1bb401SStefano Zampini pc->data = (void*)pcbddc; 2993da1bb401SStefano Zampini 2994da1bb401SStefano Zampini /* create PCIS data structure */ 2995da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 2996da1bb401SStefano Zampini 29979326c5c6Sstefano_zampini /* create local graph structure */ 29989326c5c6Sstefano_zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 29999326c5c6Sstefano_zampini 30009326c5c6Sstefano_zampini /* BDDC nonzero defaults */ 30016d9e27e4SStefano Zampini pcbddc->use_nnsp = PETSC_TRUE; 300208a5cf49SStefano Zampini pcbddc->use_local_adj = PETSC_TRUE; 300347d04d0dSStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 300447d04d0dSStefano Zampini pcbddc->use_edges = PETSC_TRUE; 30053301b35fSStefano Zampini pcbddc->symmetric_primal = PETSC_TRUE; 300614f95afaSStefano Zampini pcbddc->vertex_size = 1; 3007c703fcc7SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 300868457ee5SStefano Zampini pcbddc->coarse_size = -1; 300985c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 301047d04d0dSStefano Zampini pcbddc->coarsening_ratio = 8; 301157de7509SStefano Zampini pcbddc->coarse_eqs_per_proc = 1; 301227b6a85dSStefano Zampini pcbddc->benign_compute_correction = PETSC_TRUE; 30131e0482f5SStefano Zampini pcbddc->nedfield = -1; 30141e0482f5SStefano Zampini pcbddc->nedglobal = PETSC_TRUE; 3015be12c134Sstefano_zampini pcbddc->graphmaxcount = PETSC_MAX_INT; 3016b96c3477SStefano Zampini pcbddc->sub_schurs_layers = -1; 3017bd2a564bSStefano Zampini pcbddc->adaptive_threshold[0] = 0.0; 3018bd2a564bSStefano Zampini pcbddc->adaptive_threshold[1] = 0.0; 3019b7eb3628SStefano Zampini 3020da1bb401SStefano Zampini /* function pointers */ 3021da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 302293bd9ae7SStefano Zampini pc->ops->applytranspose = PCApplyTranspose_BDDC; 3023da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 3024da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 3025da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 30266b78500eSPatrick Sanan pc->ops->view = PCView_BDDC; 3027da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 3028da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 3029da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 3030534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 3031534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 30329326c5c6Sstefano_zampini pc->ops->reset = PCReset_BDDC; 3033da1bb401SStefano Zampini 3034da1bb401SStefano Zampini /* composing function */ 3035a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",PCBDDCSetDiscreteGradient_BDDC);CHKERRQ(ierr); 3036a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",PCBDDCSetDivergenceMat_BDDC);CHKERRQ(ierr); 3037906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",PCBDDCSetChangeOfBasisMat_BDDC);CHKERRQ(ierr); 3038674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 303930368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",PCBDDCSetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 30403100ebe3SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetPrimalVerticesLocalIS_C",PCBDDCGetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 30413100ebe3SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetPrimalVerticesIS_C",PCBDDCGetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 3042bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 30432b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr); 3044b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr); 30452b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr); 3046bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 304782ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 3048bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 304982ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 3050bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 305182ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 3052bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 305382ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 3054bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 305563602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",PCBDDCSetDofsSplittingLocal_BDDC);CHKERRQ(ierr); 3056bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 3057bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 3058bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 3059bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 3060a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",PCPreSolveChangeRHS_BDDC);CHKERRQ(ierr); 3061ab8c8b98SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_BDDC);CHKERRQ(ierr); 3062da1bb401SStefano Zampini PetscFunctionReturn(0); 3063da1bb401SStefano Zampini } 306443371fb9SStefano Zampini 306543371fb9SStefano Zampini /*@C 306643371fb9SStefano Zampini PCBDDCInitializePackage - This function initializes everything in the PCBDDC package. It is called 30678a690491SBarry Smith from PCInitializePackage(). 306843371fb9SStefano Zampini 306943371fb9SStefano Zampini Level: developer 307043371fb9SStefano Zampini 307143371fb9SStefano Zampini .seealso: PetscInitialize() 307243371fb9SStefano Zampini @*/ 307343371fb9SStefano Zampini PetscErrorCode PCBDDCInitializePackage(void) 307443371fb9SStefano Zampini { 307543371fb9SStefano Zampini PetscErrorCode ierr; 307643371fb9SStefano Zampini int i; 307743371fb9SStefano Zampini 307843371fb9SStefano Zampini PetscFunctionBegin; 307943371fb9SStefano Zampini if (PCBDDCPackageInitialized) PetscFunctionReturn(0); 308043371fb9SStefano Zampini PCBDDCPackageInitialized = PETSC_TRUE; 308143371fb9SStefano Zampini ierr = PetscRegisterFinalize(PCBDDCFinalizePackage);CHKERRQ(ierr); 308243371fb9SStefano Zampini 308343371fb9SStefano Zampini /* general events */ 308443371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCTopo",PC_CLASSID,&PC_BDDC_Topology[0]);CHKERRQ(ierr); 308543371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCLKSP",PC_CLASSID,&PC_BDDC_LocalSolvers[0]);CHKERRQ(ierr); 308643371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCLWor",PC_CLASSID,&PC_BDDC_LocalWork[0]);CHKERRQ(ierr); 308743371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCorr",PC_CLASSID,&PC_BDDC_CorrectionSetUp[0]);CHKERRQ(ierr); 30888ead10e4SStefano Zampini ierr = PetscLogEventRegister("PCBDDCASet",PC_CLASSID,&PC_BDDC_ApproxSetUp[0]);CHKERRQ(ierr); 30898ead10e4SStefano Zampini ierr = PetscLogEventRegister("PCBDDCAApp",PC_CLASSID,&PC_BDDC_ApproxApply[0]);CHKERRQ(ierr); 309043371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCSet",PC_CLASSID,&PC_BDDC_CoarseSetUp[0]);CHKERRQ(ierr); 309143371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCKSP",PC_CLASSID,&PC_BDDC_CoarseSolver[0]);CHKERRQ(ierr); 309243371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCAdap",PC_CLASSID,&PC_BDDC_AdaptiveSetUp[0]);CHKERRQ(ierr); 309343371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCScal",PC_CLASSID,&PC_BDDC_Scaling[0]);CHKERRQ(ierr); 309443371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCSchr",PC_CLASSID,&PC_BDDC_Schurs[0]);CHKERRQ(ierr); 309543371fb9SStefano Zampini for (i=1;i<PETSC_PCBDDC_MAXLEVELS;i++) { 309643371fb9SStefano Zampini char ename[32]; 309743371fb9SStefano Zampini 309843371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCTopo l%02d",i);CHKERRQ(ierr); 309943371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Topology[i]);CHKERRQ(ierr); 310043371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCLKSP l%02d",i);CHKERRQ(ierr); 310143371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_LocalSolvers[i]);CHKERRQ(ierr); 310243371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCLWor l%02d",i);CHKERRQ(ierr); 310343371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_LocalWork[i]);CHKERRQ(ierr); 310443371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCorr l%02d",i);CHKERRQ(ierr); 310543371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CorrectionSetUp[i]);CHKERRQ(ierr); 31068ead10e4SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCASet l%02d",i);CHKERRQ(ierr); 31078ead10e4SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_ApproxSetUp[i]);CHKERRQ(ierr); 31088ead10e4SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCAApp l%02d",i);CHKERRQ(ierr); 31098ead10e4SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_ApproxApply[i]);CHKERRQ(ierr); 311043371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCSet l%02d",i);CHKERRQ(ierr); 311143371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CoarseSetUp[i]);CHKERRQ(ierr); 311243371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCKSP l%02d",i);CHKERRQ(ierr); 311343371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CoarseSolver[i]);CHKERRQ(ierr); 311443371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCAdap l%02d",i);CHKERRQ(ierr); 311543371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_AdaptiveSetUp[i]);CHKERRQ(ierr); 311643371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCScal l%02d",i);CHKERRQ(ierr); 311743371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Scaling[i]);CHKERRQ(ierr); 311843371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCSchr l%02d",i);CHKERRQ(ierr); 311943371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Schurs[i]);CHKERRQ(ierr); 312043371fb9SStefano Zampini } 312143371fb9SStefano Zampini PetscFunctionReturn(0); 312243371fb9SStefano Zampini } 312343371fb9SStefano Zampini 312443371fb9SStefano Zampini /*@C 312543371fb9SStefano Zampini PCBDDCFinalizePackage - This function frees everything from the PCBDDC package. It is 312643371fb9SStefano Zampini called from PetscFinalize() automatically. 312743371fb9SStefano Zampini 312843371fb9SStefano Zampini Level: developer 312943371fb9SStefano Zampini 313043371fb9SStefano Zampini .seealso: PetscFinalize() 313143371fb9SStefano Zampini @*/ 313243371fb9SStefano Zampini PetscErrorCode PCBDDCFinalizePackage(void) 313343371fb9SStefano Zampini { 313443371fb9SStefano Zampini PetscFunctionBegin; 313543371fb9SStefano Zampini PCBDDCPackageInitialized = PETSC_FALSE; 313643371fb9SStefano Zampini PetscFunctionReturn(0); 313743371fb9SStefano Zampini } 3138