153cdbc3dSStefano Zampini /* TODOLIST 2eb97c9d2SStefano Zampini 3eb97c9d2SStefano Zampini Solvers 4a0d3c3abSStefano Zampini - Add support for cholesky for coarse solver (similar to local solvers) 5eb97c9d2SStefano Zampini - Propagate ksp prefixes for solvers to mat objects? 6eb97c9d2SStefano Zampini 7eb97c9d2SStefano Zampini User interface 80f202f7eSStefano Zampini - ** DM attached to pc? 9eb97c9d2SStefano Zampini 10eb97c9d2SStefano Zampini Debugging output 11b9b85e73SStefano Zampini - * Better management of verbosity levels of debugging output 12eb97c9d2SStefano Zampini 13eb97c9d2SStefano Zampini Extra 14b9b85e73SStefano Zampini - *** Is it possible to work with PCBDDCGraph on boundary indices only (less memory consumed)? 15eb97c9d2SStefano Zampini - BDDC with MG framework? 16eb97c9d2SStefano Zampini 17eb97c9d2SStefano Zampini MATIS related operations contained in BDDC code 18eb97c9d2SStefano Zampini - Provide general case for subassembling 19eb97c9d2SStefano Zampini 2053cdbc3dSStefano Zampini */ 210c7d97c5SJed Brown 22ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 23ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 243b03a366Sstefano_zampini #include <petscblaslapack.h> 25674ae819SStefano Zampini 2643371fb9SStefano Zampini static PetscBool PCBDDCPackageInitialized = PETSC_FALSE; 2743371fb9SStefano Zampini 28f3d41395Sstefano_zampini static PetscBool cited = PETSC_FALSE; 29f3d41395Sstefano_zampini static const char citation[] = 30f3d41395Sstefano_zampini "@article{ZampiniPCBDDC,\n" 31f3d41395Sstefano_zampini "author = {Stefano Zampini},\n" 32f3d41395Sstefano_zampini "title = {{PCBDDC}: A Class of Robust Dual-Primal Methods in {PETS}c},\n" 33f3d41395Sstefano_zampini "journal = {SIAM Journal on Scientific Computing},\n" 34f3d41395Sstefano_zampini "volume = {38},\n" 35f3d41395Sstefano_zampini "number = {5},\n" 36f3d41395Sstefano_zampini "pages = {S282-S306},\n" 37f3d41395Sstefano_zampini "year = {2016},\n" 38f3d41395Sstefano_zampini "doi = {10.1137/15M1025785},\n" 39f3d41395Sstefano_zampini "URL = {http://dx.doi.org/10.1137/15M1025785},\n" 40f3d41395Sstefano_zampini "eprint = {http://dx.doi.org/10.1137/15M1025785}\n" 41f3d41395Sstefano_zampini "}\n"; 42f3d41395Sstefano_zampini 4343371fb9SStefano Zampini PetscLogEvent PC_BDDC_Topology[PETSC_PCBDDC_MAXLEVELS]; 4443371fb9SStefano Zampini PetscLogEvent PC_BDDC_LocalSolvers[PETSC_PCBDDC_MAXLEVELS]; 4543371fb9SStefano Zampini PetscLogEvent PC_BDDC_LocalWork[PETSC_PCBDDC_MAXLEVELS]; 4643371fb9SStefano Zampini PetscLogEvent PC_BDDC_CorrectionSetUp[PETSC_PCBDDC_MAXLEVELS]; 4743371fb9SStefano Zampini PetscLogEvent PC_BDDC_CoarseSetUp[PETSC_PCBDDC_MAXLEVELS]; 4843371fb9SStefano Zampini PetscLogEvent PC_BDDC_CoarseSolver[PETSC_PCBDDC_MAXLEVELS]; 4943371fb9SStefano Zampini PetscLogEvent PC_BDDC_AdaptiveSetUp[PETSC_PCBDDC_MAXLEVELS]; 5043371fb9SStefano Zampini PetscLogEvent PC_BDDC_Scaling[PETSC_PCBDDC_MAXLEVELS]; 5143371fb9SStefano Zampini PetscLogEvent PC_BDDC_Schurs[PETSC_PCBDDC_MAXLEVELS]; 5243371fb9SStefano Zampini 530369aaf7SStefano Zampini PetscErrorCode PCApply_BDDC(PC,Vec,Vec); 540369aaf7SStefano Zampini 554416b707SBarry Smith PetscErrorCode PCSetFromOptions_BDDC(PetscOptionItems *PetscOptionsObject,PC pc) 560c7d97c5SJed Brown { 570c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 58e569e4e1SStefano Zampini PetscInt nt,i; 590c7d97c5SJed Brown PetscErrorCode ierr; 600c7d97c5SJed Brown 610c7d97c5SJed Brown PetscFunctionBegin; 62e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"BDDC options");CHKERRQ(ierr); 638eeda7d8SStefano Zampini /* Verbose debugging */ 64a13144ffSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_check_level","Verbose output for PCBDDC (intended for debug)","none",pcbddc->dbg_flag,&pcbddc->dbg_flag,NULL);CHKERRQ(ierr); 65a13144ffSStefano Zampini /* Approximate solvers */ 66c7017625SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_dirichlet_approximate","Inform PCBDDC that we are using approximate Dirichlet solvers","none",pcbddc->NullSpace_corr[0],&pcbddc->NullSpace_corr[0],NULL);CHKERRQ(ierr); 67c7017625SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_dirichlet_approximate_scale","Inform PCBDDC that we need to scale the Dirichlet solve","none",pcbddc->NullSpace_corr[1],&pcbddc->NullSpace_corr[1],NULL);CHKERRQ(ierr); 68c7017625SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_neumann_approximate","Inform PCBDDC that we are using approximate Neumann solvers","none",pcbddc->NullSpace_corr[2],&pcbddc->NullSpace_corr[2],NULL);CHKERRQ(ierr); 69c7017625SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_neumann_approximate_scale","Inform PCBDDC that we need to scale the Neumann solve","none",pcbddc->NullSpace_corr[3],&pcbddc->NullSpace_corr[3],NULL);CHKERRQ(ierr); 706b78500eSPatrick Sanan /* Primal space customization */ 7108a5cf49SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_local_mat_graph","Use or not adjacency graph of local mat for interface analysis","none",pcbddc->use_local_adj,&pcbddc->use_local_adj,NULL);CHKERRQ(ierr); 72be12c134Sstefano_zampini ierr = PetscOptionsInt("-pc_bddc_graph_maxcount","Maximum number of shared subdomains for a connected component","none",pcbddc->graphmaxcount,&pcbddc->graphmaxcount,NULL);CHKERRQ(ierr); 731c7a958bSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_corner_selection","Activates face-based corner selection","none",pcbddc->corner_selection,&pcbddc->corner_selection,NULL);CHKERRQ(ierr); 748eeda7d8SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_vertices","Use or not corner dofs in coarse space","none",pcbddc->use_vertices,&pcbddc->use_vertices,NULL);CHKERRQ(ierr); 758eeda7d8SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_edges","Use or not edge constraints in coarse space","none",pcbddc->use_edges,&pcbddc->use_edges,NULL);CHKERRQ(ierr); 768eeda7d8SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_faces","Use or not face constraints in coarse space","none",pcbddc->use_faces,&pcbddc->use_faces,NULL);CHKERRQ(ierr); 7714f95afaSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_vertex_size","Connected components smaller or equal to vertex size will be considered as primal vertices","none",pcbddc->vertex_size,&pcbddc->vertex_size,NULL);CHKERRQ(ierr); 786661aa1dSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_true_nnsp","Use near null space attached to the matrix without modifications","none",pcbddc->use_nnsp_true,&pcbddc->use_nnsp_true,NULL);CHKERRQ(ierr); 7914f95afaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_qr_single","Use QR factorization for single constraints on cc (QR is always used when multiple constraints are present)","none",pcbddc->use_qr_single,&pcbddc->use_qr_single,NULL);CHKERRQ(ierr); 808eeda7d8SStefano Zampini /* Change of basis */ 81b9b85e73SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_change_of_basis","Use or not internal change of basis on local edge nodes","none",pcbddc->use_change_of_basis,&pcbddc->use_change_of_basis,NULL);CHKERRQ(ierr); 82b9b85e73SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_change_on_faces","Use or not internal change of basis on local face nodes","none",pcbddc->use_change_on_faces,&pcbddc->use_change_on_faces,NULL);CHKERRQ(ierr); 83674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 84674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 85674ae819SStefano Zampini } 868eeda7d8SStefano Zampini /* Switch between M_2 (default) and M_3 preconditioners (as defined by C. Dohrmann in the ref. article) */ 878eeda7d8SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_switch_static","Switch on static condensation ops around the interface preconditioner","none",pcbddc->switch_static,&pcbddc->switch_static,NULL);CHKERRQ(ierr); 88e569e4e1SStefano 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); 89e569e4e1SStefano Zampini i = pcbddc->coarsening_ratio; 90e569e4e1SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","PCBDDCSetCoarseningRatio",i,&i,NULL);CHKERRQ(ierr); 91e569e4e1SStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc,i);CHKERRQ(ierr); 92e569e4e1SStefano Zampini i = pcbddc->max_levels; 93e569e4e1SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_levels","Set maximum number of levels for multilevel","PCBDDCSetLevels",i,&i,NULL);CHKERRQ(ierr); 94e569e4e1SStefano Zampini ierr = PCBDDCSetLevels(pc,i);CHKERRQ(ierr); 95e569e4e1SStefano 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); 96323d395dSStefano 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); 97674ae819SStefano 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); 98b96c3477SStefano 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); 99b96c3477SStefano 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); 100b96c3477SStefano 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); 101683d3df6SStefano 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); 102bf3a8328SStefano 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); 103839e9adbSstefano_zampini ierr = PetscOptionsBool("-pc_bddc_deluxe_singlemat","Collapse deluxe operators","none",pcbddc->deluxe_singlemat,&pcbddc->deluxe_singlemat,NULL);CHKERRQ(ierr); 104bf3a8328SStefano 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); 105bd2a564bSStefano Zampini nt = 2; 106bd2a564bSStefano Zampini ierr = PetscOptionsRealArray("-pc_bddc_adaptive_threshold","Thresholds to be used for adaptive selection of constraints","none",pcbddc->adaptive_threshold,&nt,NULL);CHKERRQ(ierr); 107bd2a564bSStefano Zampini if (nt == 1) pcbddc->adaptive_threshold[1] = pcbddc->adaptive_threshold[0]; 10808122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmin","Minimum number of constraints per connected components","none",pcbddc->adaptive_nmin,&pcbddc->adaptive_nmin,NULL);CHKERRQ(ierr); 10908122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmax","Maximum number of constraints per connected components","none",pcbddc->adaptive_nmax,&pcbddc->adaptive_nmax,NULL);CHKERRQ(ierr); 1103301b35fSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_symmetric","Symmetric computation of primal basis functions","none",pcbddc->symmetric_primal,&pcbddc->symmetric_primal,NULL);CHKERRQ(ierr); 111b0c7d250SStefano 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); 112b3afcdbeSStefano 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); 113e9627c49SStefano 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); 11427b6a85dSStefano 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); 115a198735bSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nonetflux","Automatic computation of no-net-flux quadrature weights","none",pcbddc->compute_nonetflux,&pcbddc->compute_nonetflux,NULL);CHKERRQ(ierr); 1164f1b2e48SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_detect_disconnected","Detects disconnected subdomains","none",pcbddc->detect_disconnected,&pcbddc->detect_disconnected,NULL);CHKERRQ(ierr); 1178361f951SStefano 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); 11870c64980SStefano 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); 1190c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 1200c7d97c5SJed Brown PetscFunctionReturn(0); 1210c7d97c5SJed Brown } 1226b78500eSPatrick Sanan 1236b78500eSPatrick Sanan static PetscErrorCode PCView_BDDC(PC pc,PetscViewer viewer) 1246b78500eSPatrick Sanan { 1256b78500eSPatrick Sanan PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 126e9627c49SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1276b78500eSPatrick Sanan PetscErrorCode ierr; 12871783a16SStefano Zampini PetscBool isascii; 129e9627c49SStefano Zampini PetscSubcomm subcomm; 130e9627c49SStefano Zampini PetscViewer subviewer; 1316b78500eSPatrick Sanan 1326b78500eSPatrick Sanan PetscFunctionBegin; 1336b78500eSPatrick Sanan ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1346b78500eSPatrick Sanan /* ASCII viewer */ 1356b78500eSPatrick Sanan if (isascii) { 1364b2aedd3SStefano Zampini PetscMPIInt color,rank,size; 137fbad9177SStefano Zampini PetscInt64 loc[7],gsum[6],gmax[6],gmin[6],totbenign; 138e9627c49SStefano Zampini PetscScalar interface_size; 139e9627c49SStefano Zampini PetscReal ratio1=0.,ratio2=0.; 140e9627c49SStefano Zampini Vec counter; 1416b78500eSPatrick Sanan 142b74ba07aSstefano_zampini if (!pc->setupcalled) { 143b74ba07aSstefano_zampini ierr = PetscViewerASCIIPrintf(viewer," Partial information available: preconditioner has not been setup yet\n");CHKERRQ(ierr); 144b74ba07aSstefano_zampini } 145efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use verbose output: %D\n",pcbddc->dbg_flag);CHKERRQ(ierr); 1466f0c0a6aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use user-defined CSR: %d\n",!!pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 1476f0c0a6aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use local mat graph: %d\n",pcbddc->use_local_adj && !pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 148e9627c49SStefano Zampini if (pcbddc->mat_graph->twodim) { 149efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Connectivity graph topological dimension: 2\n");CHKERRQ(ierr); 150e9627c49SStefano Zampini } else { 151efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Connectivity graph topological dimension: 3\n");CHKERRQ(ierr); 152e9627c49SStefano Zampini } 153aefa1729SStefano Zampini if (pcbddc->graphmaxcount != PETSC_MAX_INT) { 154efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Graph max count: %D\n",pcbddc->graphmaxcount);CHKERRQ(ierr); 155aefa1729SStefano Zampini } 15650e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Use vertices: %d (vertex size %D)\n",pcbddc->use_vertices,pcbddc->vertex_size);CHKERRQ(ierr); 157efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use edges: %d\n",pcbddc->use_edges);CHKERRQ(ierr); 158efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use faces: %d\n",pcbddc->use_faces);CHKERRQ(ierr); 159efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use true near null space: %d\n",pcbddc->use_nnsp_true);CHKERRQ(ierr); 160efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use QR for single constraints on cc: %d\n",pcbddc->use_qr_single);CHKERRQ(ierr); 161efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use change of basis on local edge nodes: %d\n",pcbddc->use_change_of_basis);CHKERRQ(ierr); 162efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use change of basis on local face nodes: %d\n",pcbddc->use_change_on_faces);CHKERRQ(ierr); 163efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," User defined change of basis matrix: %d\n",!!pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 164efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Has change of basis matrix: %d\n",!!pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 165efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eliminate dirichlet boundary dofs: %d\n",pcbddc->eliminate_dirdofs);CHKERRQ(ierr); 166efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Switch on static condensation ops around the interface preconditioner: %d\n",pcbddc->switch_static);CHKERRQ(ierr); 167efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use exact dirichlet trick: %d\n",pcbddc->use_exact_dirichlet_trick);CHKERRQ(ierr); 16850e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Multilevel max levels: %D\n",pcbddc->max_levels);CHKERRQ(ierr); 16950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Multilevel coarsening ratio: %D\n",pcbddc->coarsening_ratio);CHKERRQ(ierr); 170efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use estimated eigs for coarse problem: %d\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 171efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe scaling: %d\n",pcbddc->use_deluxe_scaling);CHKERRQ(ierr); 172efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe zerorows: %d\n",pcbddc->deluxe_zerorows);CHKERRQ(ierr); 173efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use deluxe singlemat: %d\n",pcbddc->deluxe_singlemat);CHKERRQ(ierr); 174efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Rebuild interface graph for Schur principal minors: %d\n",pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 17550e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Number of dofs' layers for the computation of principal minors: %D\n",pcbddc->sub_schurs_layers);CHKERRQ(ierr); 176efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Use user CSR graph to compute successive layers: %d\n",pcbddc->sub_schurs_use_useradj);CHKERRQ(ierr); 177bd2a564bSStefano Zampini if (pcbddc->adaptive_threshold[1] != pcbddc->adaptive_threshold[0]) { 178bd2a564bSStefano 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); 179bd2a564bSStefano Zampini } else { 180bd2a564bSStefano 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); 181bd2a564bSStefano Zampini } 18250e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Min constraints / connected component: %D\n",pcbddc->adaptive_nmin);CHKERRQ(ierr); 18350e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Max constraints / connected component: %D\n",pcbddc->adaptive_nmax);CHKERRQ(ierr); 184efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Invert exact Schur complement for adaptive selection: %d\n",pcbddc->sub_schurs_exact_schur);CHKERRQ(ierr); 185efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Symmetric computation of primal basis functions: %d\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 18650e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Num. Procs. to map coarse adjacency list: %D\n",pcbddc->coarse_adj_red);CHKERRQ(ierr); 18750e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Coarse eqs per proc (significant at the coarsest level): %D\n",pcbddc->coarse_eqs_per_proc);CHKERRQ(ierr); 1888361f951SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Detect disconnected: %d (filter %d)\n",pcbddc->detect_disconnected,pcbddc->detect_disconnected_filter);CHKERRQ(ierr); 189efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Benign subspace trick: %d (change explicit %d)\n",pcbddc->benign_saddle_point,pcbddc->benign_change_explicit);CHKERRQ(ierr); 190efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Benign subspace trick is active: %d\n",pcbddc->benign_have_null);CHKERRQ(ierr); 19115579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Algebraic computation of no-net-flux: %d\n",pcbddc->compute_nonetflux);CHKERRQ(ierr); 192b74ba07aSstefano_zampini if (!pc->setupcalled) PetscFunctionReturn(0); 1936b78500eSPatrick Sanan 194fbad9177SStefano Zampini /* compute interface size */ 195e9627c49SStefano Zampini ierr = VecSet(pcis->vec1_B,1.0);CHKERRQ(ierr); 196e9627c49SStefano Zampini ierr = MatCreateVecs(pc->pmat,&counter,0);CHKERRQ(ierr); 197e9627c49SStefano Zampini ierr = VecSet(counter,0.0);CHKERRQ(ierr); 198e9627c49SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 199e9627c49SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 200e9627c49SStefano Zampini ierr = VecSum(counter,&interface_size);CHKERRQ(ierr); 201e9627c49SStefano Zampini ierr = VecDestroy(&counter);CHKERRQ(ierr); 202fbad9177SStefano Zampini 203fbad9177SStefano Zampini /* compute some statistics on the domain decomposition */ 204e9627c49SStefano Zampini gsum[0] = 1; 205fbad9177SStefano Zampini gsum[1] = gsum[2] = gsum[3] = gsum[4] = gsum[5] = 0; 206e9627c49SStefano Zampini loc[0] = !!pcis->n; 207e9627c49SStefano Zampini loc[1] = pcis->n - pcis->n_B; 208e9627c49SStefano Zampini loc[2] = pcis->n_B; 209e9627c49SStefano Zampini loc[3] = pcbddc->local_primal_size; 210345ecf6cSStefano Zampini loc[4] = pcis->n; 211fbad9177SStefano Zampini loc[5] = pcbddc->n_local_subs > 0 ? pcbddc->n_local_subs : (pcis->n ? 1 : 0); 212fbad9177SStefano Zampini loc[6] = pcbddc->benign_n; 213fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gsum,6,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 214fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = -1; 215fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gmax,6,MPIU_INT64,MPI_MAX,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 216fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = PETSC_MAX_INT; 217fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gmin,6,MPIU_INT64,MPI_MIN,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 218fbad9177SStefano Zampini ierr = MPI_Reduce(&loc[6],&totbenign,1,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 219e9627c49SStefano Zampini if (pcbddc->coarse_size) { 220e9627c49SStefano Zampini ratio1 = pc->pmat->rmap->N/(1.*pcbddc->coarse_size); 221e9627c49SStefano Zampini ratio2 = PetscRealPart(interface_size)/pcbddc->coarse_size; 222e9627c49SStefano Zampini } 223efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"********************************** STATISTICS AT LEVEL %d **********************************\n",pcbddc->current_level);CHKERRQ(ierr); 22450e0721cSStefano 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); 22550e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Coarsening ratios: all/coarse %D interface/coarse %D\n",(PetscInt)ratio1,(PetscInt)ratio2);CHKERRQ(ierr); 22650e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Active processes : %D\n",(PetscInt)gsum[0]);CHKERRQ(ierr); 22750e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Total subdomains : %D\n",(PetscInt)gsum[5]);CHKERRQ(ierr); 228345ecf6cSStefano Zampini if (pcbddc->benign_have_null) { 22950e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Benign subs : %D\n",(PetscInt)totbenign);CHKERRQ(ierr); 230345ecf6cSStefano Zampini } 23150e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Dofs type :\tMIN\tMAX\tMEAN\n");CHKERRQ(ierr); 23250e0721cSStefano 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); 23350e0721cSStefano 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); 23450e0721cSStefano 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); 23550e0721cSStefano 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); 23650e0721cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Local subs :\t%D\t%D\n" ,(PetscInt)gmin[5],(PetscInt)gmax[5]);CHKERRQ(ierr); 23715579a77SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 23815579a77SStefano Zampini 23915579a77SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 24015579a77SStefano Zampini 24115579a77SStefano Zampini /* local solvers */ 24215579a77SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscObjectComm((PetscObject)pcbddc->ksp_D),&subviewer);CHKERRQ(ierr); 24315579a77SStefano Zampini if (!rank) { 24415579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Interior solver (rank 0)\n");CHKERRQ(ierr); 24515579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 24615579a77SStefano Zampini ierr = KSPView(pcbddc->ksp_D,subviewer);CHKERRQ(ierr); 24715579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 24815579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Correction solver (rank 0)\n");CHKERRQ(ierr); 24915579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 25015579a77SStefano Zampini ierr = KSPView(pcbddc->ksp_R,subviewer);CHKERRQ(ierr); 25115579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 25215579a77SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 25315579a77SStefano Zampini } 25415579a77SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscObjectComm((PetscObject)pcbddc->ksp_D),&subviewer);CHKERRQ(ierr); 25527b6a85dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 256e9627c49SStefano Zampini 257fbad9177SStefano Zampini /* the coarse problem can be handled by a different communicator */ 258e9627c49SStefano Zampini if (pcbddc->coarse_ksp) color = 1; 259e9627c49SStefano Zampini else color = 0; 2604b2aedd3SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 261e9627c49SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)pc),&subcomm);CHKERRQ(ierr); 2624b2aedd3SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,PetscMin(size,2));CHKERRQ(ierr); 263e9627c49SStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 264e9627c49SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 265e9627c49SStefano Zampini if (color == 1) { 26615579a77SStefano Zampini ierr = PetscViewerASCIIPrintf(subviewer,"--- Coarse solver\n");CHKERRQ(ierr); 26715579a77SStefano Zampini ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 268e9627c49SStefano Zampini ierr = KSPView(pcbddc->coarse_ksp,subviewer);CHKERRQ(ierr); 26915579a77SStefano Zampini ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 270e9627c49SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 271e9627c49SStefano Zampini } 272e9627c49SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 273e9627c49SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 274e9627c49SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 275e9627c49SStefano Zampini } 2766b78500eSPatrick Sanan PetscFunctionReturn(0); 2776b78500eSPatrick Sanan } 278a13144ffSStefano Zampini 2791e0482f5SStefano Zampini static PetscErrorCode PCBDDCSetDiscreteGradient_BDDC(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 280a13144ffSStefano Zampini { 281a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 282a13144ffSStefano Zampini PetscErrorCode ierr; 283a13144ffSStefano Zampini 284a13144ffSStefano Zampini PetscFunctionBegin; 285a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr); 286a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 287a13144ffSStefano Zampini pcbddc->discretegradient = G; 288a13144ffSStefano Zampini pcbddc->nedorder = order > 0 ? order : -order; 289495a2a07SStefano Zampini pcbddc->nedfield = field; 2901e0482f5SStefano Zampini pcbddc->nedglobal = global; 2911e0482f5SStefano Zampini pcbddc->conforming = conforming; 292a13144ffSStefano Zampini PetscFunctionReturn(0); 293a13144ffSStefano Zampini } 294a13144ffSStefano Zampini 295a13144ffSStefano Zampini /*@ 296a13144ffSStefano Zampini PCBDDCSetDiscreteGradient - Sets the discrete gradient 297a13144ffSStefano Zampini 298a13144ffSStefano Zampini Collective on PC 299a13144ffSStefano Zampini 300a13144ffSStefano Zampini Input Parameters: 301a13144ffSStefano Zampini + pc - the preconditioning context 302a13144ffSStefano Zampini . G - the discrete gradient matrix (should be in AIJ format) 303a13144ffSStefano Zampini . order - the order of the Nedelec space (1 for the lowest order) 304495a2a07SStefano Zampini . field - the field id of the Nedelec dofs (not used if the fields have not been specified) 3051e0482f5SStefano Zampini . global - the type of global ordering for the rows of G 306a13144ffSStefano Zampini - conforming - whether the mesh is conforming or not 307a13144ffSStefano Zampini 308a13144ffSStefano Zampini Level: advanced 309a13144ffSStefano Zampini 31095452b02SPatrick Sanan Notes: 31195452b02SPatrick Sanan The discrete gradient matrix G is used to analyze the subdomain edges, and it should not contain any zero entry. 312495a2a07SStefano Zampini For variable order spaces, the order should be set to zero. 3131e0482f5SStefano Zampini If global is true, the rows of G should be given in global ordering for the whole dofs; 3141e0482f5SStefano Zampini if false, the ordering should be global for the Nedelec field. 3151e0482f5SStefano 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 3161e0482f5SStefano Zampini and geid the one for the Nedelec field. 317a13144ffSStefano Zampini 318495a2a07SStefano Zampini .seealso: PCBDDC,PCBDDCSetDofsSplitting(),PCBDDCSetDofsSplittingLocal() 319a13144ffSStefano Zampini @*/ 3201e0482f5SStefano Zampini PetscErrorCode PCBDDCSetDiscreteGradient(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 321a13144ffSStefano Zampini { 322a13144ffSStefano Zampini PetscErrorCode ierr; 323a13144ffSStefano Zampini 324a13144ffSStefano Zampini PetscFunctionBegin; 325a13144ffSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 326a13144ffSStefano Zampini PetscValidHeaderSpecific(G,MAT_CLASSID,2); 327a13144ffSStefano Zampini PetscValidLogicalCollectiveInt(pc,order,3); 3281e0482f5SStefano Zampini PetscValidLogicalCollectiveInt(pc,field,4); 3291e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,global,5); 3301e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,conforming,6); 3311e0482f5SStefano Zampini PetscCheckSameComm(pc,1,G,2); 3321e0482f5SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDiscreteGradient_C",(PC,Mat,PetscInt,PetscInt,PetscBool,PetscBool),(pc,G,order,field,global,conforming));CHKERRQ(ierr); 333a13144ffSStefano Zampini PetscFunctionReturn(0); 334a13144ffSStefano Zampini } 335a13144ffSStefano Zampini 3368ae0ca82SStefano Zampini static PetscErrorCode PCBDDCSetDivergenceMat_BDDC(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 337a198735bSStefano Zampini { 338a198735bSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 339a198735bSStefano Zampini PetscErrorCode ierr; 3406b78500eSPatrick Sanan 341a198735bSStefano Zampini PetscFunctionBegin; 342a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)divudotp);CHKERRQ(ierr); 343a198735bSStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 344a198735bSStefano Zampini pcbddc->divudotp = divudotp; 3458ae0ca82SStefano Zampini pcbddc->divudotp_trans = trans; 346a198735bSStefano Zampini pcbddc->compute_nonetflux = PETSC_TRUE; 347a198735bSStefano Zampini if (vl2l) { 348a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2l);CHKERRQ(ierr); 349fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 350a198735bSStefano Zampini pcbddc->divudotp_vl2l = vl2l; 351a198735bSStefano Zampini } 352a198735bSStefano Zampini PetscFunctionReturn(0); 353a198735bSStefano Zampini } 3543d996552SStefano Zampini 355a198735bSStefano Zampini /*@ 356a198735bSStefano Zampini PCBDDCSetDivergenceMat - Sets the linear operator representing \int_\Omega \div {\bf u} \cdot p dx 357a198735bSStefano Zampini 358a198735bSStefano Zampini Collective on PC 359a198735bSStefano Zampini 360a198735bSStefano Zampini Input Parameters: 361a198735bSStefano Zampini + pc - the preconditioning context 362a198735bSStefano Zampini . divudotp - the matrix (must be of type MATIS) 3638ae0ca82SStefano Zampini . trans - if trans if false (resp. true), then pressures are in the test (trial) space and velocities are in the trial (test) space. 36405a3bf82SStefano 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 365a198735bSStefano Zampini 366a198735bSStefano Zampini Level: advanced 367a198735bSStefano Zampini 36895452b02SPatrick Sanan Notes: 36995452b02SPatrick Sanan This auxiliary matrix is used to compute quadrature weights representing the net-flux across subdomain boundaries 37005a3bf82SStefano Zampini If vl2l is NULL, the local ordering for velocities in divudotp should match that of the preconditioning matrix 371a198735bSStefano Zampini 372a198735bSStefano Zampini .seealso: PCBDDC 373a198735bSStefano Zampini @*/ 3748ae0ca82SStefano Zampini PetscErrorCode PCBDDCSetDivergenceMat(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 375a198735bSStefano Zampini { 376a198735bSStefano Zampini PetscBool ismatis; 377a198735bSStefano Zampini PetscErrorCode ierr; 378a198735bSStefano Zampini 379a198735bSStefano Zampini PetscFunctionBegin; 380a198735bSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 381a198735bSStefano Zampini PetscValidHeaderSpecific(divudotp,MAT_CLASSID,2); 382a198735bSStefano Zampini PetscCheckSameComm(pc,1,divudotp,2); 3838ae0ca82SStefano Zampini PetscValidLogicalCollectiveBool(pc,trans,3); 3841b24a7afSStefano Zampini if (vl2l) PetscValidHeaderSpecific(vl2l,IS_CLASSID,4); 385a198735bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)divudotp,MATIS,&ismatis);CHKERRQ(ierr); 386a198735bSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Divergence matrix needs to be of type MATIS"); 3878ae0ca82SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDivergenceMat_C",(PC,Mat,PetscBool,IS),(pc,divudotp,trans,vl2l));CHKERRQ(ierr); 388a198735bSStefano Zampini PetscFunctionReturn(0); 389a198735bSStefano Zampini } 3902d505d7fSStefano Zampini 3911dd7afcfSStefano Zampini static PetscErrorCode PCBDDCSetChangeOfBasisMat_BDDC(PC pc, Mat change, PetscBool interior) 392b9b85e73SStefano Zampini { 393b9b85e73SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 394b9b85e73SStefano Zampini PetscErrorCode ierr; 395b9b85e73SStefano Zampini 396b9b85e73SStefano Zampini PetscFunctionBegin; 397b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)change);CHKERRQ(ierr); 39856282151SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 399b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = change; 4001dd7afcfSStefano Zampini pcbddc->change_interior = interior; 401b9b85e73SStefano Zampini PetscFunctionReturn(0); 402b9b85e73SStefano Zampini } 403b9b85e73SStefano Zampini /*@ 404906d46d4SStefano Zampini PCBDDCSetChangeOfBasisMat - Set user defined change of basis for dofs 405b9b85e73SStefano Zampini 406b9b85e73SStefano Zampini Collective on PC 407b9b85e73SStefano Zampini 408b9b85e73SStefano Zampini Input Parameters: 409b9b85e73SStefano Zampini + pc - the preconditioning context 4101dd7afcfSStefano Zampini . change - the change of basis matrix 4111dd7afcfSStefano Zampini - interior - whether or not the change of basis modifies interior dofs 412b9b85e73SStefano Zampini 413b9b85e73SStefano Zampini Level: intermediate 414b9b85e73SStefano Zampini 415b9b85e73SStefano Zampini Notes: 416b9b85e73SStefano Zampini 417b9b85e73SStefano Zampini .seealso: PCBDDC 418b9b85e73SStefano Zampini @*/ 4191dd7afcfSStefano Zampini PetscErrorCode PCBDDCSetChangeOfBasisMat(PC pc, Mat change, PetscBool interior) 420b9b85e73SStefano Zampini { 421b9b85e73SStefano Zampini PetscErrorCode ierr; 422b9b85e73SStefano Zampini 423b9b85e73SStefano Zampini PetscFunctionBegin; 424b9b85e73SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 425b9b85e73SStefano Zampini PetscValidHeaderSpecific(change,MAT_CLASSID,2); 426906d46d4SStefano Zampini PetscCheckSameComm(pc,1,change,2); 427906d46d4SStefano Zampini if (pc->mat) { 428906d46d4SStefano Zampini PetscInt rows_c,cols_c,rows,cols; 429906d46d4SStefano Zampini ierr = MatGetSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 430906d46d4SStefano Zampini ierr = MatGetSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 431e0fe2d75SToby 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); 432e0fe2d75SToby 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); 433906d46d4SStefano Zampini ierr = MatGetLocalSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 434906d46d4SStefano Zampini ierr = MatGetLocalSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 435e0fe2d75SToby 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); 436e0fe2d75SToby 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); 437906d46d4SStefano Zampini } 4381dd7afcfSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetChangeOfBasisMat_C",(PC,Mat,PetscBool),(pc,change,interior));CHKERRQ(ierr); 439b9b85e73SStefano Zampini PetscFunctionReturn(0); 440b9b85e73SStefano Zampini } 4412d505d7fSStefano Zampini 44230368db7SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesIS_BDDC(PC pc, IS PrimalVertices) 44330368db7SStefano Zampini { 44430368db7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 44556282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 44630368db7SStefano Zampini PetscErrorCode ierr; 44730368db7SStefano Zampini 44830368db7SStefano Zampini PetscFunctionBegin; 44956282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 45056282151SStefano Zampini if (pcbddc->user_primal_vertices) { 45156282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices,&isequal);CHKERRQ(ierr); 45256282151SStefano Zampini } 45330368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 45430368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 45530368db7SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 45656282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 45730368db7SStefano Zampini PetscFunctionReturn(0); 45830368db7SStefano Zampini } 459ab8c8b98SStefano Zampini 46030368db7SStefano Zampini /*@ 46130368db7SStefano Zampini PCBDDCSetPrimalVerticesIS - Set additional user defined primal vertices in PCBDDC 46230368db7SStefano Zampini 46330368db7SStefano Zampini Collective 46430368db7SStefano Zampini 46530368db7SStefano Zampini Input Parameters: 46630368db7SStefano Zampini + pc - the preconditioning context 46730368db7SStefano Zampini - PrimalVertices - index set of primal vertices in global numbering (can be empty) 46830368db7SStefano Zampini 46930368db7SStefano Zampini Level: intermediate 47030368db7SStefano Zampini 47130368db7SStefano Zampini Notes: 47230368db7SStefano Zampini Any process can list any global node 47330368db7SStefano Zampini 4743100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCGetPrimalVerticesIS(), PCBDDCSetPrimalVerticesLocalIS(), PCBDDCGetPrimalVerticesLocalIS() 47530368db7SStefano Zampini @*/ 47630368db7SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesIS(PC pc, IS PrimalVertices) 47730368db7SStefano Zampini { 47830368db7SStefano Zampini PetscErrorCode ierr; 47930368db7SStefano Zampini 48030368db7SStefano Zampini PetscFunctionBegin; 48130368db7SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 48230368db7SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 48330368db7SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 48430368db7SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 48530368db7SStefano Zampini PetscFunctionReturn(0); 48630368db7SStefano Zampini } 4872d505d7fSStefano Zampini 4883100ebe3SStefano Zampini static PetscErrorCode PCBDDCGetPrimalVerticesIS_BDDC(PC pc, IS *is) 4893100ebe3SStefano Zampini { 4903100ebe3SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4913100ebe3SStefano Zampini 4923100ebe3SStefano Zampini PetscFunctionBegin; 4933100ebe3SStefano Zampini *is = pcbddc->user_primal_vertices; 4943100ebe3SStefano Zampini PetscFunctionReturn(0); 4953100ebe3SStefano Zampini } 4963100ebe3SStefano Zampini 4973100ebe3SStefano Zampini /*@ 4983100ebe3SStefano Zampini PCBDDCGetPrimalVerticesIS - Get user defined primal vertices set with PCBDDCSetPrimalVerticesIS() 4993100ebe3SStefano Zampini 5003100ebe3SStefano Zampini Collective 5013100ebe3SStefano Zampini 5023100ebe3SStefano Zampini Input Parameters: 5033100ebe3SStefano Zampini . pc - the preconditioning context 5043100ebe3SStefano Zampini 5053100ebe3SStefano Zampini Output Parameters: 5063100ebe3SStefano Zampini . is - index set of primal vertices in global numbering (NULL if not set) 5073100ebe3SStefano Zampini 5083100ebe3SStefano Zampini Level: intermediate 5093100ebe3SStefano Zampini 5103100ebe3SStefano Zampini Notes: 5113100ebe3SStefano Zampini 5123100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCSetPrimalVerticesIS(), PCBDDCSetPrimalVerticesLocalIS(), PCBDDCGetPrimalVerticesLocalIS() 5133100ebe3SStefano Zampini @*/ 5143100ebe3SStefano Zampini PetscErrorCode PCBDDCGetPrimalVerticesIS(PC pc, IS *is) 5153100ebe3SStefano Zampini { 5163100ebe3SStefano Zampini PetscErrorCode ierr; 5173100ebe3SStefano Zampini 5183100ebe3SStefano Zampini PetscFunctionBegin; 5193100ebe3SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5203100ebe3SStefano Zampini PetscValidPointer(is,2); 5213100ebe3SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetPrimalVerticesIS_C",(PC,IS*),(pc,is));CHKERRQ(ierr); 5223100ebe3SStefano Zampini PetscFunctionReturn(0); 5233100ebe3SStefano Zampini } 5243100ebe3SStefano Zampini 525674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 526674ae819SStefano Zampini { 527674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 52856282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 529674ae819SStefano Zampini PetscErrorCode ierr; 5301e6b0712SBarry Smith 531674ae819SStefano Zampini PetscFunctionBegin; 53256282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 53356282151SStefano Zampini if (pcbddc->user_primal_vertices_local) { 53456282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices_local,&isequal);CHKERRQ(ierr); 53556282151SStefano Zampini } 536674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 53730368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 53830368db7SStefano Zampini pcbddc->user_primal_vertices_local = PrimalVertices; 53956282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 540674ae819SStefano Zampini PetscFunctionReturn(0); 541674ae819SStefano Zampini } 5423100ebe3SStefano Zampini 543674ae819SStefano Zampini /*@ 54428509bceSStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC 545674ae819SStefano Zampini 54617eb1463SStefano Zampini Collective 547674ae819SStefano Zampini 548674ae819SStefano Zampini Input Parameters: 549674ae819SStefano Zampini + pc - the preconditioning context 55017eb1463SStefano Zampini - PrimalVertices - index set of primal vertices in local numbering (can be empty) 551674ae819SStefano Zampini 552674ae819SStefano Zampini Level: intermediate 553674ae819SStefano Zampini 554674ae819SStefano Zampini Notes: 555674ae819SStefano Zampini 5563100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCSetPrimalVerticesIS(), PCBDDCGetPrimalVerticesIS(), PCBDDCGetPrimalVerticesLocalIS() 557674ae819SStefano Zampini @*/ 558674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 559674ae819SStefano Zampini { 560674ae819SStefano Zampini PetscErrorCode ierr; 561674ae819SStefano Zampini 562674ae819SStefano Zampini PetscFunctionBegin; 563674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 564674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 56517eb1463SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 566674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 567674ae819SStefano Zampini PetscFunctionReturn(0); 568674ae819SStefano Zampini } 5692d505d7fSStefano Zampini 5703100ebe3SStefano Zampini static PetscErrorCode PCBDDCGetPrimalVerticesLocalIS_BDDC(PC pc, IS *is) 5713100ebe3SStefano Zampini { 5723100ebe3SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5733100ebe3SStefano Zampini 5743100ebe3SStefano Zampini PetscFunctionBegin; 5753100ebe3SStefano Zampini *is = pcbddc->user_primal_vertices_local; 5763100ebe3SStefano Zampini PetscFunctionReturn(0); 5773100ebe3SStefano Zampini } 5783100ebe3SStefano Zampini 5793100ebe3SStefano Zampini /*@ 5803100ebe3SStefano Zampini PCBDDCGetPrimalVerticesLocalIS - Get user defined primal vertices set with PCBDDCSetPrimalVerticesLocalIS() 5813100ebe3SStefano Zampini 5823100ebe3SStefano Zampini Collective 5833100ebe3SStefano Zampini 5843100ebe3SStefano Zampini Input Parameters: 5853100ebe3SStefano Zampini . pc - the preconditioning context 5863100ebe3SStefano Zampini 5873100ebe3SStefano Zampini Output Parameters: 5883100ebe3SStefano Zampini . is - index set of primal vertices in local numbering (NULL if not set) 5893100ebe3SStefano Zampini 5903100ebe3SStefano Zampini Level: intermediate 5913100ebe3SStefano Zampini 5923100ebe3SStefano Zampini Notes: 5933100ebe3SStefano Zampini 5943100ebe3SStefano Zampini .seealso: PCBDDC, PCBDDCSetPrimalVerticesIS(), PCBDDCGetPrimalVerticesIS(), PCBDDCSetPrimalVerticesLocalIS() 5953100ebe3SStefano Zampini @*/ 5963100ebe3SStefano Zampini PetscErrorCode PCBDDCGetPrimalVerticesLocalIS(PC pc, IS *is) 5973100ebe3SStefano Zampini { 5983100ebe3SStefano Zampini PetscErrorCode ierr; 5993100ebe3SStefano Zampini 6003100ebe3SStefano Zampini PetscFunctionBegin; 6013100ebe3SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6023100ebe3SStefano Zampini PetscValidPointer(is,2); 6033100ebe3SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetPrimalVerticesLocalIS_C",(PC,IS*),(pc,is));CHKERRQ(ierr); 6043100ebe3SStefano Zampini PetscFunctionReturn(0); 6053100ebe3SStefano Zampini } 6063100ebe3SStefano Zampini 6074fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 6084fad6a16SStefano Zampini { 6094fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6104fad6a16SStefano Zampini 6114fad6a16SStefano Zampini PetscFunctionBegin; 6124fad6a16SStefano Zampini pcbddc->coarsening_ratio = k; 6134fad6a16SStefano Zampini PetscFunctionReturn(0); 6144fad6a16SStefano Zampini } 6151e6b0712SBarry Smith 6164fad6a16SStefano Zampini /*@ 61728509bceSStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel 6184fad6a16SStefano Zampini 6194fad6a16SStefano Zampini Logically collective on PC 6204fad6a16SStefano Zampini 6214fad6a16SStefano Zampini Input Parameters: 6224fad6a16SStefano Zampini + pc - the preconditioning context 62328509bceSStefano Zampini - k - coarsening ratio (H/h at the coarser level) 6244fad6a16SStefano Zampini 6250f202f7eSStefano Zampini Options Database Keys: 6260f202f7eSStefano Zampini . -pc_bddc_coarsening_ratio 6274fad6a16SStefano Zampini 6284fad6a16SStefano Zampini Level: intermediate 6294fad6a16SStefano Zampini 6304fad6a16SStefano Zampini Notes: 6310f202f7eSStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level 6324fad6a16SStefano Zampini 6330f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetLevels() 6344fad6a16SStefano Zampini @*/ 6354fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 6364fad6a16SStefano Zampini { 6374fad6a16SStefano Zampini PetscErrorCode ierr; 6384fad6a16SStefano Zampini 6394fad6a16SStefano Zampini PetscFunctionBegin; 6404fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6412b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,k,2); 6424fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 6434fad6a16SStefano Zampini PetscFunctionReturn(0); 6444fad6a16SStefano Zampini } 6452b510759SStefano Zampini 646b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */ 647b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg) 648b8ffe317SStefano Zampini { 649b8ffe317SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 650b8ffe317SStefano Zampini 651b8ffe317SStefano Zampini PetscFunctionBegin; 65285c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = flg; 653b8ffe317SStefano Zampini PetscFunctionReturn(0); 654b8ffe317SStefano Zampini } 655b8ffe317SStefano Zampini 656b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg) 6572b510759SStefano Zampini { 6582b510759SStefano Zampini PetscErrorCode ierr; 6592b510759SStefano Zampini 6602b510759SStefano Zampini PetscFunctionBegin; 6612b510759SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 662b8ffe317SStefano Zampini PetscValidLogicalCollectiveBool(pc,flg,2); 663b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr); 6642b510759SStefano Zampini PetscFunctionReturn(0); 6652b510759SStefano Zampini } 6661e6b0712SBarry Smith 6672b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level) 6684fad6a16SStefano Zampini { 6694fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6704fad6a16SStefano Zampini 6714fad6a16SStefano Zampini PetscFunctionBegin; 6722b510759SStefano Zampini pcbddc->current_level = level; 6734fad6a16SStefano Zampini PetscFunctionReturn(0); 6744fad6a16SStefano Zampini } 6751e6b0712SBarry Smith 676b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 677b8ffe317SStefano Zampini { 678b8ffe317SStefano Zampini PetscErrorCode ierr; 679b8ffe317SStefano Zampini 680b8ffe317SStefano Zampini PetscFunctionBegin; 681b8ffe317SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 682b8ffe317SStefano Zampini PetscValidLogicalCollectiveInt(pc,level,2); 683b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr); 684b8ffe317SStefano Zampini PetscFunctionReturn(0); 685b8ffe317SStefano Zampini } 686b8ffe317SStefano Zampini 6872b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels) 6882b510759SStefano Zampini { 6892b510759SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6902b510759SStefano Zampini 6912b510759SStefano Zampini PetscFunctionBegin; 6926080607fSStefano 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); 6932b510759SStefano Zampini pcbddc->max_levels = levels; 6942b510759SStefano Zampini PetscFunctionReturn(0); 6952b510759SStefano Zampini } 6962b510759SStefano Zampini 6974fad6a16SStefano Zampini /*@ 69837ebbdf7SStefano Zampini PCBDDCSetLevels - Sets the maximum number of additional levels allowed for multilevel BDDC 6994fad6a16SStefano Zampini 7004fad6a16SStefano Zampini Logically collective on PC 7014fad6a16SStefano Zampini 7024fad6a16SStefano Zampini Input Parameters: 7034fad6a16SStefano Zampini + pc - the preconditioning context 70437ebbdf7SStefano Zampini - levels - the maximum number of levels 7054fad6a16SStefano Zampini 7060f202f7eSStefano Zampini Options Database Keys: 7070f202f7eSStefano Zampini . -pc_bddc_levels 7084fad6a16SStefano Zampini 7094fad6a16SStefano Zampini Level: intermediate 7104fad6a16SStefano Zampini 7114fad6a16SStefano Zampini Notes: 71237ebbdf7SStefano Zampini The default value is 0, that gives the classical two-levels BDDC 7134fad6a16SStefano Zampini 7140f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetCoarseningRatio() 7154fad6a16SStefano Zampini @*/ 7162b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels) 7174fad6a16SStefano Zampini { 7184fad6a16SStefano Zampini PetscErrorCode ierr; 7194fad6a16SStefano Zampini 7204fad6a16SStefano Zampini PetscFunctionBegin; 7214fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 7222b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,levels,2); 7232b510759SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr); 7244fad6a16SStefano Zampini PetscFunctionReturn(0); 7254fad6a16SStefano Zampini } 7261e6b0712SBarry Smith 7273b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 7283b03a366Sstefano_zampini { 7293b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 73056282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 7313b03a366Sstefano_zampini PetscErrorCode ierr; 7323b03a366Sstefano_zampini 7333b03a366Sstefano_zampini PetscFunctionBegin; 73456282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 73556282151SStefano Zampini if (pcbddc->DirichletBoundaries) { 73656282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundaries,&isequal);CHKERRQ(ierr); 73756282151SStefano Zampini } 738785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 739785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 7403b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 74136e030ebSStefano Zampini pcbddc->DirichletBoundaries = DirichletBoundaries; 74256282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7433b03a366Sstefano_zampini PetscFunctionReturn(0); 7443b03a366Sstefano_zampini } 7451e6b0712SBarry Smith 7463b03a366Sstefano_zampini /*@ 74728509bceSStefano Zampini PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem. 7483b03a366Sstefano_zampini 749785d1243SStefano Zampini Collective 7503b03a366Sstefano_zampini 7513b03a366Sstefano_zampini Input Parameters: 7523b03a366Sstefano_zampini + pc - the preconditioning context 753785d1243SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries 7543b03a366Sstefano_zampini 7553b03a366Sstefano_zampini Level: intermediate 7563b03a366Sstefano_zampini 7570f202f7eSStefano Zampini Notes: 7580f202f7eSStefano Zampini Provide the information if you used MatZeroRows/Columns routines. Any process can list any global node 7593b03a366Sstefano_zampini 7600f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundariesLocal(), MatZeroRows(), MatZeroRowsColumns() 7613b03a366Sstefano_zampini @*/ 7623b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 7633b03a366Sstefano_zampini { 7643b03a366Sstefano_zampini PetscErrorCode ierr; 7653b03a366Sstefano_zampini 7663b03a366Sstefano_zampini PetscFunctionBegin; 7673b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 768674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 769785d1243SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 7703b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 7713b03a366Sstefano_zampini PetscFunctionReturn(0); 7723b03a366Sstefano_zampini } 7731e6b0712SBarry Smith 77482ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries) 7753b03a366Sstefano_zampini { 7763b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 77756282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 7783b03a366Sstefano_zampini PetscErrorCode ierr; 7793b03a366Sstefano_zampini 7803b03a366Sstefano_zampini PetscFunctionBegin; 78156282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 78256282151SStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 78356282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundariesLocal,&isequal);CHKERRQ(ierr); 78456282151SStefano Zampini } 785785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 786785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 7873b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 788785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = DirichletBoundaries; 78956282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7903b03a366Sstefano_zampini PetscFunctionReturn(0); 7913b03a366Sstefano_zampini } 7923b03a366Sstefano_zampini 7933b03a366Sstefano_zampini /*@ 79482ba6b80SStefano Zampini PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering. 7953b03a366Sstefano_zampini 796785d1243SStefano Zampini Collective 7973b03a366Sstefano_zampini 7983b03a366Sstefano_zampini Input Parameters: 7993b03a366Sstefano_zampini + pc - the preconditioning context 80082ba6b80SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering) 8013b03a366Sstefano_zampini 8023b03a366Sstefano_zampini Level: intermediate 8033b03a366Sstefano_zampini 8043b03a366Sstefano_zampini Notes: 8053b03a366Sstefano_zampini 8060f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundaries(), MatZeroRows(), MatZeroRowsColumns() 8073b03a366Sstefano_zampini @*/ 80882ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries) 8093b03a366Sstefano_zampini { 8103b03a366Sstefano_zampini PetscErrorCode ierr; 8113b03a366Sstefano_zampini 8123b03a366Sstefano_zampini PetscFunctionBegin; 8133b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 8143b03a366Sstefano_zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 81582ba6b80SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 81682ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 8173b03a366Sstefano_zampini PetscFunctionReturn(0); 8183b03a366Sstefano_zampini } 8193b03a366Sstefano_zampini 82053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 8210c7d97c5SJed Brown { 8220c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 82356282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 82453cdbc3dSStefano Zampini PetscErrorCode ierr; 8250c7d97c5SJed Brown 8260c7d97c5SJed Brown PetscFunctionBegin; 82756282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 82856282151SStefano Zampini if (pcbddc->NeumannBoundaries) { 82956282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundaries,&isequal);CHKERRQ(ierr); 83056282151SStefano Zampini } 831785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 832785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 83353cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 83436e030ebSStefano Zampini pcbddc->NeumannBoundaries = NeumannBoundaries; 83556282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 8360c7d97c5SJed Brown PetscFunctionReturn(0); 8370c7d97c5SJed Brown } 8381e6b0712SBarry Smith 83957527edcSJed Brown /*@ 84028509bceSStefano Zampini PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem. 84157527edcSJed Brown 842785d1243SStefano Zampini Collective 84357527edcSJed Brown 84457527edcSJed Brown Input Parameters: 84557527edcSJed Brown + pc - the preconditioning context 846785d1243SStefano Zampini - NeumannBoundaries - parallel IS defining the Neumann boundaries 84757527edcSJed Brown 84857527edcSJed Brown Level: intermediate 84957527edcSJed Brown 8500f202f7eSStefano Zampini Notes: 8510f202f7eSStefano Zampini Any process can list any global node 85257527edcSJed Brown 8530f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundariesLocal() 85457527edcSJed Brown @*/ 85553cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 8560c7d97c5SJed Brown { 8570c7d97c5SJed Brown PetscErrorCode ierr; 8580c7d97c5SJed Brown 8590c7d97c5SJed Brown PetscFunctionBegin; 8600c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 861674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 862785d1243SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 86353cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 86453cdbc3dSStefano Zampini PetscFunctionReturn(0); 86553cdbc3dSStefano Zampini } 8661e6b0712SBarry Smith 86782ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries) 8680c7d97c5SJed Brown { 8690c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 87056282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 8710c7d97c5SJed Brown PetscErrorCode ierr; 8720c7d97c5SJed Brown 8730c7d97c5SJed Brown PetscFunctionBegin; 87456282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 87556282151SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 87656282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundariesLocal,&isequal);CHKERRQ(ierr); 87756282151SStefano Zampini } 878785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 879785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 8800c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 881785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = NeumannBoundaries; 88256282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 8830c7d97c5SJed Brown PetscFunctionReturn(0); 8840c7d97c5SJed Brown } 8850c7d97c5SJed Brown 8860c7d97c5SJed Brown /*@ 88782ba6b80SStefano Zampini PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering. 8880c7d97c5SJed Brown 889785d1243SStefano Zampini Collective 8900c7d97c5SJed Brown 8910c7d97c5SJed Brown Input Parameters: 8920c7d97c5SJed Brown + pc - the preconditioning context 89382ba6b80SStefano Zampini - NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering) 8940c7d97c5SJed Brown 8950c7d97c5SJed Brown Level: intermediate 8960c7d97c5SJed Brown 8970c7d97c5SJed Brown Notes: 8980c7d97c5SJed Brown 8990f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundaries() 9000c7d97c5SJed Brown @*/ 90182ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries) 9020c7d97c5SJed Brown { 9030c7d97c5SJed Brown PetscErrorCode ierr; 9040c7d97c5SJed Brown 9050c7d97c5SJed Brown PetscFunctionBegin; 9060c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 9070c7d97c5SJed Brown PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 90882ba6b80SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 90982ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 91053cdbc3dSStefano Zampini PetscFunctionReturn(0); 91153cdbc3dSStefano Zampini } 91253cdbc3dSStefano Zampini 913da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 914da1bb401SStefano Zampini { 915da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 916da1bb401SStefano Zampini 917da1bb401SStefano Zampini PetscFunctionBegin; 918da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 919da1bb401SStefano Zampini PetscFunctionReturn(0); 920da1bb401SStefano Zampini } 9211e6b0712SBarry Smith 922da1bb401SStefano Zampini /*@ 923785d1243SStefano Zampini PCBDDCGetDirichletBoundaries - Get parallel IS for Dirichlet boundaries 924da1bb401SStefano Zampini 925785d1243SStefano Zampini Collective 926785d1243SStefano Zampini 927785d1243SStefano Zampini Input Parameters: 928785d1243SStefano Zampini . pc - the preconditioning context 929785d1243SStefano Zampini 930785d1243SStefano Zampini Output Parameters: 931785d1243SStefano Zampini . DirichletBoundaries - index set defining the Dirichlet boundaries 932785d1243SStefano Zampini 933785d1243SStefano Zampini Level: intermediate 934785d1243SStefano Zampini 9350f202f7eSStefano Zampini Notes: 9360f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetDirichletBoundaries 937785d1243SStefano Zampini 938785d1243SStefano Zampini .seealso: PCBDDC 939785d1243SStefano Zampini @*/ 940785d1243SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 941785d1243SStefano Zampini { 942785d1243SStefano Zampini PetscErrorCode ierr; 943785d1243SStefano Zampini 944785d1243SStefano Zampini PetscFunctionBegin; 945785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 946785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 947785d1243SStefano Zampini PetscFunctionReturn(0); 948785d1243SStefano Zampini } 949785d1243SStefano Zampini 950785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries) 951785d1243SStefano Zampini { 952785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 953785d1243SStefano Zampini 954785d1243SStefano Zampini PetscFunctionBegin; 955785d1243SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundariesLocal; 956785d1243SStefano Zampini PetscFunctionReturn(0); 957785d1243SStefano Zampini } 958785d1243SStefano Zampini 959da1bb401SStefano Zampini /*@ 96082ba6b80SStefano Zampini PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering) 961da1bb401SStefano Zampini 962785d1243SStefano Zampini Collective 963da1bb401SStefano Zampini 964da1bb401SStefano Zampini Input Parameters: 96528509bceSStefano Zampini . pc - the preconditioning context 966da1bb401SStefano Zampini 967da1bb401SStefano Zampini Output Parameters: 96828509bceSStefano Zampini . DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 969da1bb401SStefano Zampini 970da1bb401SStefano Zampini Level: intermediate 971da1bb401SStefano Zampini 972da1bb401SStefano Zampini Notes: 9730f202f7eSStefano 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). 9740f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 975da1bb401SStefano Zampini 976da1bb401SStefano Zampini .seealso: PCBDDC 977da1bb401SStefano Zampini @*/ 97882ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries) 979da1bb401SStefano Zampini { 980da1bb401SStefano Zampini PetscErrorCode ierr; 981da1bb401SStefano Zampini 982da1bb401SStefano Zampini PetscFunctionBegin; 983da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 98482ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 985da1bb401SStefano Zampini PetscFunctionReturn(0); 986da1bb401SStefano Zampini } 9871e6b0712SBarry Smith 98853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 98953cdbc3dSStefano Zampini { 99053cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 99153cdbc3dSStefano Zampini 99253cdbc3dSStefano Zampini PetscFunctionBegin; 99353cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 99453cdbc3dSStefano Zampini PetscFunctionReturn(0); 99553cdbc3dSStefano Zampini } 9961e6b0712SBarry Smith 99753cdbc3dSStefano Zampini /*@ 998785d1243SStefano Zampini PCBDDCGetNeumannBoundaries - Get parallel IS for Neumann boundaries 99953cdbc3dSStefano Zampini 1000785d1243SStefano Zampini Collective 1001785d1243SStefano Zampini 1002785d1243SStefano Zampini Input Parameters: 1003785d1243SStefano Zampini . pc - the preconditioning context 1004785d1243SStefano Zampini 1005785d1243SStefano Zampini Output Parameters: 1006785d1243SStefano Zampini . NeumannBoundaries - index set defining the Neumann boundaries 1007785d1243SStefano Zampini 1008785d1243SStefano Zampini Level: intermediate 1009785d1243SStefano Zampini 10100f202f7eSStefano Zampini Notes: 10110f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetNeumannBoundaries 1012785d1243SStefano Zampini 1013785d1243SStefano Zampini .seealso: PCBDDC 1014785d1243SStefano Zampini @*/ 1015785d1243SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 1016785d1243SStefano Zampini { 1017785d1243SStefano Zampini PetscErrorCode ierr; 1018785d1243SStefano Zampini 1019785d1243SStefano Zampini PetscFunctionBegin; 1020785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1021785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 1022785d1243SStefano Zampini PetscFunctionReturn(0); 1023785d1243SStefano Zampini } 1024785d1243SStefano Zampini 1025785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries) 1026785d1243SStefano Zampini { 1027785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1028785d1243SStefano Zampini 1029785d1243SStefano Zampini PetscFunctionBegin; 1030785d1243SStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundariesLocal; 1031785d1243SStefano Zampini PetscFunctionReturn(0); 1032785d1243SStefano Zampini } 1033785d1243SStefano Zampini 103453cdbc3dSStefano Zampini /*@ 103582ba6b80SStefano Zampini PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering) 103653cdbc3dSStefano Zampini 1037785d1243SStefano Zampini Collective 103853cdbc3dSStefano Zampini 103953cdbc3dSStefano Zampini Input Parameters: 104028509bceSStefano Zampini . pc - the preconditioning context 104153cdbc3dSStefano Zampini 104253cdbc3dSStefano Zampini Output Parameters: 104328509bceSStefano Zampini . NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 104453cdbc3dSStefano Zampini 104553cdbc3dSStefano Zampini Level: intermediate 104653cdbc3dSStefano Zampini 104753cdbc3dSStefano Zampini Notes: 10480f202f7eSStefano 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). 10490f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 105053cdbc3dSStefano Zampini 105153cdbc3dSStefano Zampini .seealso: PCBDDC 105253cdbc3dSStefano Zampini @*/ 105382ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries) 105453cdbc3dSStefano Zampini { 105553cdbc3dSStefano Zampini PetscErrorCode ierr; 105653cdbc3dSStefano Zampini 105753cdbc3dSStefano Zampini PetscFunctionBegin; 105853cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 105982ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 10600c7d97c5SJed Brown PetscFunctionReturn(0); 10610c7d97c5SJed Brown } 10621e6b0712SBarry Smith 10631a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 106436e030ebSStefano Zampini { 106536e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1066da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 106756282151SStefano Zampini PetscBool same_data = PETSC_FALSE; 1068da1bb401SStefano Zampini PetscErrorCode ierr; 106936e030ebSStefano Zampini 107036e030ebSStefano Zampini PetscFunctionBegin; 10718687889aSStefano Zampini if (!nvtxs) { 107204194a47SStefano Zampini if (copymode == PETSC_OWN_POINTER) { 107304194a47SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 107404194a47SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 107504194a47SStefano Zampini } 10768687889aSStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 10778687889aSStefano Zampini PetscFunctionReturn(0); 10788687889aSStefano Zampini } 107966da6bd7Sstefano_zampini if (mat_graph->nvtxs == nvtxs && mat_graph->freecsr) { /* we own the data */ 108056282151SStefano Zampini if (mat_graph->xadj == xadj && mat_graph->adjncy == adjncy) same_data = PETSC_TRUE; 108156282151SStefano Zampini if (!same_data && mat_graph->xadj[nvtxs] == xadj[nvtxs]) { 10822d505d7fSStefano Zampini ierr = PetscMemcmp(xadj,mat_graph->xadj,(nvtxs+1)*sizeof(PetscInt),&same_data);CHKERRQ(ierr); 10832d505d7fSStefano Zampini if (same_data) { 10842d505d7fSStefano Zampini ierr = PetscMemcmp(adjncy,mat_graph->adjncy,xadj[nvtxs]*sizeof(PetscInt),&same_data);CHKERRQ(ierr); 10852d505d7fSStefano Zampini } 108656282151SStefano Zampini } 108756282151SStefano Zampini } 108856282151SStefano Zampini if (!same_data) { 1089674ae819SStefano Zampini /* free old CSR */ 1090674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 1091674ae819SStefano Zampini /* get CSR into graph structure */ 1092da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 1093854ce69bSBarry Smith ierr = PetscMalloc1(nvtxs+1,&mat_graph->xadj);CHKERRQ(ierr); 1094785e854fSJed Brown ierr = PetscMalloc1(xadj[nvtxs],&mat_graph->adjncy);CHKERRQ(ierr); 1095674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 1096674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 1097a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 1098da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 10991a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 11001a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 1101a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 1102a1dbd327SStefano Zampini } else if (copymode == PETSC_USE_POINTER) { 1103a1dbd327SStefano Zampini mat_graph->xadj = (PetscInt*)xadj; 1104a1dbd327SStefano Zampini mat_graph->adjncy = (PetscInt*)adjncy; 1105a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_FALSE; 1106e0fe2d75SToby Isaac } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %D",copymode); 1107575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 110856282151SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 110956282151SStefano Zampini } 111036e030ebSStefano Zampini PetscFunctionReturn(0); 111136e030ebSStefano Zampini } 11121e6b0712SBarry Smith 111336e030ebSStefano Zampini /*@ 111454fffbccSStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local degrees of freedom. 111536e030ebSStefano Zampini 111636e030ebSStefano Zampini Not collective 111736e030ebSStefano Zampini 111836e030ebSStefano Zampini Input Parameters: 111954fffbccSStefano Zampini + pc - the preconditioning context. 112054fffbccSStefano Zampini . nvtxs - number of local vertices of the graph (i.e., the number of local dofs). 112154fffbccSStefano Zampini . xadj, adjncy - the connectivity of the dofs in CSR format. 112254fffbccSStefano Zampini - copymode - supported modes are PETSC_COPY_VALUES, PETSC_USE_POINTER or PETSC_OWN_POINTER. 112336e030ebSStefano Zampini 112436e030ebSStefano Zampini Level: intermediate 112536e030ebSStefano Zampini 112695452b02SPatrick Sanan Notes: 112795452b02SPatrick Sanan A dof is considered connected with all local dofs if xadj[dof+1]-xadj[dof] == 1 and adjncy[xadj[dof]] is negative. 112836e030ebSStefano Zampini 112928509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode 113036e030ebSStefano Zampini @*/ 11311a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 113236e030ebSStefano Zampini { 1133575ad6abSStefano Zampini void (*f)(void) = 0; 113436e030ebSStefano Zampini PetscErrorCode ierr; 113536e030ebSStefano Zampini 113636e030ebSStefano Zampini PetscFunctionBegin; 113736e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 11388687889aSStefano Zampini if (nvtxs) { 1139674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 11401633d1f0SStefano Zampini if (xadj[nvtxs]) PetscValidIntPointer(adjncy,4); 11418687889aSStefano Zampini } 11421a83f524SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 1143575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 1144575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 1145575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 1146575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 1147575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 1148da1bb401SStefano Zampini } 114936e030ebSStefano Zampini PetscFunctionReturn(0); 115036e030ebSStefano Zampini } 11511e6b0712SBarry Smith 115263602bcaSStefano Zampini static PetscErrorCode PCBDDCSetDofsSplittingLocal_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 115363602bcaSStefano Zampini { 115463602bcaSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 115563602bcaSStefano Zampini PetscInt i; 115656282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 115763602bcaSStefano Zampini PetscErrorCode ierr; 115863602bcaSStefano Zampini 115963602bcaSStefano Zampini PetscFunctionBegin; 116056282151SStefano Zampini if (pcbddc->n_ISForDofsLocal == n_is) { 116156282151SStefano Zampini for (i=0;i<n_is;i++) { 116256282151SStefano Zampini PetscBool isequalt; 116356282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofsLocal[i],&isequalt);CHKERRQ(ierr); 116456282151SStefano Zampini if (!isequalt) break; 116556282151SStefano Zampini } 116656282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 116756282151SStefano Zampini } 116856282151SStefano Zampini for (i=0;i<n_is;i++) { 116956282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 117056282151SStefano Zampini } 117163602bcaSStefano Zampini /* Destroy ISes if they were already set */ 117263602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 117363602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 117463602bcaSStefano Zampini } 117563602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 117663602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 117763602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 117863602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 117963602bcaSStefano Zampini } 118063602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 118163602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 118263602bcaSStefano Zampini /* allocate space then set */ 1183d02579f5SStefano Zampini if (n_is) { 1184d02579f5SStefano Zampini ierr = PetscMalloc1(n_is,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1185d02579f5SStefano Zampini } 118663602bcaSStefano Zampini for (i=0;i<n_is;i++) { 118763602bcaSStefano Zampini pcbddc->ISForDofsLocal[i] = ISForDofs[i]; 118863602bcaSStefano Zampini } 118963602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = n_is; 119063602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 119156282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 119263602bcaSStefano Zampini PetscFunctionReturn(0); 119363602bcaSStefano Zampini } 119463602bcaSStefano Zampini 119563602bcaSStefano Zampini /*@ 119663602bcaSStefano Zampini PCBDDCSetDofsSplittingLocal - Set index sets defining fields of the local subdomain matrix 119763602bcaSStefano Zampini 119863602bcaSStefano Zampini Collective 119963602bcaSStefano Zampini 120063602bcaSStefano Zampini Input Parameters: 120163602bcaSStefano Zampini + pc - the preconditioning context 12020f202f7eSStefano Zampini . n_is - number of index sets defining the fields 12030f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in local ordering 120463602bcaSStefano Zampini 120563602bcaSStefano Zampini Level: intermediate 120663602bcaSStefano Zampini 12070f202f7eSStefano Zampini Notes: 12080f202f7eSStefano Zampini n_is should be the same among processes. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 120963602bcaSStefano Zampini 121063602bcaSStefano Zampini .seealso: PCBDDC 121163602bcaSStefano Zampini @*/ 121263602bcaSStefano Zampini PetscErrorCode PCBDDCSetDofsSplittingLocal(PC pc,PetscInt n_is, IS ISForDofs[]) 121363602bcaSStefano Zampini { 121463602bcaSStefano Zampini PetscInt i; 121563602bcaSStefano Zampini PetscErrorCode ierr; 121663602bcaSStefano Zampini 121763602bcaSStefano Zampini PetscFunctionBegin; 121863602bcaSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 121963602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 122063602bcaSStefano Zampini for (i=0;i<n_is;i++) { 122163602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 122263602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 122363602bcaSStefano Zampini } 1224e71e7a71SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplittingLocal_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 122563602bcaSStefano Zampini PetscFunctionReturn(0); 122663602bcaSStefano Zampini } 122763602bcaSStefano Zampini 12289c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 12299c0446d6SStefano Zampini { 12309c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 12319c0446d6SStefano Zampini PetscInt i; 123256282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 12339c0446d6SStefano Zampini PetscErrorCode ierr; 12349c0446d6SStefano Zampini 12359c0446d6SStefano Zampini PetscFunctionBegin; 123656282151SStefano Zampini if (pcbddc->n_ISForDofs == n_is) { 123756282151SStefano Zampini for (i=0;i<n_is;i++) { 123856282151SStefano Zampini PetscBool isequalt; 123956282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofs[i],&isequalt);CHKERRQ(ierr); 124056282151SStefano Zampini if (!isequalt) break; 124156282151SStefano Zampini } 124256282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 124356282151SStefano Zampini } 124456282151SStefano Zampini for (i=0;i<n_is;i++) { 124556282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 124656282151SStefano Zampini } 1247da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 12489c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 12499c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 12509c0446d6SStefano Zampini } 1251d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 125263602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 125363602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 125463602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 125563602bcaSStefano Zampini } 125663602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 125763602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 1258da1bb401SStefano Zampini /* allocate space then set */ 1259d02579f5SStefano Zampini if (n_is) { 1260785e854fSJed Brown ierr = PetscMalloc1(n_is,&pcbddc->ISForDofs);CHKERRQ(ierr); 1261d02579f5SStefano Zampini } 12629c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 1263da1bb401SStefano Zampini pcbddc->ISForDofs[i] = ISForDofs[i]; 12649c0446d6SStefano Zampini } 12659c0446d6SStefano Zampini pcbddc->n_ISForDofs = n_is; 126663602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 126756282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 12689c0446d6SStefano Zampini PetscFunctionReturn(0); 12699c0446d6SStefano Zampini } 12701e6b0712SBarry Smith 12719c0446d6SStefano Zampini /*@ 127263602bcaSStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of the global matrix 12739c0446d6SStefano Zampini 127463602bcaSStefano Zampini Collective 12759c0446d6SStefano Zampini 12769c0446d6SStefano Zampini Input Parameters: 12779c0446d6SStefano Zampini + pc - the preconditioning context 12780f202f7eSStefano Zampini . n_is - number of index sets defining the fields 12790f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in global ordering 12809c0446d6SStefano Zampini 12819c0446d6SStefano Zampini Level: intermediate 12829c0446d6SStefano Zampini 12830f202f7eSStefano Zampini Notes: 12840f202f7eSStefano Zampini Any process can list any global node. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 12859c0446d6SStefano Zampini 12869c0446d6SStefano Zampini .seealso: PCBDDC 12879c0446d6SStefano Zampini @*/ 12889c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 12899c0446d6SStefano Zampini { 12902b510759SStefano Zampini PetscInt i; 12919c0446d6SStefano Zampini PetscErrorCode ierr; 12929c0446d6SStefano Zampini 12939c0446d6SStefano Zampini PetscFunctionBegin; 12949c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 129563602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 12962b510759SStefano Zampini for (i=0;i<n_is;i++) { 129763602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 1298a011d5a7Sstefano_zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 12992b510759SStefano Zampini } 13009c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 13019c0446d6SStefano Zampini PetscFunctionReturn(0); 13029c0446d6SStefano Zampini } 1303906d46d4SStefano Zampini 1304534831adSStefano Zampini /* 1305534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 1306534831adSStefano Zampini guess if a transformation of basis approach has been selected. 13079c0446d6SStefano Zampini 1308534831adSStefano Zampini Input Parameter: 1309534831adSStefano Zampini + pc - the preconditioner contex 1310534831adSStefano Zampini 1311534831adSStefano Zampini Application Interface Routine: PCPreSolve() 1312534831adSStefano Zampini 1313534831adSStefano Zampini Notes: 1314534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 1315534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1316534831adSStefano Zampini */ 1317534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1318534831adSStefano Zampini { 1319534831adSStefano Zampini PetscErrorCode ierr; 1320534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1321534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 13223972b0daSStefano Zampini Vec used_vec; 13234df7a6bfSStefano Zampini PetscBool iscg = PETSC_FALSE, save_rhs = PETSC_TRUE, benign_correction_computed; 1324534831adSStefano Zampini 1325534831adSStefano Zampini PetscFunctionBegin; 13261f4df5f7SStefano Zampini /* if we are working with CG, one dirichlet solve can be avoided during Krylov iterations */ 132785c4d303SStefano Zampini if (ksp) { 13284df7a6bfSStefano Zampini PetscBool isgroppcg, ispipecg, ispipelcg, ispipecgrr; 13294df7a6bfSStefano Zampini 133085c4d303SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr); 133127b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPGROPPCG,&isgroppcg);CHKERRQ(ierr); 133227b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECG,&ispipecg);CHKERRQ(ierr); 13334df7a6bfSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECG,&ispipelcg);CHKERRQ(ierr); 1334f94e96cbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECGRR,&ispipecgrr);CHKERRQ(ierr); 13354df7a6bfSStefano Zampini iscg = (PetscBool)(iscg || isgroppcg || ispipecg || ispipelcg || ispipecgrr); 1336*3bf6e316SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static || !iscg || pc->mat != pc->pmat) { 133785c4d303SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 133885c4d303SStefano Zampini } 133985c4d303SStefano Zampini } 1340*3bf6e316SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static || pc->mat != pc->pmat) { 1341fc17d649SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 1342fc17d649SStefano Zampini } 13431f4df5f7SStefano Zampini 134485c4d303SStefano Zampini /* Creates parallel work vectors used in presolve */ 134562a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 134662a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 134762a6ff1dSStefano Zampini } 134862a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 134962a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 135062a6ff1dSStefano Zampini } 13518d00608fSStefano Zampini 135227b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_FALSE; 13533972b0daSStefano Zampini if (x) { 13543972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 13553972b0daSStefano Zampini used_vec = x; 13568d00608fSStefano Zampini } else { /* it can only happen when calling PCBDDCMatFETIDPGetRHS */ 13573972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 13583972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 13593972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 136027b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 1361266e20e9SStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 1362266e20e9SStefano Zampini save_rhs = PETSC_FALSE; 1363266e20e9SStefano Zampini pcbddc->eliminate_dirdofs = PETSC_TRUE; 13643972b0daSStefano Zampini } 13658efcfb23SStefano Zampini 13668efcfb23SStefano Zampini /* hack into ksp data structure since PCPreSolve comes earlier than setting to zero the guess in src/ksp/ksp/interface/itfunc.c */ 13673972b0daSStefano Zampini if (ksp) { 1368a0cb1b98SStefano Zampini /* store the flag for the initial guess since it will be restored back during PCPostSolve_BDDC */ 13698efcfb23SStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 13708efcfb23SStefano Zampini if (!pcbddc->ksp_guess_nonzero) { 13713972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 13723972b0daSStefano Zampini } 13733972b0daSStefano Zampini } 13743308cffdSStefano Zampini 13758d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 13763972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 137770c64980SStefano Zampini if (rhs && pcbddc->eliminate_dirdofs) { 13783975b054SStefano Zampini IS dirIS = NULL; 13793975b054SStefano Zampini 1380a07ea27aSStefano Zampini /* DirichletBoundariesLocal may not be consistent among neighbours; gets a dirichlet dofs IS from graph (may be cached) */ 13813975b054SStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 13823975b054SStefano Zampini if (dirIS) { 1383906d46d4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1384785d1243SStefano Zampini PetscInt dirsize,i,*is_indices; 13852b095fd8SStefano Zampini PetscScalar *array_x; 13862b095fd8SStefano Zampini const PetscScalar *array_diagonal; 1387785d1243SStefano Zampini 13883972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 13893972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 1390e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1391e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1392e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1393e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 139482ba6b80SStefano Zampini ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr); 13953972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 13962b095fd8SStefano Zampini ierr = VecGetArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 13973972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 13982fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 13993972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 14002b095fd8SStefano Zampini ierr = VecRestoreArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 14013972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 1402e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1403e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 14048d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 14051b968477SStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 14068efcfb23SStefano Zampini } 1407a07ea27aSStefano Zampini } 1408b76ba322SStefano Zampini 14098efcfb23SStefano Zampini /* remove the computed solution or the initial guess from the rhs */ 14108d00608fSStefano Zampini if (pcbddc->rhs_change || (ksp && pcbddc->ksp_guess_nonzero) ) { 141127b6a85dSStefano Zampini /* save the original rhs */ 141227b6a85dSStefano Zampini if (save_rhs) { 141327b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 141427b6a85dSStefano Zampini save_rhs = PETSC_FALSE; 14158d00608fSStefano Zampini } 14168d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 14173972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 141827b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,used_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 14193972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 14208efcfb23SStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 142127b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 14227acc28cbSStefano Zampini if (ksp) { 14237acc28cbSStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_FALSE);CHKERRQ(ierr); 14247acc28cbSStefano Zampini } 14253308cffdSStefano Zampini } 14268efcfb23SStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 1427b76ba322SStefano Zampini 1428fc17d649SStefano Zampini /* compute initial vector in benign space if needed 142927b6a85dSStefano Zampini and remove non-benign solution from the rhs */ 143027b6a85dSStefano Zampini benign_correction_computed = PETSC_FALSE; 143108af2428SStefano Zampini if (rhs && pcbddc->benign_compute_correction && (pcbddc->benign_have_null || pcbddc->benign_apply_coarse_only)) { 14321f4df5f7SStefano Zampini /* compute u^*_h using ideas similar to those in Xuemin Tu's PhD thesis (see Section 4.8.1) 14331f4df5f7SStefano Zampini Recursively apply BDDC in the multilevel case */ 14340369aaf7SStefano Zampini if (!pcbddc->benign_vec) { 14350369aaf7SStefano Zampini ierr = VecDuplicate(rhs,&pcbddc->benign_vec);CHKERRQ(ierr); 14360369aaf7SStefano Zampini } 1437c69e9cc1SStefano Zampini /* keep applying coarse solver unless we no longer have benign subdomains */ 1438c69e9cc1SStefano Zampini pcbddc->benign_apply_coarse_only = pcbddc->benign_have_null ? PETSC_TRUE : PETSC_FALSE; 143927b6a85dSStefano Zampini if (!pcbddc->benign_skip_correction) { 14401dd7afcfSStefano Zampini ierr = PCApply_BDDC(pc,rhs,pcbddc->benign_vec);CHKERRQ(ierr); 14413bca92a6SStefano Zampini benign_correction_computed = PETSC_TRUE; 14421f4df5f7SStefano Zampini if (pcbddc->temp_solution_used) { 14431f4df5f7SStefano Zampini ierr = VecAXPY(pcbddc->temp_solution,1.0,pcbddc->benign_vec);CHKERRQ(ierr); 14441f4df5f7SStefano Zampini } 14451f4df5f7SStefano Zampini ierr = VecScale(pcbddc->benign_vec,-1.0);CHKERRQ(ierr); 144627b6a85dSStefano Zampini /* store the original rhs if not done earlier */ 144727b6a85dSStefano Zampini if (save_rhs) { 144827b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 144992e3dcfbSStefano Zampini } 145027b6a85dSStefano Zampini if (pcbddc->rhs_change) { 14510369aaf7SStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,rhs,rhs);CHKERRQ(ierr); 145227b6a85dSStefano Zampini } else { 145327b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 145427b6a85dSStefano Zampini } 14550369aaf7SStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 145627b6a85dSStefano Zampini } 145727b6a85dSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_FALSE; 14584df7a6bfSStefano Zampini } else { 14594df7a6bfSStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 14600369aaf7SStefano Zampini } 14612d4c4fecSStefano Zampini 14622d4c4fecSStefano Zampini /* dbg output */ 1463a198735bSStefano Zampini if (pcbddc->dbg_flag && benign_correction_computed) { 14641f4df5f7SStefano Zampini Vec v; 1465c69e9cc1SStefano Zampini 14661f4df5f7SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&v);CHKERRQ(ierr); 1467c69e9cc1SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 14681f4df5f7SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,v);CHKERRQ(ierr); 1469c69e9cc1SStefano Zampini } else { 1470c69e9cc1SStefano Zampini ierr = VecCopy(rhs,v);CHKERRQ(ierr); 1471c69e9cc1SStefano Zampini } 14721f4df5f7SStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,v,PETSC_TRUE);CHKERRQ(ierr); 1473e0fe2d75SToby Isaac ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"LEVEL %D: is the correction benign?\n",pcbddc->current_level);CHKERRQ(ierr); 1474c69e9cc1SStefano Zampini ierr = PetscScalarView(pcbddc->benign_n,pcbddc->benign_p0,pcbddc->dbg_viewer);CHKERRQ(ierr); 1475c69e9cc1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 14761f4df5f7SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 14771f4df5f7SStefano Zampini } 14780369aaf7SStefano Zampini 14790369aaf7SStefano Zampini /* set initial guess if using PCG */ 14808ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 14810369aaf7SStefano Zampini if (x && pcbddc->use_exact_dirichlet_trick) { 14820369aaf7SStefano Zampini ierr = VecSet(x,0.0);CHKERRQ(ierr); 14831dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 148427b6a85dSStefano Zampini if (benign_correction_computed) { /* we have already saved the changed rhs */ 14851dd7afcfSStefano Zampini ierr = VecLockPop(pcis->vec1_global);CHKERRQ(ierr); 14861dd7afcfSStefano Zampini } else { 14871dd7afcfSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,pcis->vec1_global);CHKERRQ(ierr); 14881dd7afcfSStefano Zampini } 14891dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14901dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14911dd7afcfSStefano Zampini } else { 14920369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14930369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14941dd7afcfSStefano Zampini } 14950369aaf7SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 1496c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 14971dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 14981dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.);CHKERRQ(ierr); 14991dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15001dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15011dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x);CHKERRQ(ierr); 15021dd7afcfSStefano Zampini } else { 15030369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15040369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15051dd7afcfSStefano Zampini } 15060369aaf7SStefano Zampini if (ksp) { 15070369aaf7SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 15080369aaf7SStefano Zampini } 15098ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_TRUE; 1510266e20e9SStefano Zampini } else if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior && benign_correction_computed && pcbddc->use_exact_dirichlet_trick) { 1511266e20e9SStefano Zampini ierr = VecLockPop(pcis->vec1_global);CHKERRQ(ierr); 15120369aaf7SStefano Zampini } 1513534831adSStefano Zampini PetscFunctionReturn(0); 1514534831adSStefano Zampini } 1515906d46d4SStefano Zampini 1516534831adSStefano Zampini /* 1517534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 1518534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 1519534831adSStefano Zampini 1520534831adSStefano Zampini Input Parameter: 1521534831adSStefano Zampini + pc - the preconditioner contex 1522534831adSStefano Zampini 1523534831adSStefano Zampini Application Interface Routine: PCPostSolve() 1524534831adSStefano Zampini 1525534831adSStefano Zampini Notes: 1526534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 1527534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1528534831adSStefano Zampini */ 1529534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1530534831adSStefano Zampini { 1531534831adSStefano Zampini PetscErrorCode ierr; 1532534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1533534831adSStefano Zampini 1534534831adSStefano Zampini PetscFunctionBegin; 15353972b0daSStefano Zampini /* add solution removed in presolve */ 15366bcfc461SStefano Zampini if (x && pcbddc->rhs_change) { 153727b6a85dSStefano Zampini if (pcbddc->temp_solution_used) { 15383425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 1539af140850Sstefano_zampini } else if (pcbddc->benign_compute_correction && pcbddc->benign_vec) { 154027b6a85dSStefano Zampini ierr = VecAXPY(x,-1.0,pcbddc->benign_vec);CHKERRQ(ierr); 15413425bc38SStefano Zampini } 1542af140850Sstefano_zampini /* restore to original state (not for FETI-DP) */ 1543af140850Sstefano_zampini if (ksp) pcbddc->temp_solution_used = PETSC_FALSE; 154427b6a85dSStefano Zampini } 154527b6a85dSStefano Zampini 1546266e20e9SStefano Zampini /* restore rhs to its original state (not needed for FETI-DP) */ 15478d00608fSStefano Zampini if (rhs && pcbddc->rhs_change) { 154827b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 15498d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 1550af140850Sstefano_zampini } 15518efcfb23SStefano Zampini /* restore ksp guess state */ 15528efcfb23SStefano Zampini if (ksp) { 15538efcfb23SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 15548ae0ca82SStefano Zampini /* reset flag for exact dirichlet trick */ 15558ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 1556af140850Sstefano_zampini } 1557534831adSStefano Zampini PetscFunctionReturn(0); 1558534831adSStefano Zampini } 1559af140850Sstefano_zampini 15600c7d97c5SJed Brown /* 15610c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 15620c7d97c5SJed Brown by setting data structures and options. 15630c7d97c5SJed Brown 15640c7d97c5SJed Brown Input Parameter: 156553cdbc3dSStefano Zampini + pc - the preconditioner context 15660c7d97c5SJed Brown 15670c7d97c5SJed Brown Application Interface Routine: PCSetUp() 15680c7d97c5SJed Brown 15690c7d97c5SJed Brown Notes: 15700c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 15710c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 15720c7d97c5SJed Brown */ 157353cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 15740c7d97c5SJed Brown { 15750c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1576c703fcc7SStefano Zampini PCBDDCSubSchurs sub_schurs; 15775e8657edSStefano Zampini Mat_IS* matis; 157808122e43SStefano Zampini MatNullSpace nearnullspace; 157935509ce9Sstefano_zampini Mat lA; 158035509ce9Sstefano_zampini IS lP,zerodiag = NULL; 158191e8d312SStefano Zampini PetscInt nrows,ncols; 158286bfa4cfSStefano Zampini PetscMPIInt size; 1583c703fcc7SStefano Zampini PetscBool computesubschurs; 15848de1fae6SStefano Zampini PetscBool computeconstraintsmatrix; 15853b03f7bbSStefano Zampini PetscBool new_nearnullspace_provided,ismatis,rl; 1586c703fcc7SStefano Zampini PetscErrorCode ierr; 15870c7d97c5SJed Brown 15880c7d97c5SJed Brown PetscFunctionBegin; 15895e8657edSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATIS,&ismatis);CHKERRQ(ierr); 15906c4ed002SBarry Smith if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner requires matrix of type MATIS"); 159191e8d312SStefano Zampini ierr = MatGetSize(pc->pmat,&nrows,&ncols);CHKERRQ(ierr); 15926c4ed002SBarry Smith if (nrows != ncols) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PCBDDC preconditioner requires a square preconditioning matrix"); 159386bfa4cfSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 159486bfa4cfSStefano Zampini 15955e8657edSStefano Zampini matis = (Mat_IS*)pc->pmat->data; 1596f4ddd8eeSStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other future nonoverlapping preconditioners */ 15973b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 159871582508SStefano Zampini Also, BDDC builds its own KSP for the Dirichlet problem */ 15993b03f7bbSStefano Zampini rl = pcbddc->recompute_topography; 16003b03f7bbSStefano Zampini if (!pc->setupcalled || pc->flag == DIFFERENT_NONZERO_PATTERN) rl = PETSC_TRUE; 16013b03f7bbSStefano Zampini ierr = MPIU_Allreduce(&rl,&pcbddc->recompute_topography,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1602c83e1ba7SStefano Zampini if (pcbddc->recompute_topography) { 1603c83e1ba7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 1604c83e1ba7SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1605c83e1ba7SStefano Zampini } else { 16068de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_FALSE; 1607c83e1ba7SStefano Zampini } 1608b087196eSStefano Zampini 1609b087196eSStefano Zampini /* check parameters' compatibility */ 1610b7ab4a40SStefano Zampini if (!pcbddc->use_deluxe_scaling) pcbddc->deluxe_zerorows = PETSC_FALSE; 1611bd2a564bSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_threshold[0] != 0.0 || pcbddc->adaptive_threshold[1] != 0.0); 161286bfa4cfSStefano Zampini pcbddc->use_deluxe_scaling = (PetscBool)(pcbddc->use_deluxe_scaling && size > 1); 161386bfa4cfSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_selection && size > 1); 1614bf3a8328SStefano Zampini pcbddc->adaptive_userdefined = (PetscBool)(pcbddc->adaptive_selection && pcbddc->adaptive_userdefined); 1615862806e4SStefano Zampini if (pcbddc->adaptive_selection) pcbddc->use_faces = PETSC_TRUE; 1616862806e4SStefano Zampini 16175a95e1ceSStefano Zampini computesubschurs = (PetscBool)(pcbddc->adaptive_selection || pcbddc->use_deluxe_scaling); 161816909a7fSStefano Zampini if (pcbddc->switch_static) { 161916909a7fSStefano Zampini PetscBool ismatis; 1620d9869140SStefano Zampini 162116909a7fSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->mat,MATIS,&ismatis);CHKERRQ(ierr); 162216909a7fSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"When the static switch is one, the iteration matrix should be of type MATIS"); 162316909a7fSStefano Zampini } 162416909a7fSStefano Zampini 162571582508SStefano Zampini /* activate all connected components if the netflux has been requested */ 1626bb05f991SStefano Zampini if (pcbddc->compute_nonetflux) { 1627bb05f991SStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 1628bb05f991SStefano Zampini pcbddc->use_edges = PETSC_TRUE; 1629bb05f991SStefano Zampini pcbddc->use_faces = PETSC_TRUE; 1630bb05f991SStefano Zampini } 1631bb05f991SStefano Zampini 1632f4ddd8eeSStefano Zampini /* Get stdout for dbg */ 163370cf5478SStefano Zampini if (pcbddc->dbg_flag) { 163470cf5478SStefano Zampini if (!pcbddc->dbg_viewer) { 163558a03d70SStefano Zampini pcbddc->dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pc)); 1636f4ddd8eeSStefano Zampini } 1637d9869140SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 163858a03d70SStefano Zampini ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1639f4ddd8eeSStefano Zampini } 1640f4ddd8eeSStefano Zampini 1641c703fcc7SStefano Zampini /* process topology information */ 164243371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Topology[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 164371582508SStefano Zampini if (pcbddc->recompute_topography) { 164471582508SStefano Zampini ierr = PCBDDCComputeLocalTopologyInfo(pc);CHKERRQ(ierr); 1645c703fcc7SStefano Zampini if (pcbddc->discretegradient) { 1646a13144ffSStefano Zampini ierr = PCBDDCNedelecSupport(pc);CHKERRQ(ierr); 1647a13144ffSStefano Zampini } 1648c703fcc7SStefano Zampini } 1649a13144ffSStefano Zampini 1650c703fcc7SStefano Zampini /* change basis if requested by the user */ 16515e8657edSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 16525e8657edSStefano Zampini /* use_change_of_basis flag is used to automatically compute a change of basis from constraints */ 16535e8657edSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 16545e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 16555e8657edSStefano Zampini } else { 1656b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 16575e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 16585e8657edSStefano Zampini pcbddc->local_mat = matis->A; 1659d16cbb6bSStefano Zampini } 1660d16cbb6bSStefano Zampini 16614f1b2e48SStefano Zampini /* 1662c703fcc7SStefano Zampini Compute change of basis on local pressures (aka zerodiag dofs) with the benign trick 16634f1b2e48SStefano Zampini This should come earlier then PCISSetUp for extracting the correct subdomain matrices 16644f1b2e48SStefano Zampini */ 16651dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 1666d16cbb6bSStefano Zampini if (pcbddc->benign_saddle_point) { 16679f47a83aSStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 16689f47a83aSStefano Zampini 166905b28244SStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->use_change_of_basis || !computesubschurs) pcbddc->benign_change_explicit = PETSC_TRUE; 16703b03f7bbSStefano Zampini /* detect local saddle point and change the basis in pcbddc->local_mat */ 16713b03f7bbSStefano Zampini ierr = PCBDDCBenignDetectSaddlePoint(pc,(PetscBool)(!pcbddc->recompute_topography),&zerodiag);CHKERRQ(ierr); 1672a3df083aSStefano Zampini /* pop B0 mat from local mat */ 1673c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 16741dd7afcfSStefano Zampini /* give pcis a hint to not reuse submatrices during PCISCreate */ 16751dd7afcfSStefano Zampini if (pc->flag == SAME_NONZERO_PATTERN && pcis->reusesubmatrices == PETSC_TRUE) { 16761dd7afcfSStefano Zampini if (pcbddc->benign_n && (pcbddc->benign_change_explicit || pcbddc->dbg_flag)) { 16771dd7afcfSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 16781dd7afcfSStefano Zampini } else { 1679a3df083aSStefano Zampini pcis->reusesubmatrices = PETSC_TRUE; 16801dd7afcfSStefano Zampini } 1681a3df083aSStefano Zampini } else { 16829f47a83aSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 1683674ae819SStefano Zampini } 1684a3df083aSStefano Zampini } 168527b6a85dSStefano Zampini 16868037d520SStefano Zampini /* propagate relevant information */ 168706a4e24aSStefano Zampini if (matis->A->symmetric_set) { 168806a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 168906a4e24aSStefano Zampini } 169006a4e24aSStefano Zampini if (matis->A->spd_set) { 169106a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SPD,matis->A->spd);CHKERRQ(ierr); 169206a4e24aSStefano Zampini } 1693e496cd5dSStefano Zampini 16945e8657edSStefano Zampini /* Set up all the "iterative substructuring" common block without computing solvers */ 16955e8657edSStefano Zampini { 16965e8657edSStefano Zampini Mat temp_mat; 16975e8657edSStefano Zampini 16985e8657edSStefano Zampini temp_mat = matis->A; 16995e8657edSStefano Zampini matis->A = pcbddc->local_mat; 1700d9869140SStefano Zampini ierr = PCISSetUp(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 17015e8657edSStefano Zampini pcbddc->local_mat = matis->A; 17025e8657edSStefano Zampini matis->A = temp_mat; 17035e8657edSStefano Zampini } 1704684f6988SStefano Zampini 170581d14e9dSStefano Zampini /* Analyze interface */ 170664ac59b8SStefano Zampini if (!pcbddc->graphanalyzed) { 1707674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 17088de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1709345ecf6cSStefano Zampini if (pcbddc->adaptive_selection && !pcbddc->use_deluxe_scaling && !pcbddc->mat_graph->twodim) { 17104247aa23Sstefano_zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot compute the adaptive primal space for a problem with 3D edges without deluxe scaling"); 1711345ecf6cSStefano Zampini } 1712a198735bSStefano Zampini if (pcbddc->compute_nonetflux) { 1713669cc0f4SStefano Zampini MatNullSpace nnfnnsp; 1714669cc0f4SStefano Zampini 171521ef3d20SStefano Zampini if (!pcbddc->divudotp) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Missing divudotp operator"); 17168ae0ca82SStefano Zampini ierr = PCBDDCComputeNoNetFlux(pc->pmat,pcbddc->divudotp,pcbddc->divudotp_trans,pcbddc->divudotp_vl2l,pcbddc->mat_graph,&nnfnnsp);CHKERRQ(ierr); 171771582508SStefano Zampini /* TODO what if a nearnullspace is already attached? */ 17188037d520SStefano Zampini if (nnfnnsp) { 1719669cc0f4SStefano Zampini ierr = MatSetNearNullSpace(pc->pmat,nnfnnsp);CHKERRQ(ierr); 1720669cc0f4SStefano Zampini ierr = MatNullSpaceDestroy(&nnfnnsp);CHKERRQ(ierr); 1721669cc0f4SStefano Zampini } 1722674ae819SStefano Zampini } 17238037d520SStefano Zampini } 172443371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Topology[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 1725fb8d54d4SStefano Zampini 17265408967cSStefano Zampini /* check existence of a divergence free extension, i.e. 17275408967cSStefano Zampini b(v_I,p_0) = 0 for all v_I (raise error if not). 17285408967cSStefano Zampini Also, check that PCBDDCBenignGetOrSetP0 works */ 1729ff1f7e73Sstefano_zampini if (pcbddc->benign_saddle_point && pcbddc->dbg_flag > 1) { 17305408967cSStefano Zampini ierr = PCBDDCBenignCheck(pc,zerodiag);CHKERRQ(ierr); 173109f581a4SStefano Zampini } 17324f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 173306f24817SStefano Zampini 1734b96c3477SStefano Zampini /* Setup local dirichlet solver ksp_D and sub_schurs solvers */ 1735c703fcc7SStefano Zampini if (computesubschurs && pcbddc->recompute_topography) { 173608122e43SStefano Zampini ierr = PCBDDCInitSubSchurs(pc);CHKERRQ(ierr); 1737b1b3d7a2SStefano Zampini } 17389d54b7f4SStefano Zampini /* SetUp Scaling operator (scaling matrices could be needed in SubSchursSetUp)*/ 17399d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) { 17409d54b7f4SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 17419d54b7f4SStefano Zampini } 1742c703fcc7SStefano Zampini 1743c703fcc7SStefano Zampini /* finish setup solvers and do adaptive selection of constraints */ 1744b334f244SStefano Zampini sub_schurs = pcbddc->sub_schurs; 1745b334f244SStefano Zampini if (sub_schurs && sub_schurs->schur_explicit) { 17462070dbb6SStefano Zampini if (computesubschurs) { 174708122e43SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 17482070dbb6SStefano Zampini } 1749d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 1750d5574798SStefano Zampini } else { 1751d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 17522070dbb6SStefano Zampini if (computesubschurs) { 1753d5574798SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 1754d5574798SStefano Zampini } 17552070dbb6SStefano Zampini } 175608122e43SStefano Zampini if (pcbddc->adaptive_selection) { 175708122e43SStefano Zampini ierr = PCBDDCAdaptiveSelection(pc);CHKERRQ(ierr); 17588de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1759b7eb3628SStefano Zampini } 1760684f6988SStefano Zampini 1761f4ddd8eeSStefano Zampini /* infer if NullSpace object attached to Mat via MatSetNearNullSpace has changed */ 1762fb8d54d4SStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1763f4ddd8eeSStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullspace);CHKERRQ(ierr); 1764f4ddd8eeSStefano Zampini if (pcbddc->onearnullspace) { /* already used nearnullspace */ 1765f4ddd8eeSStefano Zampini if (!nearnullspace) { /* near null space attached to mat has been destroyed */ 1766f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1767f4ddd8eeSStefano Zampini } else { 1768f4ddd8eeSStefano Zampini /* determine if the two nullspaces are different (should be lightweight) */ 1769f4ddd8eeSStefano Zampini if (nearnullspace != pcbddc->onearnullspace) { 1770f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1771165b64e2SStefano Zampini } else { /* maybe the user has changed the content of the nearnullspace so check vectors ObjectStateId */ 1772f4ddd8eeSStefano Zampini PetscInt i; 1773165b64e2SStefano Zampini const Vec *nearnullvecs; 1774165b64e2SStefano Zampini PetscObjectState state; 1775165b64e2SStefano Zampini PetscInt nnsp_size; 1776165b64e2SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullspace,NULL,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1777f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1778f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&state);CHKERRQ(ierr); 1779165b64e2SStefano Zampini if (pcbddc->onearnullvecs_state[i] != state) { 1780f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1781f4ddd8eeSStefano Zampini break; 1782f4ddd8eeSStefano Zampini } 1783f4ddd8eeSStefano Zampini } 1784f4ddd8eeSStefano Zampini } 1785f4ddd8eeSStefano Zampini } 1786f4ddd8eeSStefano Zampini } else { 1787f4ddd8eeSStefano Zampini if (!nearnullspace) { /* both nearnullspaces are null */ 1788f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1789f4ddd8eeSStefano Zampini } else { /* nearnullspace attached later */ 1790f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1791f4ddd8eeSStefano Zampini } 1792f4ddd8eeSStefano Zampini } 1793f4ddd8eeSStefano Zampini 1794f4ddd8eeSStefano Zampini /* Setup constraints and related work vectors */ 1795727cdba6SStefano Zampini /* reset primal space flags */ 179643371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_LocalWork[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 1797f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 1798727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 17998de1fae6SStefano Zampini if (computeconstraintsmatrix || new_nearnullspace_provided) { 1800727cdba6SStefano Zampini /* It also sets the primal space flags */ 1801674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 18029543d0ffSStefano Zampini } 1803e7b262bdSStefano Zampini /* Allocate needed local vectors (which depends on quantities defined during ConstraintsSetUp) */ 1804f4ddd8eeSStefano Zampini ierr = PCBDDCSetUpLocalWorkVectors(pc);CHKERRQ(ierr); 18055e8657edSStefano Zampini 18065e8657edSStefano Zampini if (pcbddc->use_change_of_basis) { 18075e8657edSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 18085e8657edSStefano Zampini 18095e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 18104f1b2e48SStefano Zampini if (pcbddc->benign_change) { 18111dd7afcfSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 1812c263805aSStefano Zampini /* pop B0 from pcbddc->local_mat */ 1813c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 1814c263805aSStefano Zampini } 18155e8657edSStefano Zampini /* get submatrices */ 18165e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 18175e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 18185e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 18197dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 18207dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 18217dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 18223975b054SStefano Zampini /* set flag in pcis to not reuse submatrices during PCISCreate */ 18233975b054SStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 18249c6a02ceSStefano Zampini } else if (!pcbddc->user_ChangeOfBasisMatrix && !pcbddc->benign_change) { 1825b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 18265e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 18275e8657edSStefano Zampini pcbddc->local_mat = matis->A; 18285e8657edSStefano Zampini } 182935509ce9Sstefano_zampini 183035509ce9Sstefano_zampini /* interface pressure block row for B_C */ 183135509ce9Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lP" ,(PetscObject*)&lP);CHKERRQ(ierr); 183235509ce9Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject*)&lA);CHKERRQ(ierr); 183335509ce9Sstefano_zampini if (lA && lP) { 183435509ce9Sstefano_zampini PC_IS* pcis = (PC_IS*)pc->data; 183535509ce9Sstefano_zampini Mat B_BI,B_BB,Bt_BI,Bt_BB; 183635509ce9Sstefano_zampini PetscBool issym; 183735509ce9Sstefano_zampini ierr = MatIsSymmetric(lA,PETSC_SMALL,&issym);CHKERRQ(ierr); 18386cc1294bSstefano_zampini if (issym) { 18397dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_I_local,MAT_INITIAL_MATRIX,&B_BI);CHKERRQ(ierr); 18407dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_B_local,MAT_INITIAL_MATRIX,&B_BB);CHKERRQ(ierr); 184135509ce9Sstefano_zampini ierr = MatCreateTranspose(B_BI,&Bt_BI);CHKERRQ(ierr); 184235509ce9Sstefano_zampini ierr = MatCreateTranspose(B_BB,&Bt_BB);CHKERRQ(ierr); 184335509ce9Sstefano_zampini } else { 18447dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_I_local,MAT_INITIAL_MATRIX,&B_BI);CHKERRQ(ierr); 18457dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,lP,pcis->is_B_local,MAT_INITIAL_MATRIX,&B_BB);CHKERRQ(ierr); 18467dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,pcis->is_I_local,lP,MAT_INITIAL_MATRIX,&Bt_BI);CHKERRQ(ierr); 18477dae84e0SHong Zhang ierr = MatCreateSubMatrix(lA,pcis->is_B_local,lP,MAT_INITIAL_MATRIX,&Bt_BB);CHKERRQ(ierr); 184835509ce9Sstefano_zampini } 184935509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_B_BI",(PetscObject)B_BI);CHKERRQ(ierr); 185035509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_B_BB",(PetscObject)B_BB);CHKERRQ(ierr); 185135509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_Bt_BI",(PetscObject)Bt_BI);CHKERRQ(ierr); 185235509ce9Sstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_Bt_BB",(PetscObject)Bt_BB);CHKERRQ(ierr); 185335509ce9Sstefano_zampini ierr = MatDestroy(&B_BI);CHKERRQ(ierr); 185435509ce9Sstefano_zampini ierr = MatDestroy(&B_BB);CHKERRQ(ierr); 185535509ce9Sstefano_zampini ierr = MatDestroy(&Bt_BI);CHKERRQ(ierr); 185635509ce9Sstefano_zampini ierr = MatDestroy(&Bt_BB);CHKERRQ(ierr); 185735509ce9Sstefano_zampini } 185843371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_LocalWork[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 185935509ce9Sstefano_zampini 1860b96c3477SStefano Zampini /* SetUp coarse and local Neumann solvers */ 186199cc7994SStefano Zampini ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr); 1862b96c3477SStefano Zampini /* SetUp Scaling operator */ 18639d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1864674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 18650c7d97c5SJed Brown } 1866c703fcc7SStefano Zampini 18671dd7afcfSStefano Zampini /* mark topography as done */ 186856282151SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 18690369aaf7SStefano Zampini 18701dd7afcfSStefano Zampini /* wrap pcis->A_IB and pcis->A_BI if we did not change explicitly the variables on the pressures */ 18711dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_FALSE);CHKERRQ(ierr); 18721dd7afcfSStefano Zampini 187358a03d70SStefano Zampini if (pcbddc->dbg_flag) { 187458a03d70SStefano Zampini ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1875d9869140SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 18762b510759SStefano Zampini } 18770c7d97c5SJed Brown PetscFunctionReturn(0); 18780c7d97c5SJed Brown } 18790c7d97c5SJed Brown 18800c7d97c5SJed Brown /* 188150efa1b5SStefano Zampini PCApply_BDDC - Applies the BDDC operator to a vector. 18820c7d97c5SJed Brown 18830c7d97c5SJed Brown Input Parameters: 18840f202f7eSStefano Zampini + pc - the preconditioner context 18850f202f7eSStefano Zampini - r - input vector (global) 18860c7d97c5SJed Brown 18870c7d97c5SJed Brown Output Parameter: 18880c7d97c5SJed Brown . z - output vector (global) 18890c7d97c5SJed Brown 18900c7d97c5SJed Brown Application Interface Routine: PCApply() 18910c7d97c5SJed Brown */ 189253cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 18930c7d97c5SJed Brown { 18940c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 18950c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1896b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 18970c7d97c5SJed Brown PetscErrorCode ierr; 18983b03a366Sstefano_zampini const PetscScalar one = 1.0; 18993b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 19002617d88aSStefano Zampini const PetscScalar zero = 0.0; 19010c7d97c5SJed Brown 19020c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 19030c7d97c5SJed Brown NN interface preconditioner changed to BDDC 1904b097fa66SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static == PETSC_TRUE) */ 19050c7d97c5SJed Brown 19060c7d97c5SJed Brown PetscFunctionBegin; 1907f3d41395Sstefano_zampini ierr = PetscCitationsRegister(citation,&cited);CHKERRQ(ierr); 19081dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 19091dd7afcfSStefano Zampini Vec swap; 191027b6a85dSStefano Zampini 191127b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 19121dd7afcfSStefano Zampini swap = pcbddc->work_change; 19131dd7afcfSStefano Zampini pcbddc->work_change = r; 19141dd7afcfSStefano Zampini r = swap; 19151dd7afcfSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 19169cc2a9b1Sstefano_zampini if (pcbddc->benign_apply_coarse_only && pcbddc->use_exact_dirichlet_trick && pcbddc->change_interior) { 19171dd7afcfSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 19181dd7afcfSStefano Zampini ierr = VecLockPush(pcis->vec1_global);CHKERRQ(ierr); 19191dd7afcfSStefano Zampini } 19201dd7afcfSStefano Zampini } 192127b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 1922015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1923efc2fbd9SStefano Zampini } 19248ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 1925b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 19260c7d97c5SJed Brown /* First Dirichlet solve */ 19270c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19280c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19290c7d97c5SJed Brown /* 19300c7d97c5SJed Brown Assembling right hand side for BDDC operator 1931b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 1932674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 19330c7d97c5SJed Brown */ 1934b097fa66SStefano Zampini if (n_D) { 1935b097fa66SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 1936c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 19370c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 193816909a7fSStefano Zampini if (pcbddc->switch_static) { 193916909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 194016909a7fSStefano Zampini 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) { 194516909a7fSStefano Zampini ierr = MatMult(matis->A,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); 194816909a7fSStefano Zampini ierr = MatMult(matis->A,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 Mat_IS *matis = (Mat_IS*)(pc->mat->data); 198316909a7fSStefano Zampini 198416909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 198516909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 198616909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 198716909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 198816909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 198916909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 199016909a7fSStefano Zampini } else { 199116909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 199216909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 199316909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 199416909a7fSStefano Zampini } 199516909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 199616909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 199716909a7fSStefano Zampini } else { 19980c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 199916909a7fSStefano Zampini } 200016909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 200116909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 200216909a7fSStefano Zampini 200316909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 200416909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 200516909a7fSStefano Zampini } else { 200616909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 200716909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 200816909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 200916909a7fSStefano Zampini } 2010b097fa66SStefano Zampini } 2011df187020SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 2012c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec4_D);CHKERRQ(ierr); 2013efc2fbd9SStefano Zampini 20148ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2015b097fa66SStefano Zampini if (pcbddc->switch_static) { 2016b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 2017b097fa66SStefano Zampini } else { 2018b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 2019b097fa66SStefano Zampini } 20200c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20210c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2022b097fa66SStefano Zampini } else { 2023b097fa66SStefano Zampini if (pcbddc->switch_static) { 2024b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 2025b097fa66SStefano Zampini } else { 2026b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 2027b097fa66SStefano Zampini } 2028b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2029b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2030b097fa66SStefano Zampini } 203127b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 20321dd7afcfSStefano Zampini if (pcbddc->benign_apply_coarse_only) { 20331dd7afcfSStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 20341dd7afcfSStefano Zampini } 2035015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 2036efc2fbd9SStefano Zampini } 20371f4df5f7SStefano Zampini 20381dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2039f913dca9SStefano Zampini pcbddc->work_change = r; 20401dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 20411dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 20421dd7afcfSStefano Zampini } 20430c7d97c5SJed Brown PetscFunctionReturn(0); 20440c7d97c5SJed Brown } 204550efa1b5SStefano Zampini 204650efa1b5SStefano Zampini /* 204750efa1b5SStefano Zampini PCApplyTranspose_BDDC - Applies the transpose of the BDDC operator to a vector. 204850efa1b5SStefano Zampini 204950efa1b5SStefano Zampini Input Parameters: 20500f202f7eSStefano Zampini + pc - the preconditioner context 20510f202f7eSStefano Zampini - r - input vector (global) 205250efa1b5SStefano Zampini 205350efa1b5SStefano Zampini Output Parameter: 205450efa1b5SStefano Zampini . z - output vector (global) 205550efa1b5SStefano Zampini 205650efa1b5SStefano Zampini Application Interface Routine: PCApplyTranspose() 205750efa1b5SStefano Zampini */ 205850efa1b5SStefano Zampini PetscErrorCode PCApplyTranspose_BDDC(PC pc,Vec r,Vec z) 205950efa1b5SStefano Zampini { 206050efa1b5SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 206150efa1b5SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 2062b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 206350efa1b5SStefano Zampini PetscErrorCode ierr; 206450efa1b5SStefano Zampini const PetscScalar one = 1.0; 206550efa1b5SStefano Zampini const PetscScalar m_one = -1.0; 206650efa1b5SStefano Zampini const PetscScalar zero = 0.0; 206750efa1b5SStefano Zampini 206850efa1b5SStefano Zampini PetscFunctionBegin; 2069f3d41395Sstefano_zampini ierr = PetscCitationsRegister(citation,&cited);CHKERRQ(ierr); 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); 208027b6a85dSStefano Zampini ierr = VecLockPush(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 Mat_IS *matis = (Mat_IS*)(pc->mat->data); 210216909a7fSStefano Zampini 210316909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 210416909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 210516909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 210616909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 210716909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 210816909a7fSStefano Zampini } else { 210916909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 211016909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 211116909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 211216909a7fSStefano Zampini } 211316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 211416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 211516909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 211616909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 211716909a7fSStefano Zampini } else { 2118b097fa66SStefano Zampini ierr = MatMultTranspose(pcis->A_IB,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 211916909a7fSStefano Zampini } 2120b097fa66SStefano Zampini } else { 2121b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 2122b097fa66SStefano Zampini } 212350efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 212450efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 212550efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 212650efa1b5SStefano Zampini } else { 212750efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 212850efa1b5SStefano Zampini } 212950efa1b5SStefano Zampini 213050efa1b5SStefano Zampini /* Apply interface preconditioner 213150efa1b5SStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 2132dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_TRUE);CHKERRQ(ierr); 213350efa1b5SStefano Zampini 213450efa1b5SStefano Zampini /* Apply transpose of partition of unity operator */ 213550efa1b5SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 213650efa1b5SStefano Zampini 213750efa1b5SStefano Zampini /* Second Dirichlet solve and assembling of output */ 213850efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 213950efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2140b097fa66SStefano Zampini if (n_B) { 214116909a7fSStefano Zampini if (pcbddc->switch_static) { 214216909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 214316909a7fSStefano Zampini 214416909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 214516909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 214616909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 214716909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 214816909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 214916909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 215016909a7fSStefano Zampini } else { 215116909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 215216909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 215316909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 215416909a7fSStefano Zampini } 215516909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 215616909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 215716909a7fSStefano Zampini } else { 215850efa1b5SStefano Zampini ierr = MatMultTranspose(pcis->A_BI,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 215916909a7fSStefano Zampini } 216016909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 216116909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 216216909a7fSStefano Zampini 216316909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 216416909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 216516909a7fSStefano Zampini } else { 216616909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 216716909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 216816909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 216916909a7fSStefano Zampini } 2170b097fa66SStefano Zampini } 2171b0147a47SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 2172c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec4_D);CHKERRQ(ierr); 21738ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2174b097fa66SStefano Zampini if (pcbddc->switch_static) { 2175b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 2176b097fa66SStefano Zampini } else { 2177b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 2178b097fa66SStefano Zampini } 217950efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 218050efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2181b097fa66SStefano Zampini } else { 2182b097fa66SStefano Zampini if (pcbddc->switch_static) { 2183b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 2184b097fa66SStefano Zampini } else { 2185b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 2186b097fa66SStefano Zampini } 2187b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2188b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2189b097fa66SStefano Zampini } 219027b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 2191537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 2192537c1cdfSStefano Zampini } 21931dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2194f913dca9SStefano Zampini pcbddc->work_change = r; 21951dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 21961dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 21971dd7afcfSStefano Zampini } 219850efa1b5SStefano Zampini PetscFunctionReturn(0); 219950efa1b5SStefano Zampini } 2200674ae819SStefano Zampini 22019326c5c6Sstefano_zampini PetscErrorCode PCReset_BDDC(PC pc) 2202da1bb401SStefano Zampini { 2203da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 22049326c5c6Sstefano_zampini PC_IS *pcis = (PC_IS*)pc->data; 22059326c5c6Sstefano_zampini KSP kspD,kspR,kspC; 2206da1bb401SStefano Zampini PetscErrorCode ierr; 2207da1bb401SStefano Zampini 2208da1bb401SStefano Zampini PetscFunctionBegin; 2209674ae819SStefano Zampini /* free BDDC custom data */ 2210674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 2211674ae819SStefano Zampini /* destroy objects related to topography */ 2212674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 221334a97f8cSStefano Zampini /* destroy objects for scaling operator */ 2214674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 2215674ae819SStefano Zampini /* free solvers stuff */ 2216674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 221762a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 221862a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 221962a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 22201dd7afcfSStefano Zampini /* free data created by PCIS */ 22211dd7afcfSStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 22229326c5c6Sstefano_zampini 22239326c5c6Sstefano_zampini /* restore defaults */ 22249326c5c6Sstefano_zampini kspD = pcbddc->ksp_D; 22259326c5c6Sstefano_zampini kspR = pcbddc->ksp_R; 22269326c5c6Sstefano_zampini kspC = pcbddc->coarse_ksp; 22279326c5c6Sstefano_zampini ierr = PetscMemzero(pc->data,sizeof(*pcbddc));CHKERRQ(ierr); 22289326c5c6Sstefano_zampini pcis->n_neigh = -1; 22299326c5c6Sstefano_zampini pcis->scaling_factor = 1.0; 22309326c5c6Sstefano_zampini pcis->reusesubmatrices = PETSC_TRUE; 22319326c5c6Sstefano_zampini pcbddc->use_local_adj = PETSC_TRUE; 22329326c5c6Sstefano_zampini pcbddc->use_vertices = PETSC_TRUE; 22339326c5c6Sstefano_zampini pcbddc->use_edges = PETSC_TRUE; 22349326c5c6Sstefano_zampini pcbddc->symmetric_primal = PETSC_TRUE; 22359326c5c6Sstefano_zampini pcbddc->vertex_size = 1; 22369326c5c6Sstefano_zampini pcbddc->recompute_topography = PETSC_TRUE; 22379326c5c6Sstefano_zampini pcbddc->coarse_size = -1; 22389326c5c6Sstefano_zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 22399326c5c6Sstefano_zampini pcbddc->coarsening_ratio = 8; 22409326c5c6Sstefano_zampini pcbddc->coarse_eqs_per_proc = 1; 22419326c5c6Sstefano_zampini pcbddc->benign_compute_correction = PETSC_TRUE; 22429326c5c6Sstefano_zampini pcbddc->nedfield = -1; 22439326c5c6Sstefano_zampini pcbddc->nedglobal = PETSC_TRUE; 22449326c5c6Sstefano_zampini pcbddc->graphmaxcount = PETSC_MAX_INT; 22459326c5c6Sstefano_zampini pcbddc->sub_schurs_layers = -1; 22469326c5c6Sstefano_zampini pcbddc->ksp_D = kspD; 22479326c5c6Sstefano_zampini pcbddc->ksp_R = kspR; 22489326c5c6Sstefano_zampini pcbddc->coarse_ksp = kspC; 22499326c5c6Sstefano_zampini PetscFunctionReturn(0); 22509326c5c6Sstefano_zampini } 22519326c5c6Sstefano_zampini 22529326c5c6Sstefano_zampini PetscErrorCode PCDestroy_BDDC(PC pc) 22539326c5c6Sstefano_zampini { 22549326c5c6Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 22559326c5c6Sstefano_zampini PetscErrorCode ierr; 22569326c5c6Sstefano_zampini 22579326c5c6Sstefano_zampini PetscFunctionBegin; 22589326c5c6Sstefano_zampini ierr = PCReset_BDDC(pc);CHKERRQ(ierr); 22599326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 22609326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 22619326c5c6Sstefano_zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 2262a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",NULL);CHKERRQ(ierr); 2263a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",NULL);CHKERRQ(ierr); 2264906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",NULL);CHKERRQ(ierr); 2265674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 226630368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",NULL);CHKERRQ(ierr); 2267bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 22682b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr); 2269b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr); 22702b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr); 2271bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 227282ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2273bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 227482ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2275bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 227682ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2277bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 2278785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2279bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 228063602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",NULL);CHKERRQ(ierr); 2281bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 2282bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 2283bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 2284bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 2285a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",NULL);CHKERRQ(ierr); 2286ab8c8b98SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",NULL);CHKERRQ(ierr); 2287674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 2288da1bb401SStefano Zampini PetscFunctionReturn(0); 2289da1bb401SStefano Zampini } 22901e6b0712SBarry Smith 2291ab8c8b98SStefano Zampini static PetscErrorCode PCSetCoordinates_BDDC(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 2292ab8c8b98SStefano Zampini { 2293ab8c8b98SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2294ab8c8b98SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 2295ab8c8b98SStefano Zampini PetscErrorCode ierr; 2296ab8c8b98SStefano Zampini 2297ab8c8b98SStefano Zampini PetscFunctionBegin; 2298ab8c8b98SStefano Zampini ierr = PetscFree(mat_graph->coords);CHKERRQ(ierr); 2299ab8c8b98SStefano Zampini ierr = PetscMalloc1(nloc*dim,&mat_graph->coords);CHKERRQ(ierr); 2300ab8c8b98SStefano Zampini ierr = PetscMemcpy(mat_graph->coords,coords,nloc*dim*sizeof(PetscReal));CHKERRQ(ierr); 2301ab8c8b98SStefano Zampini mat_graph->cnloc = nloc; 2302ab8c8b98SStefano Zampini mat_graph->cdim = dim; 2303ab8c8b98SStefano Zampini mat_graph->cloc = PETSC_FALSE; 2304ab8c8b98SStefano Zampini PetscFunctionReturn(0); 2305ab8c8b98SStefano Zampini } 2306ab8c8b98SStefano Zampini 2307a06fd7f2SStefano Zampini static PetscErrorCode PCPreSolveChangeRHS_BDDC(PC pc, PetscBool* change) 2308a06fd7f2SStefano Zampini { 2309a06fd7f2SStefano Zampini PetscFunctionBegin; 2310a06fd7f2SStefano Zampini *change = PETSC_TRUE; 2311a06fd7f2SStefano Zampini PetscFunctionReturn(0); 2312a06fd7f2SStefano Zampini } 2313a06fd7f2SStefano Zampini 23143425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 23153425bc38SStefano Zampini { 2316674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 2317266e20e9SStefano Zampini Vec work; 23183425bc38SStefano Zampini PC_IS* pcis; 23193425bc38SStefano Zampini PC_BDDC* pcbddc; 23203425bc38SStefano Zampini PetscErrorCode ierr; 23210c7d97c5SJed Brown 23223425bc38SStefano Zampini PetscFunctionBegin; 23233425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 23243425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 23253425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 23263425bc38SStefano Zampini 2327229984c5Sstefano_zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 2328229984c5Sstefano_zampini /* copy rhs since we may change it during PCPreSolve_BDDC */ 2329229984c5Sstefano_zampini if (!pcbddc->original_rhs) { 2330229984c5Sstefano_zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 2331229984c5Sstefano_zampini } 23326cc1294bSstefano_zampini if (mat_ctx->rhs_flip) { 23336cc1294bSstefano_zampini ierr = VecPointwiseMult(pcbddc->original_rhs,standard_rhs,mat_ctx->rhs_flip);CHKERRQ(ierr); 23346cc1294bSstefano_zampini } else { 2335229984c5Sstefano_zampini ierr = VecCopy(standard_rhs,pcbddc->original_rhs);CHKERRQ(ierr); 23366cc1294bSstefano_zampini } 2337af140850Sstefano_zampini if (mat_ctx->g2g_p) { 2338229984c5Sstefano_zampini /* interface pressure rhs */ 2339022d8d2bSstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,fetidp_flux_rhs,pcbddc->original_rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2340022d8d2bSstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,fetidp_flux_rhs,pcbddc->original_rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2341229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,standard_rhs,fetidp_flux_rhs,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2342229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,standard_rhs,fetidp_flux_rhs,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23436cc1294bSstefano_zampini if (!mat_ctx->rhs_flip) { 2344229984c5Sstefano_zampini ierr = VecScale(fetidp_flux_rhs,-1.);CHKERRQ(ierr); 2345229984c5Sstefano_zampini } 23466cc1294bSstefano_zampini } 2347c08af4c6SStefano Zampini /* 2348c08af4c6SStefano Zampini change of basis for physical rhs if needed 2349c08af4c6SStefano Zampini It also changes the rhs in case of dirichlet boundaries 2350c08af4c6SStefano Zampini */ 23513738a8e6SStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,pcbddc->original_rhs,NULL);CHKERRQ(ierr); 2352fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 23533738a8e6SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcbddc->original_rhs,pcbddc->work_change);CHKERRQ(ierr); 23543738a8e6SStefano Zampini work = pcbddc->work_change; 2355fc17d649SStefano Zampini } else { 23563738a8e6SStefano Zampini work = pcbddc->original_rhs; 2357fc17d649SStefano Zampini } 23583425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 2359266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2360266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2361fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 2362fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 2363266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2364266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2365674ae819SStefano Zampini /* Apply partition of unity */ 23663425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 2367266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 23688eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 23693425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 23703425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 2371c0decd05SBarry Smith /* Cannot propagate up error in KSPSolve() because there is no access to the PC */ 23723425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 23733425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 2374266e20e9SStefano Zampini ierr = VecSet(work,0.0);CHKERRQ(ierr); 2375266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2376266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2377266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 2378266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2379266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23803425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 23813425bc38SStefano Zampini } 23823425bc38SStefano Zampini /* BDDC rhs */ 23833425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 23848eeda7d8SStefano Zampini if (pcbddc->switch_static) { 23853425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 23863425bc38SStefano Zampini } 23873425bc38SStefano Zampini /* apply BDDC */ 2388229984c5Sstefano_zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 2389dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2390266e20e9SStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 2391229984c5Sstefano_zampini 23923425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 23933425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 23943425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23953425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2396229984c5Sstefano_zampini /* Add contribution to interface pressures */ 2397229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2398229984c5Sstefano_zampini ierr = MatMult(mat_ctx->B_BB,pcis->vec1_B,mat_ctx->vP);CHKERRQ(ierr); 2399229984c5Sstefano_zampini if (pcbddc->switch_static) { 2400229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->B_BI,pcis->vec1_D,mat_ctx->vP,mat_ctx->vP);CHKERRQ(ierr); 2401229984c5Sstefano_zampini } 2402229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->l2g_p,mat_ctx->vP,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2403229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->l2g_p,mat_ctx->vP,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2404229984c5Sstefano_zampini } 24053425bc38SStefano Zampini PetscFunctionReturn(0); 24063425bc38SStefano Zampini } 24071e6b0712SBarry Smith 24083425bc38SStefano Zampini /*@ 24090f202f7eSStefano Zampini PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETI-DP linear system using the physical right-hand side 24103425bc38SStefano Zampini 24113425bc38SStefano Zampini Collective 24123425bc38SStefano Zampini 24133425bc38SStefano Zampini Input Parameters: 24140f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix object obtained by a call to PCBDDCCreateFETIDPOperators 24150f202f7eSStefano Zampini - standard_rhs - the right-hand side of the original linear system 24163425bc38SStefano Zampini 24173425bc38SStefano Zampini Output Parameters: 24180f202f7eSStefano Zampini . fetidp_flux_rhs - the right-hand side for the FETI-DP linear system 24193425bc38SStefano Zampini 24203425bc38SStefano Zampini Level: developer 24213425bc38SStefano Zampini 24223425bc38SStefano Zampini Notes: 24233425bc38SStefano Zampini 24240f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetSolution 24253425bc38SStefano Zampini @*/ 24263425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 24273425bc38SStefano Zampini { 2428674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 24293425bc38SStefano Zampini PetscErrorCode ierr; 24303425bc38SStefano Zampini 24313425bc38SStefano Zampini PetscFunctionBegin; 2432266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2433266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_rhs,VEC_CLASSID,2); 2434266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_rhs,VEC_CLASSID,3); 24353425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2436163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 24373425bc38SStefano Zampini PetscFunctionReturn(0); 24383425bc38SStefano Zampini } 24391e6b0712SBarry Smith 24403425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 24413425bc38SStefano Zampini { 2442674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 24433425bc38SStefano Zampini PC_IS* pcis; 24443425bc38SStefano Zampini PC_BDDC* pcbddc; 24453425bc38SStefano Zampini PetscErrorCode ierr; 2446229984c5Sstefano_zampini Vec work; 24473425bc38SStefano Zampini 24483425bc38SStefano Zampini PetscFunctionBegin; 24493425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 24503425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 24513425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 24523425bc38SStefano Zampini 24533425bc38SStefano Zampini /* apply B_delta^T */ 2454af140850Sstefano_zampini ierr = VecSet(pcis->vec1_B,0.);CHKERRQ(ierr); 24553425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24563425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24573425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 2458229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2459229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->l2g_p,fetidp_flux_sol,mat_ctx->vP,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2460229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->l2g_p,fetidp_flux_sol,mat_ctx->vP,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2461229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->Bt_BB,mat_ctx->vP,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 2462229984c5Sstefano_zampini } 2463229984c5Sstefano_zampini 24643425bc38SStefano Zampini /* compute rhs for BDDC application */ 24653425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 24668eeda7d8SStefano Zampini if (pcbddc->switch_static) { 24673425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 2468229984c5Sstefano_zampini if (mat_ctx->l2g_p) { 2469229984c5Sstefano_zampini ierr = VecScale(mat_ctx->vP,-1.);CHKERRQ(ierr); 2470229984c5Sstefano_zampini ierr = MatMultAdd(mat_ctx->Bt_BI,mat_ctx->vP,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); 24713425bc38SStefano Zampini } 2472229984c5Sstefano_zampini } 2473229984c5Sstefano_zampini 24743425bc38SStefano Zampini /* apply BDDC */ 2475229984c5Sstefano_zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 2476dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2477229984c5Sstefano_zampini 2478229984c5Sstefano_zampini /* put values into global vector */ 2479af140850Sstefano_zampini if (pcbddc->ChangeOfBasisMatrix) work = pcbddc->work_change; 2480af140850Sstefano_zampini else work = standard_sol; 2481229984c5Sstefano_zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2482229984c5Sstefano_zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24838eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 24843425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 24853425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 248600f6b531SStefano Zampini ierr = VecAYPX(pcis->vec1_D,-1.0,mat_ctx->temp_solution_D);CHKERRQ(ierr); 248700f6b531SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); 2488c0decd05SBarry Smith /* Cannot propagate up error in KSPSolve() because there is no access to the PC */ 24893425bc38SStefano Zampini } 2490229984c5Sstefano_zampini 2491229984c5Sstefano_zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2492229984c5Sstefano_zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_D,work,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2493266e20e9SStefano Zampini /* add p0 solution to final solution */ 2494229984c5Sstefano_zampini ierr = PCBDDCBenignGetOrSetP0(mat_ctx->pc,work,PETSC_FALSE);CHKERRQ(ierr); 2495fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2496af140850Sstefano_zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,work,standard_sol);CHKERRQ(ierr); 2497fc17d649SStefano Zampini } 2498af140850Sstefano_zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 2499af140850Sstefano_zampini if (mat_ctx->g2g_p) { 2500229984c5Sstefano_zampini ierr = VecScatterBegin(mat_ctx->g2g_p,fetidp_flux_sol,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2501229984c5Sstefano_zampini ierr = VecScatterEnd(mat_ctx->g2g_p,fetidp_flux_sol,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2502229984c5Sstefano_zampini } 25033425bc38SStefano Zampini PetscFunctionReturn(0); 25043425bc38SStefano Zampini } 25051e6b0712SBarry Smith 25065a1e936bSStefano Zampini static PetscErrorCode PCView_BDDCIPC(PC pc, PetscViewer viewer) 25075a1e936bSStefano Zampini { 25085a1e936bSStefano Zampini PetscErrorCode ierr; 25095a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25105a1e936bSStefano Zampini PetscBool isascii; 25115a1e936bSStefano Zampini 25125a1e936bSStefano Zampini PetscFunctionBegin; 25135a1e936bSStefano Zampini ierr = PCShellGetContext(pc,(void **)&bddcipc_ctx);CHKERRQ(ierr); 25145a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 25155a1e936bSStefano Zampini if (isascii) { 25165a1e936bSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"BDDC interface preconditioner\n");CHKERRQ(ierr); 25175a1e936bSStefano Zampini } 25185a1e936bSStefano Zampini ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 25195a1e936bSStefano Zampini ierr = PCView(bddcipc_ctx->bddc,viewer);CHKERRQ(ierr); 25205a1e936bSStefano Zampini ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 25215a1e936bSStefano Zampini PetscFunctionReturn(0); 25225a1e936bSStefano Zampini } 25235a1e936bSStefano Zampini 25245a1e936bSStefano Zampini static PetscErrorCode PCSetUp_BDDCIPC(PC pc) 25255a1e936bSStefano Zampini { 25265a1e936bSStefano Zampini PetscErrorCode ierr; 25275a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25285a1e936bSStefano Zampini PetscBool isbddc; 25295a1e936bSStefano Zampini Vec vv; 25305a1e936bSStefano Zampini IS is; 25315a1e936bSStefano Zampini PC_IS *pcis; 25325a1e936bSStefano Zampini 25335a1e936bSStefano Zampini PetscFunctionBegin; 25345a1e936bSStefano Zampini ierr = PCShellGetContext(pc,(void **)&bddcipc_ctx);CHKERRQ(ierr); 25355a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)bddcipc_ctx->bddc,PCBDDC,&isbddc);CHKERRQ(ierr); 25365a1e936bSStefano Zampini if (!isbddc) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid type %s. Must be of type bddc",((PetscObject)bddcipc_ctx->bddc)->type_name); 25375a1e936bSStefano Zampini ierr = PCSetUp(bddcipc_ctx->bddc);CHKERRQ(ierr); 25385a1e936bSStefano Zampini 25395a1e936bSStefano Zampini /* create interface scatter */ 25405a1e936bSStefano Zampini pcis = (PC_IS*)(bddcipc_ctx->bddc->data); 25415a1e936bSStefano Zampini ierr = VecScatterDestroy(&bddcipc_ctx->g2l);CHKERRQ(ierr); 25425a1e936bSStefano Zampini ierr = MatCreateVecs(pc->pmat,&vv,NULL);CHKERRQ(ierr); 25435a1e936bSStefano Zampini ierr = ISRenumber(pcis->is_B_global,NULL,NULL,&is);CHKERRQ(ierr); 254435928de7SBarry Smith ierr = VecScatterCreateWithData(vv,is,pcis->vec1_B,NULL,&bddcipc_ctx->g2l);CHKERRQ(ierr); 25455a1e936bSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 25465a1e936bSStefano Zampini ierr = VecDestroy(&vv);CHKERRQ(ierr); 25475a1e936bSStefano Zampini PetscFunctionReturn(0); 25485a1e936bSStefano Zampini } 25495a1e936bSStefano Zampini 25505a1e936bSStefano Zampini static PetscErrorCode PCApply_BDDCIPC(PC pc, Vec r, Vec x) 25515a1e936bSStefano Zampini { 25525a1e936bSStefano Zampini PetscErrorCode ierr; 25535a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25545a1e936bSStefano Zampini PC_IS *pcis; 25555a1e936bSStefano Zampini VecScatter tmps; 25565a1e936bSStefano Zampini 25575a1e936bSStefano Zampini PetscFunctionBegin; 25585a1e936bSStefano Zampini ierr = PCShellGetContext(pc,(void **)&bddcipc_ctx);CHKERRQ(ierr); 25595a1e936bSStefano Zampini pcis = (PC_IS*)(bddcipc_ctx->bddc->data); 25605a1e936bSStefano Zampini tmps = pcis->global_to_B; 25615a1e936bSStefano Zampini pcis->global_to_B = bddcipc_ctx->g2l; 25625a1e936bSStefano Zampini ierr = PCBDDCScalingRestriction(bddcipc_ctx->bddc,r,pcis->vec1_B);CHKERRQ(ierr); 25635a1e936bSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(bddcipc_ctx->bddc,PETSC_FALSE);CHKERRQ(ierr); 25645a1e936bSStefano Zampini ierr = PCBDDCScalingExtension(bddcipc_ctx->bddc,pcis->vec1_B,x);CHKERRQ(ierr); 25655a1e936bSStefano Zampini pcis->global_to_B = tmps; 25665a1e936bSStefano Zampini PetscFunctionReturn(0); 25675a1e936bSStefano Zampini } 25685a1e936bSStefano Zampini 25695a1e936bSStefano Zampini static PetscErrorCode PCApplyTranspose_BDDCIPC(PC pc, Vec r, Vec x) 25705a1e936bSStefano Zampini { 25715a1e936bSStefano Zampini PetscErrorCode ierr; 25725a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25735a1e936bSStefano Zampini PC_IS *pcis; 25745a1e936bSStefano Zampini VecScatter tmps; 25755a1e936bSStefano Zampini 25765a1e936bSStefano Zampini PetscFunctionBegin; 25775a1e936bSStefano Zampini ierr = PCShellGetContext(pc,(void **)&bddcipc_ctx);CHKERRQ(ierr); 25785a1e936bSStefano Zampini pcis = (PC_IS*)(bddcipc_ctx->bddc->data); 25795a1e936bSStefano Zampini tmps = pcis->global_to_B; 25805a1e936bSStefano Zampini pcis->global_to_B = bddcipc_ctx->g2l; 25815a1e936bSStefano Zampini ierr = PCBDDCScalingRestriction(bddcipc_ctx->bddc,r,pcis->vec1_B);CHKERRQ(ierr); 25825a1e936bSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(bddcipc_ctx->bddc,PETSC_TRUE);CHKERRQ(ierr); 25835a1e936bSStefano Zampini ierr = PCBDDCScalingExtension(bddcipc_ctx->bddc,pcis->vec1_B,x);CHKERRQ(ierr); 25845a1e936bSStefano Zampini pcis->global_to_B = tmps; 25855a1e936bSStefano Zampini PetscFunctionReturn(0); 25865a1e936bSStefano Zampini } 25875a1e936bSStefano Zampini 25885a1e936bSStefano Zampini static PetscErrorCode PCDestroy_BDDCIPC(PC pc) 25895a1e936bSStefano Zampini { 25905a1e936bSStefano Zampini PetscErrorCode ierr; 25915a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 25925a1e936bSStefano Zampini 25935a1e936bSStefano Zampini PetscFunctionBegin; 25945a1e936bSStefano Zampini ierr = PCShellGetContext(pc,(void **)&bddcipc_ctx);CHKERRQ(ierr); 25955a1e936bSStefano Zampini ierr = PCDestroy(&bddcipc_ctx->bddc);CHKERRQ(ierr); 25965a1e936bSStefano Zampini ierr = VecScatterDestroy(&bddcipc_ctx->g2l);CHKERRQ(ierr); 25975a1e936bSStefano Zampini ierr = PetscFree(bddcipc_ctx);CHKERRQ(ierr); 25985a1e936bSStefano Zampini PetscFunctionReturn(0); 25995a1e936bSStefano Zampini } 26005a1e936bSStefano Zampini 26013425bc38SStefano Zampini /*@ 26020f202f7eSStefano Zampini PCBDDCMatFETIDPGetSolution - Compute the physical solution using the solution of the FETI-DP linear system 26033425bc38SStefano Zampini 26043425bc38SStefano Zampini Collective 26053425bc38SStefano Zampini 26063425bc38SStefano Zampini Input Parameters: 26070f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix obtained by a call to PCBDDCCreateFETIDPOperators 26080f202f7eSStefano Zampini - fetidp_flux_sol - the solution of the FETI-DP linear system 26093425bc38SStefano Zampini 26103425bc38SStefano Zampini Output Parameters: 26110f202f7eSStefano Zampini . standard_sol - the solution defined on the physical domain 26123425bc38SStefano Zampini 26133425bc38SStefano Zampini Level: developer 26143425bc38SStefano Zampini 26153425bc38SStefano Zampini Notes: 26163425bc38SStefano Zampini 26170f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetRHS 26183425bc38SStefano Zampini @*/ 26193425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 26203425bc38SStefano Zampini { 2621674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 26223425bc38SStefano Zampini PetscErrorCode ierr; 26233425bc38SStefano Zampini 26243425bc38SStefano Zampini PetscFunctionBegin; 2625266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2626266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_sol,VEC_CLASSID,2); 2627266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_sol,VEC_CLASSID,3); 26283425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2629163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 26303425bc38SStefano Zampini PetscFunctionReturn(0); 26313425bc38SStefano Zampini } 26321e6b0712SBarry Smith 2633547c9a8eSstefano_zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, PetscBool fully_redundant, const char* prefix, Mat *fetidp_mat, PC *fetidp_pc) 26343425bc38SStefano Zampini { 2635674ae819SStefano Zampini 2636674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 26373425bc38SStefano Zampini Mat newmat; 2638674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 26393425bc38SStefano Zampini PC newpc; 2640ce94432eSBarry Smith MPI_Comm comm; 26413425bc38SStefano Zampini PetscErrorCode ierr; 26423425bc38SStefano Zampini 26433425bc38SStefano Zampini PetscFunctionBegin; 2644ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 264515579a77SStefano Zampini /* FETI-DP matrix */ 26463425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 26471720468bSStefano Zampini fetidpmat_ctx->fully_redundant = fully_redundant; 26483425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 2649a5bb87b3Sstefano_zampini ierr = MatCreateShell(comm,fetidpmat_ctx->n,fetidpmat_ctx->n,fetidpmat_ctx->N,fetidpmat_ctx->N,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 265015579a77SStefano Zampini ierr = PetscObjectSetName((PetscObject)newmat,!fetidpmat_ctx->l2g_lambda_only ? "F" : "G");CHKERRQ(ierr); 26513425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 2652edf7251bSStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT_TRANSPOSE,(void (*)(void))FETIDPMatMultTranspose);CHKERRQ(ierr); 26533425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 265415579a77SStefano Zampini /* propagate MatOptions */ 265515579a77SStefano Zampini { 265615579a77SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)fetidpmat_ctx->pc->data; 265715579a77SStefano Zampini PetscBool issym; 265815579a77SStefano Zampini 265915579a77SStefano Zampini ierr = MatGetOption(pc->mat,MAT_SYMMETRIC,&issym);CHKERRQ(ierr); 266015579a77SStefano Zampini if (issym || pcbddc->symmetric_primal) { 266115579a77SStefano Zampini ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 266215579a77SStefano Zampini } 266315579a77SStefano Zampini } 2664547c9a8eSstefano_zampini ierr = MatSetOptionsPrefix(newmat,prefix);CHKERRQ(ierr); 2665547c9a8eSstefano_zampini ierr = MatAppendOptionsPrefix(newmat,"fetidp_");CHKERRQ(ierr); 26663425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 266715579a77SStefano Zampini /* FETI-DP preconditioner */ 26683425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 26693425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 26703425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 2671e1214c54Sstefano_zampini ierr = PCSetOperators(newpc,newmat,newmat);CHKERRQ(ierr); 2672e1214c54Sstefano_zampini ierr = PCSetOptionsPrefix(newpc,prefix);CHKERRQ(ierr); 2673e1214c54Sstefano_zampini ierr = PCAppendOptionsPrefix(newpc,"fetidp_");CHKERRQ(ierr); 2674399ffe99SStefano Zampini ierr = PCSetErrorIfFailure(newpc,pc->erroriffailure);CHKERRQ(ierr); 267515579a77SStefano Zampini if (!fetidpmat_ctx->l2g_lambda_only) { /* standard FETI-DP */ 26763425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 267715579a77SStefano Zampini ierr = PCShellSetName(newpc,"FETI-DP multipliers");CHKERRQ(ierr); 26783425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 26793425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 2680edf7251bSStefano Zampini ierr = PCShellSetApplyTranspose(newpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 2681c45b8d2dSstefano_zampini ierr = PCShellSetView(newpc,FETIDPPCView);CHKERRQ(ierr); 26823425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 26835a1e936bSStefano Zampini } else { /* saddle-point FETI-DP */ 26845a1e936bSStefano Zampini Mat M; 26855a1e936bSStefano Zampini PetscInt psize; 26865a1e936bSStefano Zampini PetscBool fake = PETSC_FALSE, isfieldsplit; 2687e1214c54Sstefano_zampini 268815579a77SStefano Zampini ierr = ISViewFromOptions(fetidpmat_ctx->lagrange,NULL,"-lag_view");CHKERRQ(ierr); 268915579a77SStefano Zampini ierr = ISViewFromOptions(fetidpmat_ctx->pressure,NULL,"-press_view");CHKERRQ(ierr); 2690e1214c54Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_PPmat",(PetscObject*)&M);CHKERRQ(ierr); 2691e1214c54Sstefano_zampini ierr = PCSetType(newpc,PCFIELDSPLIT);CHKERRQ(ierr); 2692e1214c54Sstefano_zampini ierr = PCFieldSplitSetIS(newpc,"lag",fetidpmat_ctx->lagrange);CHKERRQ(ierr); 2693e1214c54Sstefano_zampini ierr = PCFieldSplitSetIS(newpc,"p",fetidpmat_ctx->pressure);CHKERRQ(ierr); 2694e1214c54Sstefano_zampini ierr = PCFieldSplitSetType(newpc,PC_COMPOSITE_SCHUR);CHKERRQ(ierr); 269540c75d76SStefano Zampini ierr = PCFieldSplitSetSchurFactType(newpc,PC_FIELDSPLIT_SCHUR_FACT_DIAG);CHKERRQ(ierr); 26965a1e936bSStefano Zampini ierr = ISGetSize(fetidpmat_ctx->pressure,&psize);CHKERRQ(ierr); 26975a1e936bSStefano Zampini if (psize != M->rmap->N) { 26985a1e936bSStefano Zampini Mat M2; 26995a1e936bSStefano Zampini PetscInt lpsize; 27005a1e936bSStefano Zampini 27015a1e936bSStefano Zampini fake = PETSC_TRUE; 27025a1e936bSStefano Zampini ierr = ISGetLocalSize(fetidpmat_ctx->pressure,&lpsize);CHKERRQ(ierr); 27035a1e936bSStefano Zampini ierr = MatCreate(comm,&M2);CHKERRQ(ierr); 27045a1e936bSStefano Zampini ierr = MatSetType(M2,MATAIJ);CHKERRQ(ierr); 27055a1e936bSStefano Zampini ierr = MatSetSizes(M2,lpsize,lpsize,psize,psize);CHKERRQ(ierr); 27065a1e936bSStefano Zampini ierr = MatSetUp(M2);CHKERRQ(ierr); 27075a1e936bSStefano Zampini ierr = MatAssemblyBegin(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27085a1e936bSStefano Zampini ierr = MatAssemblyEnd(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27095a1e936bSStefano Zampini ierr = PCFieldSplitSetSchurPre(newpc,PC_FIELDSPLIT_SCHUR_PRE_USER,M2);CHKERRQ(ierr); 27105a1e936bSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 27115a1e936bSStefano Zampini } else { 2712e1214c54Sstefano_zampini ierr = PCFieldSplitSetSchurPre(newpc,PC_FIELDSPLIT_SCHUR_PRE_USER,M);CHKERRQ(ierr); 27135a1e936bSStefano Zampini } 2714c096484dSStefano Zampini ierr = PCFieldSplitSetSchurScale(newpc,1.0);CHKERRQ(ierr); 271515579a77SStefano Zampini 271615579a77SStefano Zampini /* we need to setfromoptions and setup here to access the blocks */ 2717e1214c54Sstefano_zampini ierr = PCSetFromOptions(newpc);CHKERRQ(ierr); 2718e1214c54Sstefano_zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 2719e1214c54Sstefano_zampini 27205a1e936bSStefano Zampini /* user may have changed the type (e.g. -fetidp_pc_type none) */ 27215a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)newpc,PCFIELDSPLIT,&isfieldsplit);CHKERRQ(ierr); 27225a1e936bSStefano Zampini if (isfieldsplit) { 27235a1e936bSStefano Zampini KSP *ksps; 27245a1e936bSStefano Zampini PC ppc,lagpc; 27255a1e936bSStefano Zampini PetscInt nn; 2726064a4176SStefano Zampini PetscBool ismatis,matisok = PETSC_FALSE,check = PETSC_FALSE; 27275a1e936bSStefano Zampini 2728e1214c54Sstefano_zampini /* set the solver for the (0,0) block */ 27295a1e936bSStefano Zampini ierr = PCFieldSplitSchurGetSubKSP(newpc,&nn,&ksps);CHKERRQ(ierr); 27305a1e936bSStefano Zampini if (!nn) { /* not of type PC_COMPOSITE_SCHUR */ 273140c75d76SStefano Zampini ierr = PCFieldSplitGetSubKSP(newpc,&nn,&ksps);CHKERRQ(ierr); 27325a1e936bSStefano Zampini if (!fake) { /* pass pmat to the pressure solver */ 27335a1e936bSStefano Zampini Mat F; 27345a1e936bSStefano Zampini 27355a1e936bSStefano Zampini ierr = KSPGetOperators(ksps[1],&F,NULL);CHKERRQ(ierr); 27365a1e936bSStefano Zampini ierr = KSPSetOperators(ksps[1],F,M);CHKERRQ(ierr); 27375a1e936bSStefano Zampini } 27385a1e936bSStefano Zampini } else { 27395a1e936bSStefano Zampini PetscBool issym; 27405a1e936bSStefano Zampini Mat S; 27415a1e936bSStefano Zampini 27425a1e936bSStefano Zampini ierr = PCFieldSplitSchurGetS(newpc,&S);CHKERRQ(ierr); 27435a1e936bSStefano Zampini 27445a1e936bSStefano Zampini ierr = MatGetOption(newmat,MAT_SYMMETRIC,&issym);CHKERRQ(ierr); 27455a1e936bSStefano Zampini if (issym) { 27465a1e936bSStefano Zampini ierr = MatSetOption(S,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 27475a1e936bSStefano Zampini } 27485a1e936bSStefano Zampini } 27495a1e936bSStefano Zampini ierr = KSPGetPC(ksps[0],&lagpc);CHKERRQ(ierr); 2750e1214c54Sstefano_zampini ierr = PCSetType(lagpc,PCSHELL);CHKERRQ(ierr); 27515a1e936bSStefano Zampini ierr = PCShellSetName(lagpc,"FETI-DP multipliers");CHKERRQ(ierr); 2752e1214c54Sstefano_zampini ierr = PCShellSetContext(lagpc,fetidppc_ctx);CHKERRQ(ierr); 2753e1214c54Sstefano_zampini ierr = PCShellSetApply(lagpc,FETIDPPCApply);CHKERRQ(ierr); 2754e1214c54Sstefano_zampini ierr = PCShellSetApplyTranspose(lagpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 2755e1214c54Sstefano_zampini ierr = PCShellSetView(lagpc,FETIDPPCView);CHKERRQ(ierr); 2756e1214c54Sstefano_zampini ierr = PCShellSetDestroy(lagpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 27575a1e936bSStefano Zampini 27585a1e936bSStefano Zampini /* Olof's idea: interface Schur complement preconditioner for the mass matrix */ 27595a1e936bSStefano Zampini ierr = KSPGetPC(ksps[1],&ppc);CHKERRQ(ierr); 27605a1e936bSStefano Zampini if (fake) { 27615a1e936bSStefano Zampini BDDCIPC_ctx bddcipc_ctx; 2762ff11fd76SStefano Zampini PetscContainer c; 27635a1e936bSStefano Zampini 27645a1e936bSStefano Zampini matisok = PETSC_TRUE; 27655a1e936bSStefano Zampini 27665a1e936bSStefano Zampini /* create inner BDDC solver */ 27675a1e936bSStefano Zampini ierr = PetscNew(&bddcipc_ctx);CHKERRQ(ierr); 27685a1e936bSStefano Zampini ierr = PCCreate(comm,&bddcipc_ctx->bddc);CHKERRQ(ierr); 27695a1e936bSStefano Zampini ierr = PCSetType(bddcipc_ctx->bddc,PCBDDC);CHKERRQ(ierr); 27705a1e936bSStefano Zampini ierr = PCSetOperators(bddcipc_ctx->bddc,M,M);CHKERRQ(ierr); 2771ff11fd76SStefano Zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_pCSR",(PetscObject*)&c);CHKERRQ(ierr); 2772ff11fd76SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)M,MATIS,&ismatis);CHKERRQ(ierr); 2773ff11fd76SStefano Zampini if (c && ismatis) { 2774ff11fd76SStefano Zampini Mat lM; 2775ff11fd76SStefano Zampini PetscInt *csr,n; 2776ff11fd76SStefano Zampini 2777ff11fd76SStefano Zampini ierr = MatISGetLocalMat(M,&lM);CHKERRQ(ierr); 2778ff11fd76SStefano Zampini ierr = MatGetSize(lM,&n,NULL);CHKERRQ(ierr); 2779ff11fd76SStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&csr);CHKERRQ(ierr); 2780ff11fd76SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(bddcipc_ctx->bddc,n,csr,csr + (n + 1),PETSC_COPY_VALUES);CHKERRQ(ierr); 2781ff11fd76SStefano Zampini ierr = MatISRestoreLocalMat(M,&lM);CHKERRQ(ierr); 2782ff11fd76SStefano Zampini } 27835a1e936bSStefano Zampini ierr = PCSetOptionsPrefix(bddcipc_ctx->bddc,((PetscObject)ksps[1])->prefix);CHKERRQ(ierr); 27845a1e936bSStefano Zampini ierr = PCSetErrorIfFailure(bddcipc_ctx->bddc,pc->erroriffailure);CHKERRQ(ierr); 27855a1e936bSStefano Zampini ierr = PCSetFromOptions(bddcipc_ctx->bddc);CHKERRQ(ierr); 27865a1e936bSStefano Zampini 27875a1e936bSStefano Zampini /* wrap the interface application */ 27885a1e936bSStefano Zampini ierr = PCSetType(ppc,PCSHELL);CHKERRQ(ierr); 27895a1e936bSStefano Zampini ierr = PCShellSetName(ppc,"FETI-DP pressure");CHKERRQ(ierr); 27905a1e936bSStefano Zampini ierr = PCShellSetContext(ppc,bddcipc_ctx);CHKERRQ(ierr); 27915a1e936bSStefano Zampini ierr = PCShellSetSetUp(ppc,PCSetUp_BDDCIPC);CHKERRQ(ierr); 27925a1e936bSStefano Zampini ierr = PCShellSetApply(ppc,PCApply_BDDCIPC);CHKERRQ(ierr); 27935a1e936bSStefano Zampini ierr = PCShellSetApplyTranspose(ppc,PCApplyTranspose_BDDCIPC);CHKERRQ(ierr); 27945a1e936bSStefano Zampini ierr = PCShellSetView(ppc,PCView_BDDCIPC);CHKERRQ(ierr); 27955a1e936bSStefano Zampini ierr = PCShellSetDestroy(ppc,PCDestroy_BDDCIPC);CHKERRQ(ierr); 27965a1e936bSStefano Zampini } 27975a1e936bSStefano Zampini 27985a1e936bSStefano Zampini /* determine if we need to assemble M to construct a preconditioner */ 27995a1e936bSStefano Zampini if (!matisok) { 28005a1e936bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)M,MATIS,&ismatis);CHKERRQ(ierr); 28015a1e936bSStefano Zampini ierr = PetscObjectTypeCompareAny((PetscObject)ppc,&matisok,PCBDDC,PCJACOBI,PCNONE,PCMG,"");CHKERRQ(ierr); 28025a1e936bSStefano Zampini if (ismatis && !matisok) { 28035a1e936bSStefano Zampini ierr = MatConvert(M,MATAIJ,MAT_INPLACE_MATRIX,&M);CHKERRQ(ierr); 28045a1e936bSStefano Zampini } 28055a1e936bSStefano Zampini } 2806064a4176SStefano Zampini 2807064a4176SStefano Zampini /* run the subproblems to check convergence */ 2808064a4176SStefano Zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)newmat)->prefix,"-check_saddlepoint",&check,NULL);CHKERRQ(ierr); 2809064a4176SStefano Zampini if (check) { 2810064a4176SStefano Zampini PetscInt i; 2811064a4176SStefano Zampini 2812064a4176SStefano Zampini for (i=0;i<nn;i++) { 2813064a4176SStefano Zampini KSP kspC; 2814064a4176SStefano Zampini PC pc; 2815064a4176SStefano Zampini Mat F,pF; 2816064a4176SStefano Zampini Vec x,y; 2817064a4176SStefano Zampini PetscBool isschur,prec = PETSC_TRUE; 2818064a4176SStefano Zampini 2819064a4176SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)ksps[i]),&kspC);CHKERRQ(ierr); 2820064a4176SStefano Zampini ierr = KSPSetOptionsPrefix(kspC,((PetscObject)ksps[i])->prefix);CHKERRQ(ierr); 2821064a4176SStefano Zampini ierr = KSPAppendOptionsPrefix(kspC,"check_");CHKERRQ(ierr); 2822064a4176SStefano Zampini ierr = KSPGetOperators(ksps[i],&F,&pF);CHKERRQ(ierr); 2823064a4176SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)F,MATSCHURCOMPLEMENT,&isschur);CHKERRQ(ierr); 2824064a4176SStefano Zampini if (isschur) { 2825064a4176SStefano Zampini KSP kspS,kspS2; 2826064a4176SStefano Zampini Mat A00,pA00,A10,A01,A11; 2827064a4176SStefano Zampini char prefix[256]; 2828064a4176SStefano Zampini 2829064a4176SStefano Zampini ierr = MatSchurComplementGetKSP(F,&kspS);CHKERRQ(ierr); 2830064a4176SStefano Zampini ierr = MatSchurComplementGetSubMatrices(F,&A00,&pA00,&A01,&A10,&A11);CHKERRQ(ierr); 2831064a4176SStefano Zampini ierr = MatCreateSchurComplement(A00,pA00,A01,A10,A11,&F);CHKERRQ(ierr); 2832064a4176SStefano Zampini ierr = MatSchurComplementGetKSP(F,&kspS2);CHKERRQ(ierr); 2833064a4176SStefano Zampini ierr = PetscSNPrintf(prefix,sizeof(prefix),"%sschur_",((PetscObject)kspC)->prefix);CHKERRQ(ierr); 2834064a4176SStefano Zampini ierr = KSPSetOptionsPrefix(kspS2,prefix);CHKERRQ(ierr); 2835064a4176SStefano Zampini ierr = KSPGetPC(kspS2,&pc);CHKERRQ(ierr); 2836064a4176SStefano Zampini ierr = PCSetType(pc,PCKSP);CHKERRQ(ierr); 2837064a4176SStefano Zampini ierr = PCKSPSetKSP(pc,kspS);CHKERRQ(ierr); 2838064a4176SStefano Zampini ierr = KSPSetFromOptions(kspS2);CHKERRQ(ierr); 2839064a4176SStefano Zampini ierr = KSPGetPC(kspS2,&pc);CHKERRQ(ierr); 2840064a4176SStefano Zampini ierr = PCSetUseAmat(pc,PETSC_TRUE);CHKERRQ(ierr); 2841064a4176SStefano Zampini } else { 2842064a4176SStefano Zampini ierr = PetscObjectReference((PetscObject)F);CHKERRQ(ierr); 2843064a4176SStefano Zampini } 2844064a4176SStefano Zampini ierr = KSPSetFromOptions(kspC);CHKERRQ(ierr); 2845064a4176SStefano Zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)kspC)->prefix,"-preconditioned",&prec,NULL);CHKERRQ(ierr); 2846064a4176SStefano Zampini if (prec) { 2847064a4176SStefano Zampini ierr = KSPGetPC(ksps[i],&pc);CHKERRQ(ierr); 2848064a4176SStefano Zampini ierr = KSPSetPC(kspC,pc);CHKERRQ(ierr); 2849064a4176SStefano Zampini } 2850064a4176SStefano Zampini ierr = KSPSetOperators(kspC,F,pF);CHKERRQ(ierr); 2851064a4176SStefano Zampini ierr = MatCreateVecs(F,&x,&y);CHKERRQ(ierr); 2852064a4176SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 2853064a4176SStefano Zampini ierr = MatMult(F,x,y);CHKERRQ(ierr); 2854064a4176SStefano Zampini ierr = KSPSolve(kspC,y,x);CHKERRQ(ierr); 2855c0decd05SBarry Smith ierr = KSPCheckSolve(kspC,pc,x);CHKERRQ(ierr); 2856064a4176SStefano Zampini ierr = KSPDestroy(&kspC);CHKERRQ(ierr); 2857064a4176SStefano Zampini ierr = MatDestroy(&F);CHKERRQ(ierr); 2858064a4176SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2859064a4176SStefano Zampini ierr = VecDestroy(&y);CHKERRQ(ierr); 2860064a4176SStefano Zampini } 2861064a4176SStefano Zampini } 2862e1214c54Sstefano_zampini ierr = PetscFree(ksps);CHKERRQ(ierr); 2863e1214c54Sstefano_zampini } 28645a1e936bSStefano Zampini } 28653425bc38SStefano Zampini /* return pointers for objects created */ 28663425bc38SStefano Zampini *fetidp_mat = newmat; 28673425bc38SStefano Zampini *fetidp_pc = newpc; 28683425bc38SStefano Zampini PetscFunctionReturn(0); 28693425bc38SStefano Zampini } 28701e6b0712SBarry Smith 287194ef8ddeSSatish Balay /*@C 28720f202f7eSStefano Zampini PCBDDCCreateFETIDPOperators - Create FETI-DP operators 28733425bc38SStefano Zampini 28743425bc38SStefano Zampini Collective 28753425bc38SStefano Zampini 28763425bc38SStefano Zampini Input Parameters: 28771720468bSStefano Zampini + pc - the BDDC preconditioning context (setup should have been called before) 2878547c9a8eSstefano_zampini . fully_redundant - true for a fully redundant set of Lagrange multipliers 2879547c9a8eSstefano_zampini - prefix - optional options database prefix for the objects to be created (can be NULL) 288028509bceSStefano Zampini 288128509bceSStefano Zampini Output Parameters: 28820f202f7eSStefano Zampini + fetidp_mat - shell FETI-DP matrix object 28830f202f7eSStefano Zampini - fetidp_pc - shell Dirichlet preconditioner for FETI-DP matrix 288428509bceSStefano Zampini 28853425bc38SStefano Zampini Level: developer 28863425bc38SStefano Zampini 28873425bc38SStefano Zampini Notes: 28880f202f7eSStefano Zampini Currently the only operations provided for FETI-DP matrix are MatMult and MatMultTranspose 28893425bc38SStefano Zampini 28900f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCMatFETIDPGetRHS, PCBDDCMatFETIDPGetSolution 28913425bc38SStefano Zampini @*/ 2892547c9a8eSstefano_zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, PetscBool fully_redundant, const char *prefix, Mat *fetidp_mat, PC *fetidp_pc) 28933425bc38SStefano Zampini { 28943425bc38SStefano Zampini PetscErrorCode ierr; 28953425bc38SStefano Zampini 28963425bc38SStefano Zampini PetscFunctionBegin; 28973425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 28983425bc38SStefano Zampini if (pc->setupcalled) { 2899547c9a8eSstefano_zampini ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,PetscBool,const char*,Mat*,PC*),(pc,fully_redundant,prefix,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 29006080607fSStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"You must call PCSetup_BDDC() first"); 29013425bc38SStefano Zampini PetscFunctionReturn(0); 29023425bc38SStefano Zampini } 29030c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2904da1bb401SStefano Zampini /*MC 2905da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 29060c7d97c5SJed Brown 290728509bceSStefano Zampini An implementation of the BDDC preconditioner based on 290828509bceSStefano Zampini 290928509bceSStefano Zampini .vb 291028509bceSStefano Zampini [1] C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 291128509bceSStefano Zampini [2] A. Klawonn and O. B. Widlund. "Dual-Primal FETI Methods for Linear Elasticity", http://cs.nyu.edu/csweb/Research/TechReports/TR2004-855/TR2004-855.pdf 291228509bceSStefano Zampini [3] J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", http://arxiv.org/abs/0712.3977 29130f202f7eSStefano 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 291428509bceSStefano Zampini .ve 291528509bceSStefano Zampini 291628509bceSStefano Zampini The matrix to be preconditioned (Pmat) must be of type MATIS. 291728509bceSStefano Zampini 29180f202f7eSStefano Zampini Currently works with MATIS matrices with local matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers. 291928509bceSStefano Zampini 292028509bceSStefano Zampini It also works with unsymmetric and indefinite problems. 292128509bceSStefano Zampini 2922b6fdb6dfSStefano 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. 2923b6fdb6dfSStefano Zampini 2924c7017625SStefano 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). 292528509bceSStefano Zampini 29260f202f7eSStefano 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() 292730368db7SStefano Zampini Additional information on dofs can be provided by using PCBDDCSetDofsSplitting(), PCBDDCSetDirichletBoundaries(), PCBDDCSetNeumannBoundaries(), and PCBDDCSetPrimalVerticesIS() and their local counterparts. 292828509bceSStefano Zampini 29290f202f7eSStefano Zampini Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace(). Non-singular modes are retained via SVD. 293028509bceSStefano Zampini 29310f202f7eSStefano 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. 29320f202f7eSStefano Zampini User defined change of basis can be passed to PCBDDC by using PCBDDCSetChangeOfBasisMat() 293328509bceSStefano Zampini 29340f202f7eSStefano Zampini The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using a MatPartitioning object. 293528509bceSStefano Zampini 2936df4d28bfSStefano 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. 293728509bceSStefano Zampini 29380f202f7eSStefano 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. 29390f202f7eSStefano Zampini Deluxe scaling is not supported yet for FETI-DP. 29400f202f7eSStefano Zampini 29410f202f7eSStefano Zampini Options Database Keys (some of them, run with -h for a complete list): 29420f202f7eSStefano Zampini 29430f202f7eSStefano Zampini . -pc_bddc_use_vertices <true> - use or not vertices in primal space 29440f202f7eSStefano Zampini . -pc_bddc_use_edges <true> - use or not edges in primal space 29450f202f7eSStefano Zampini . -pc_bddc_use_faces <false> - use or not faces in primal space 29460f202f7eSStefano Zampini . -pc_bddc_symmetric <true> - symmetric computation of primal basis functions. Specify false for unsymmetric problems 29470f202f7eSStefano Zampini . -pc_bddc_use_change_of_basis <false> - use change of basis approach (on edges only) 29480f202f7eSStefano Zampini . -pc_bddc_use_change_on_faces <false> - use change of basis approach on faces if change of basis has been requested 29490f202f7eSStefano Zampini . -pc_bddc_switch_static <false> - switches from M_2 (default) to M_3 operator (see reference article [1]) 295028509bceSStefano Zampini . -pc_bddc_levels <0> - maximum number of levels for multilevel 29510f202f7eSStefano 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) 29525459c157SBarry 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) 29530f202f7eSStefano Zampini . -pc_bddc_use_deluxe_scaling <false> - use deluxe scaling 29540f202f7eSStefano Zampini . -pc_bddc_schur_layers <-1> - select the economic version of deluxe scaling by specifying the number of layers (-1 corresponds to the original deluxe scaling) 2955bd2a564bSStefano 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) 295628509bceSStefano Zampini - -pc_bddc_check_level <0> - set verbosity level of debugging output 295728509bceSStefano Zampini 295828509bceSStefano Zampini Options for Dirichlet, Neumann or coarse solver can be set with 295928509bceSStefano Zampini .vb 296028509bceSStefano Zampini -pc_bddc_dirichlet_ 296128509bceSStefano Zampini -pc_bddc_neumann_ 296228509bceSStefano Zampini -pc_bddc_coarse_ 296328509bceSStefano Zampini .ve 29640f202f7eSStefano Zampini e.g -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg. PCBDDC uses by default KPSPREONLY and PCLU. 296528509bceSStefano Zampini 29660f202f7eSStefano Zampini When using a multilevel approach, solvers' options at the N-th level (N > 1) can be specified as 296728509bceSStefano Zampini .vb 2968312be037SStefano Zampini -pc_bddc_dirichlet_lN_ 2969312be037SStefano Zampini -pc_bddc_neumann_lN_ 2970312be037SStefano Zampini -pc_bddc_coarse_lN_ 297128509bceSStefano Zampini .ve 29720f202f7eSStefano Zampini Note that level number ranges from the finest (0) to the coarsest (N). 29730f202f7eSStefano 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. 29740f202f7eSStefano Zampini .vb 29750f202f7eSStefano Zampini -pc_bddc_coarse_pc_bddc_adaptive_threshold 5 -pc_bddc_coarse_l1_pc_bddc_redistribute 3 29760f202f7eSStefano Zampini .ve 29770f202f7eSStefano 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 2978da1bb401SStefano Zampini 2979da1bb401SStefano Zampini Level: intermediate 2980da1bb401SStefano Zampini 2981e94cfbe0SPatrick Sanan Developer Notes: 2982da1bb401SStefano Zampini 2983da1bb401SStefano Zampini Contributed by Stefano Zampini 2984da1bb401SStefano Zampini 2985da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 2986da1bb401SStefano Zampini M*/ 2987b2573a8aSBarry Smith 29888cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 2989da1bb401SStefano Zampini { 2990da1bb401SStefano Zampini PetscErrorCode ierr; 2991da1bb401SStefano Zampini PC_BDDC *pcbddc; 2992da1bb401SStefano Zampini 2993da1bb401SStefano Zampini PetscFunctionBegin; 2994b00a9115SJed Brown ierr = PetscNewLog(pc,&pcbddc);CHKERRQ(ierr); 2995da1bb401SStefano Zampini pc->data = (void*)pcbddc; 2996da1bb401SStefano Zampini 2997da1bb401SStefano Zampini /* create PCIS data structure */ 2998da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 2999da1bb401SStefano Zampini 30009326c5c6Sstefano_zampini /* create local graph structure */ 30019326c5c6Sstefano_zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 30029326c5c6Sstefano_zampini 30039326c5c6Sstefano_zampini /* BDDC nonzero defaults */ 300408a5cf49SStefano Zampini pcbddc->use_local_adj = PETSC_TRUE; 300547d04d0dSStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 300647d04d0dSStefano Zampini pcbddc->use_edges = PETSC_TRUE; 30073301b35fSStefano Zampini pcbddc->symmetric_primal = PETSC_TRUE; 300814f95afaSStefano Zampini pcbddc->vertex_size = 1; 3009c703fcc7SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 301068457ee5SStefano Zampini pcbddc->coarse_size = -1; 301185c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 301247d04d0dSStefano Zampini pcbddc->coarsening_ratio = 8; 301357de7509SStefano Zampini pcbddc->coarse_eqs_per_proc = 1; 301427b6a85dSStefano Zampini pcbddc->benign_compute_correction = PETSC_TRUE; 30151e0482f5SStefano Zampini pcbddc->nedfield = -1; 30161e0482f5SStefano Zampini pcbddc->nedglobal = PETSC_TRUE; 3017be12c134Sstefano_zampini pcbddc->graphmaxcount = PETSC_MAX_INT; 3018b96c3477SStefano Zampini pcbddc->sub_schurs_layers = -1; 3019bd2a564bSStefano Zampini pcbddc->adaptive_threshold[0] = 0.0; 3020bd2a564bSStefano Zampini pcbddc->adaptive_threshold[1] = 0.0; 3021b7eb3628SStefano Zampini 3022da1bb401SStefano Zampini /* function pointers */ 3023da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 302493bd9ae7SStefano Zampini pc->ops->applytranspose = PCApplyTranspose_BDDC; 3025da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 3026da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 3027da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 30286b78500eSPatrick Sanan pc->ops->view = PCView_BDDC; 3029da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 3030da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 3031da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 3032534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 3033534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 30349326c5c6Sstefano_zampini pc->ops->reset = PCReset_BDDC; 3035da1bb401SStefano Zampini 3036da1bb401SStefano Zampini /* composing function */ 3037a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",PCBDDCSetDiscreteGradient_BDDC);CHKERRQ(ierr); 3038a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",PCBDDCSetDivergenceMat_BDDC);CHKERRQ(ierr); 3039906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",PCBDDCSetChangeOfBasisMat_BDDC);CHKERRQ(ierr); 3040674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 304130368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",PCBDDCSetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 30423100ebe3SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetPrimalVerticesLocalIS_C",PCBDDCGetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 30433100ebe3SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetPrimalVerticesIS_C",PCBDDCGetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 3044bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 30452b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr); 3046b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr); 30472b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr); 3048bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 304982ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 3050bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 305182ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 3052bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 305382ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 3054bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 305582ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 3056bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 305763602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",PCBDDCSetDofsSplittingLocal_BDDC);CHKERRQ(ierr); 3058bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 3059bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 3060bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 3061bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 3062a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",PCPreSolveChangeRHS_BDDC);CHKERRQ(ierr); 3063ab8c8b98SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_BDDC);CHKERRQ(ierr); 3064da1bb401SStefano Zampini PetscFunctionReturn(0); 3065da1bb401SStefano Zampini } 306643371fb9SStefano Zampini 306743371fb9SStefano Zampini /*@C 306843371fb9SStefano Zampini PCBDDCInitializePackage - This function initializes everything in the PCBDDC package. It is called 30698a690491SBarry Smith from PCInitializePackage(). 307043371fb9SStefano Zampini 307143371fb9SStefano Zampini Level: developer 307243371fb9SStefano Zampini 307343371fb9SStefano Zampini .keywords: PC, PCBDDC, initialize, package 307443371fb9SStefano Zampini .seealso: PetscInitialize() 307543371fb9SStefano Zampini @*/ 307643371fb9SStefano Zampini PetscErrorCode PCBDDCInitializePackage(void) 307743371fb9SStefano Zampini { 307843371fb9SStefano Zampini PetscErrorCode ierr; 307943371fb9SStefano Zampini int i; 308043371fb9SStefano Zampini 308143371fb9SStefano Zampini PetscFunctionBegin; 308243371fb9SStefano Zampini if (PCBDDCPackageInitialized) PetscFunctionReturn(0); 308343371fb9SStefano Zampini PCBDDCPackageInitialized = PETSC_TRUE; 308443371fb9SStefano Zampini ierr = PetscRegisterFinalize(PCBDDCFinalizePackage);CHKERRQ(ierr); 308543371fb9SStefano Zampini 308643371fb9SStefano Zampini /* general events */ 308743371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCTopo",PC_CLASSID,&PC_BDDC_Topology[0]);CHKERRQ(ierr); 308843371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCLKSP",PC_CLASSID,&PC_BDDC_LocalSolvers[0]);CHKERRQ(ierr); 308943371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCLWor",PC_CLASSID,&PC_BDDC_LocalWork[0]);CHKERRQ(ierr); 309043371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCorr",PC_CLASSID,&PC_BDDC_CorrectionSetUp[0]);CHKERRQ(ierr); 309143371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCSet",PC_CLASSID,&PC_BDDC_CoarseSetUp[0]);CHKERRQ(ierr); 309243371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCCKSP",PC_CLASSID,&PC_BDDC_CoarseSolver[0]);CHKERRQ(ierr); 309343371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCAdap",PC_CLASSID,&PC_BDDC_AdaptiveSetUp[0]);CHKERRQ(ierr); 309443371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCScal",PC_CLASSID,&PC_BDDC_Scaling[0]);CHKERRQ(ierr); 309543371fb9SStefano Zampini ierr = PetscLogEventRegister("PCBDDCSchr",PC_CLASSID,&PC_BDDC_Schurs[0]);CHKERRQ(ierr); 309643371fb9SStefano Zampini for (i=1;i<PETSC_PCBDDC_MAXLEVELS;i++) { 309743371fb9SStefano Zampini char ename[32]; 309843371fb9SStefano Zampini 309943371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCTopo l%02d",i);CHKERRQ(ierr); 310043371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Topology[i]);CHKERRQ(ierr); 310143371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCLKSP l%02d",i);CHKERRQ(ierr); 310243371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_LocalSolvers[i]);CHKERRQ(ierr); 310343371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCLWor l%02d",i);CHKERRQ(ierr); 310443371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_LocalWork[i]);CHKERRQ(ierr); 310543371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCorr l%02d",i);CHKERRQ(ierr); 310643371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CorrectionSetUp[i]);CHKERRQ(ierr); 310743371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCSet l%02d",i);CHKERRQ(ierr); 310843371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CoarseSetUp[i]);CHKERRQ(ierr); 310943371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCCKSP l%02d",i);CHKERRQ(ierr); 311043371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_CoarseSolver[i]);CHKERRQ(ierr); 311143371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCAdap l%02d",i);CHKERRQ(ierr); 311243371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_AdaptiveSetUp[i]);CHKERRQ(ierr); 311343371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCScal l%02d",i);CHKERRQ(ierr); 311443371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Scaling[i]);CHKERRQ(ierr); 311543371fb9SStefano Zampini ierr = PetscSNPrintf(ename,sizeof(ename),"PCBDDCSchr l%02d",i);CHKERRQ(ierr); 311643371fb9SStefano Zampini ierr = PetscLogEventRegister(ename,PC_CLASSID,&PC_BDDC_Schurs[i]);CHKERRQ(ierr); 311743371fb9SStefano Zampini } 311843371fb9SStefano Zampini PetscFunctionReturn(0); 311943371fb9SStefano Zampini } 312043371fb9SStefano Zampini 312143371fb9SStefano Zampini /*@C 312243371fb9SStefano Zampini PCBDDCFinalizePackage - This function frees everything from the PCBDDC package. It is 312343371fb9SStefano Zampini called from PetscFinalize() automatically. 312443371fb9SStefano Zampini 312543371fb9SStefano Zampini Level: developer 312643371fb9SStefano Zampini 312743371fb9SStefano Zampini .keywords: Petsc, destroy, package 312843371fb9SStefano Zampini .seealso: PetscFinalize() 312943371fb9SStefano Zampini @*/ 313043371fb9SStefano Zampini PetscErrorCode PCBDDCFinalizePackage(void) 313143371fb9SStefano Zampini { 313243371fb9SStefano Zampini PetscFunctionBegin; 313343371fb9SStefano Zampini PCBDDCPackageInitialized = PETSC_FALSE; 313443371fb9SStefano Zampini PetscFunctionReturn(0); 313543371fb9SStefano Zampini } 3136