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 260369aaf7SStefano Zampini /* temporarily declare it */ 270369aaf7SStefano Zampini PetscErrorCode PCApply_BDDC(PC,Vec,Vec); 280369aaf7SStefano Zampini 290c7d97c5SJed Brown #undef __FUNCT__ 300c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC" 314416b707SBarry Smith PetscErrorCode PCSetFromOptions_BDDC(PetscOptionItems *PetscOptionsObject,PC pc) 320c7d97c5SJed Brown { 330c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 340c7d97c5SJed Brown PetscErrorCode ierr; 350c7d97c5SJed Brown 360c7d97c5SJed Brown PetscFunctionBegin; 37e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"BDDC options");CHKERRQ(ierr); 388eeda7d8SStefano Zampini /* Verbose debugging */ 39a13144ffSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_check_level","Verbose output for PCBDDC (intended for debug)","none",pcbddc->dbg_flag,&pcbddc->dbg_flag,NULL);CHKERRQ(ierr); 40a13144ffSStefano Zampini /* Approximate solvers */ 41c7017625SStefano 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); 42c7017625SStefano 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); 43c7017625SStefano 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); 44c7017625SStefano 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); 456b78500eSPatrick Sanan /* Primal space customization */ 4608a5cf49SStefano 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); 47be12c134Sstefano_zampini ierr = PetscOptionsInt("-pc_bddc_graph_maxcount","Maximum number of shared subdomains for a connected component","none",pcbddc->graphmaxcount,&pcbddc->graphmaxcount,NULL);CHKERRQ(ierr); 488eeda7d8SStefano 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); 498eeda7d8SStefano 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); 508eeda7d8SStefano 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); 5114f95afaSStefano 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); 526661aa1dSStefano 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); 5314f95afaSStefano 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); 548eeda7d8SStefano Zampini /* Change of basis */ 55b9b85e73SStefano 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); 56b9b85e73SStefano 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); 57674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 58674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 59674ae819SStefano Zampini } 608eeda7d8SStefano Zampini /* Switch between M_2 (default) and M_3 preconditioners (as defined by C. Dohrmann in the ref. article) */ 618eeda7d8SStefano 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); 6257de7509SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_coarse_eqs_per_proc","Number of equations per process for coarse problem redistribution (significant only at the coarsest level)","none",pcbddc->coarse_eqs_per_proc,&pcbddc->coarse_eqs_per_proc,NULL);CHKERRQ(ierr); 630298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr); 642b510759SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr); 65323d395dSStefano 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); 66674ae819SStefano 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); 67b96c3477SStefano 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); 68b96c3477SStefano 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); 69b96c3477SStefano 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); 70683d3df6SStefano 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); 71bf3a8328SStefano 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); 72bf3a8328SStefano 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); 734c6709b3SStefano Zampini ierr = PetscOptionsReal("-pc_bddc_adaptive_threshold","Threshold to be used for adaptive selection of constraints","none",pcbddc->adaptive_threshold,&pcbddc->adaptive_threshold,NULL);CHKERRQ(ierr); 7408122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmin","Minimum number of constraints per connected components","none",pcbddc->adaptive_nmin,&pcbddc->adaptive_nmin,NULL);CHKERRQ(ierr); 7508122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmax","Maximum number of constraints per connected components","none",pcbddc->adaptive_nmax,&pcbddc->adaptive_nmax,NULL);CHKERRQ(ierr); 763301b35fSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_symmetric","Symmetric computation of primal basis functions","none",pcbddc->symmetric_primal,&pcbddc->symmetric_primal,NULL);CHKERRQ(ierr); 77b0c7d250SStefano 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); 78b3afcdbeSStefano 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); 79e9627c49SStefano 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); 8027b6a85dSStefano 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); 81a198735bSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nonetflux","Automatic computation of no-net-flux quadrature weights","none",pcbddc->compute_nonetflux,&pcbddc->compute_nonetflux,NULL);CHKERRQ(ierr); 824f1b2e48SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_detect_disconnected","Detects disconnected subdomains","none",pcbddc->detect_disconnected,&pcbddc->detect_disconnected,NULL);CHKERRQ(ierr); 8370c64980SStefano 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); 840c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 850c7d97c5SJed Brown PetscFunctionReturn(0); 860c7d97c5SJed Brown } 876b78500eSPatrick Sanan 886b78500eSPatrick Sanan #undef __FUNCT__ 896b78500eSPatrick Sanan #define __FUNCT__ "PCView_BDDC" 906b78500eSPatrick Sanan static PetscErrorCode PCView_BDDC(PC pc,PetscViewer viewer) 916b78500eSPatrick Sanan { 926b78500eSPatrick Sanan PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 93e9627c49SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 946b78500eSPatrick Sanan PetscErrorCode ierr; 956b78500eSPatrick Sanan PetscBool isascii,isstring; 96e9627c49SStefano Zampini PetscSubcomm subcomm; 97e9627c49SStefano Zampini PetscViewer subviewer; 986b78500eSPatrick Sanan 996b78500eSPatrick Sanan PetscFunctionBegin; 1006b78500eSPatrick Sanan ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1016b78500eSPatrick Sanan ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 1026b78500eSPatrick Sanan /* Nothing printed for the String viewer */ 1036b78500eSPatrick Sanan /* ASCII viewer */ 1046b78500eSPatrick Sanan if (isascii) { 1054b2aedd3SStefano Zampini PetscMPIInt color,rank,size; 106fbad9177SStefano Zampini PetscInt64 loc[7],gsum[6],gmax[6],gmin[6],totbenign; 107e9627c49SStefano Zampini PetscScalar interface_size; 108e9627c49SStefano Zampini PetscReal ratio1=0.,ratio2=0.; 109e9627c49SStefano Zampini Vec counter; 1106b78500eSPatrick Sanan 111e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use verbose output: %d\n",pcbddc->dbg_flag);CHKERRQ(ierr); 112e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use user-defined CSR: %d\n",!!pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 1136b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use local mat graph: %d\n",pcbddc->use_local_adj);CHKERRQ(ierr); 114e9627c49SStefano Zampini if (pcbddc->mat_graph->twodim) { 115e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Connectivity graph topological dimension: 2\n");CHKERRQ(ierr); 116e9627c49SStefano Zampini } else { 117e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Connectivity graph topological dimension: 3\n");CHKERRQ(ierr); 118e9627c49SStefano Zampini } 119a70d66d9SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Graph max count: %d\n",pcbddc->graphmaxcount);CHKERRQ(ierr); 120a198735bSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use vertices: %d (vertex size %d)\n",pcbddc->use_vertices,pcbddc->vertex_size);CHKERRQ(ierr); 1216b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use edges: %d\n",pcbddc->use_edges);CHKERRQ(ierr); 1226b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use faces: %d\n",pcbddc->use_faces);CHKERRQ(ierr); 1236b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use true near null space: %d\n",pcbddc->use_nnsp_true);CHKERRQ(ierr); 1246b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use QR for single constraints on cc: %d\n",pcbddc->use_qr_single);CHKERRQ(ierr); 1256b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use change of basis on local edge nodes: %d\n",pcbddc->use_change_of_basis);CHKERRQ(ierr); 1266b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use change of basis on local face nodes: %d\n",pcbddc->use_change_on_faces);CHKERRQ(ierr); 12727b6a85dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: User defined change of basis matrix: %d\n",!!pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 12827b6a85dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Has change of basis matrix: %d\n",!!pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 12927b6a85dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Eliminate dirichlet boundary dofs: %d\n",pcbddc->eliminate_dirdofs);CHKERRQ(ierr); 1306b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Switch on static condensation ops around the interface preconditioner: %d\n",pcbddc->switch_static);CHKERRQ(ierr); 13127b6a85dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use exact dirichlet trick: %d\n",pcbddc->use_exact_dirichlet_trick);CHKERRQ(ierr); 1326b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Multilevel max levels: %d\n",pcbddc->max_levels);CHKERRQ(ierr); 133e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Multilevel coarsening ratio: %d\n",pcbddc->coarsening_ratio);CHKERRQ(ierr); 1346b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use estimated eigs for coarse problem: %d\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 1356b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use deluxe scaling: %d\n",pcbddc->use_deluxe_scaling);CHKERRQ(ierr); 136e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use deluxe zerorows: %d\n",pcbddc->deluxe_zerorows);CHKERRQ(ierr); 1376b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Rebuild interface graph for Schur principal minors: %d\n",pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 1386b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Number of dofs' layers for the computation of principal minors: %d\n",pcbddc->sub_schurs_layers);CHKERRQ(ierr); 1396b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use user CSR graph to compute successive layers: %d\n",pcbddc->sub_schurs_use_useradj);CHKERRQ(ierr); 140e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Adaptive constraint selection threshold (active %d, userdefined %d): %g\n",pcbddc->adaptive_threshold,pcbddc->adaptive_selection,pcbddc->adaptive_userdefined);CHKERRQ(ierr); 1416b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Min constraints / connected component: %d\n",pcbddc->adaptive_nmin);CHKERRQ(ierr); 1426b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Max constraints / connected component: %d\n",pcbddc->adaptive_nmax);CHKERRQ(ierr); 143e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Invert exact Schur complement for adaptive selection: %d\n",pcbddc->sub_schurs_exact_schur);CHKERRQ(ierr); 1446b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Symmetric computation of primal basis functions: %d\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 1456b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Num. Procs. to map coarse adjacency list: %d\n",pcbddc->coarse_adj_red);CHKERRQ(ierr); 146e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Coarse eqs per proc (significant at the coarsest level): %d\n",pcbddc->coarse_eqs_per_proc);CHKERRQ(ierr); 147e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Detect disconnected: %d\n",pcbddc->detect_disconnected);CHKERRQ(ierr); 148fc17d649SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Benign subspace trick: %d (change explicit %d)\n",pcbddc->benign_saddle_point,pcbddc->benign_change_explicit);CHKERRQ(ierr); 149a198735bSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Benign subspace trick is active: %d\n",pcbddc->benign_have_null);CHKERRQ(ierr); 150a198735bSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Algebraic computation of no-net-flux %d\n",pcbddc->compute_nonetflux);CHKERRQ(ierr); 1516b78500eSPatrick Sanan 152fbad9177SStefano Zampini /* compute interface size */ 153e9627c49SStefano Zampini ierr = VecSet(pcis->vec1_B,1.0);CHKERRQ(ierr); 154e9627c49SStefano Zampini ierr = MatCreateVecs(pc->pmat,&counter,0);CHKERRQ(ierr); 155e9627c49SStefano Zampini ierr = VecSet(counter,0.0);CHKERRQ(ierr); 156e9627c49SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 157e9627c49SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 158e9627c49SStefano Zampini ierr = VecSum(counter,&interface_size);CHKERRQ(ierr); 159e9627c49SStefano Zampini ierr = VecDestroy(&counter);CHKERRQ(ierr); 160fbad9177SStefano Zampini 161fbad9177SStefano Zampini /* compute some statistics on the domain decomposition */ 162e9627c49SStefano Zampini gsum[0] = 1; 163fbad9177SStefano Zampini gsum[1] = gsum[2] = gsum[3] = gsum[4] = gsum[5] = 0; 164e9627c49SStefano Zampini loc[0] = !!pcis->n; 165e9627c49SStefano Zampini loc[1] = pcis->n - pcis->n_B; 166e9627c49SStefano Zampini loc[2] = pcis->n_B; 167e9627c49SStefano Zampini loc[3] = pcbddc->local_primal_size; 168345ecf6cSStefano Zampini loc[4] = pcis->n; 169fbad9177SStefano Zampini loc[5] = pcbddc->n_local_subs > 0 ? pcbddc->n_local_subs : (pcis->n ? 1 : 0); 170fbad9177SStefano Zampini loc[6] = pcbddc->benign_n; 171fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gsum,6,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 172fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = -1; 173fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gmax,6,MPIU_INT64,MPI_MAX,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 174fbad9177SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = loc[5] = PETSC_MAX_INT; 175fbad9177SStefano Zampini ierr = MPI_Reduce(loc,gmin,6,MPIU_INT64,MPI_MIN,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 176fbad9177SStefano Zampini ierr = MPI_Reduce(&loc[6],&totbenign,1,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 177e9627c49SStefano Zampini if (pcbddc->coarse_size) { 178e9627c49SStefano Zampini ratio1 = pc->pmat->rmap->N/(1.*pcbddc->coarse_size); 179e9627c49SStefano Zampini ratio2 = PetscRealPart(interface_size)/pcbddc->coarse_size; 180e9627c49SStefano Zampini } 181e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: ********************************** STATISTICS AT LEVEL %d **********************************\n",pcbddc->current_level);CHKERRQ(ierr); 182e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Global dofs sizes: all %d interface %d coarse %d\n",pc->pmat->rmap->N,(PetscInt)PetscRealPart(interface_size),pcbddc->coarse_size);CHKERRQ(ierr); 183e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Coarsening ratios: all/coarse %d interface/coarse %d\n",(PetscInt)ratio1,(PetscInt)ratio2);CHKERRQ(ierr); 184e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Active processes : %d\n",(PetscInt)gsum[0]);CHKERRQ(ierr); 185fbad9177SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Total subdomains : %d\n",(PetscInt)gsum[5]);CHKERRQ(ierr); 186345ecf6cSStefano Zampini if (pcbddc->benign_have_null) { 187345ecf6cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Benign subs : %d\n",(PetscInt)totbenign);CHKERRQ(ierr); 188345ecf6cSStefano Zampini } 189e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Dofs type :\tMIN\tMAX\tMEAN\n",(PetscInt)gmin[1],(PetscInt)gmax[1],(PetscInt)(gsum[1]/gsum[0]));CHKERRQ(ierr); 190e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Interior dofs :\t%d\t%d\t%d\n",(PetscInt)gmin[1],(PetscInt)gmax[1],(PetscInt)(gsum[1]/gsum[0]));CHKERRQ(ierr); 191e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Interface dofs :\t%d\t%d\t%d\n",(PetscInt)gmin[2],(PetscInt)gmax[2],(PetscInt)(gsum[2]/gsum[0]));CHKERRQ(ierr); 192e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Primal dofs :\t%d\t%d\t%d\n",(PetscInt)gmin[3],(PetscInt)gmax[3],(PetscInt)(gsum[3]/gsum[0]));CHKERRQ(ierr); 193345ecf6cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Local dofs :\t%d\t%d\t%d\n",(PetscInt)gmin[4],(PetscInt)gmax[4],(PetscInt)(gsum[4]/gsum[0]));CHKERRQ(ierr); 194fbad9177SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Local subs :\t%d\t%d\n",(PetscInt)gmin[5],(PetscInt)gmax[5]);CHKERRQ(ierr); 19527b6a85dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: ********************************** COARSE PROBLEM DETAILS *********************************\n",pcbddc->current_level);CHKERRQ(ierr); 19627b6a85dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 197e9627c49SStefano Zampini 198fbad9177SStefano Zampini /* the coarse problem can be handled by a different communicator */ 199e9627c49SStefano Zampini if (pcbddc->coarse_ksp) color = 1; 200e9627c49SStefano Zampini else color = 0; 201e9627c49SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 2024b2aedd3SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 203e9627c49SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)pc),&subcomm);CHKERRQ(ierr); 2044b2aedd3SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,PetscMin(size,2));CHKERRQ(ierr); 205e9627c49SStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 206e9627c49SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 207e9627c49SStefano Zampini if (color == 1) { 208e9627c49SStefano Zampini ierr = KSPView(pcbddc->coarse_ksp,subviewer);CHKERRQ(ierr); 209e9627c49SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 210e9627c49SStefano Zampini } 211e9627c49SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 212e9627c49SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 213e9627c49SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 214e9627c49SStefano Zampini } 2156b78500eSPatrick Sanan PetscFunctionReturn(0); 2166b78500eSPatrick Sanan } 217a13144ffSStefano Zampini 218a13144ffSStefano Zampini #undef __FUNCT__ 219a13144ffSStefano Zampini #define __FUNCT__ "PCBDDCSetDiscreteGradient_BDDC" 2201e0482f5SStefano Zampini static PetscErrorCode PCBDDCSetDiscreteGradient_BDDC(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 221a13144ffSStefano Zampini { 222a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 223a13144ffSStefano Zampini PetscErrorCode ierr; 224a13144ffSStefano Zampini 225a13144ffSStefano Zampini PetscFunctionBegin; 226a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr); 227a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 228a13144ffSStefano Zampini pcbddc->discretegradient = G; 229a13144ffSStefano Zampini pcbddc->nedorder = order > 0 ? order : -order; 230495a2a07SStefano Zampini pcbddc->nedfield = field; 2311e0482f5SStefano Zampini pcbddc->nedglobal = global; 2321e0482f5SStefano Zampini pcbddc->conforming = conforming; 233a13144ffSStefano Zampini PetscFunctionReturn(0); 234a13144ffSStefano Zampini } 235a13144ffSStefano Zampini 236a13144ffSStefano Zampini #undef __FUNCT__ 237a13144ffSStefano Zampini #define __FUNCT__ "PCBDDCSetDiscreteGradient" 238a13144ffSStefano Zampini /*@ 239a13144ffSStefano Zampini PCBDDCSetDiscreteGradient - Sets the discrete gradient 240a13144ffSStefano Zampini 241a13144ffSStefano Zampini Collective on PC 242a13144ffSStefano Zampini 243a13144ffSStefano Zampini Input Parameters: 244a13144ffSStefano Zampini + pc - the preconditioning context 245a13144ffSStefano Zampini . G - the discrete gradient matrix (should be in AIJ format) 246a13144ffSStefano Zampini . order - the order of the Nedelec space (1 for the lowest order) 247495a2a07SStefano Zampini . field - the field id of the Nedelec dofs (not used if the fields have not been specified) 2481e0482f5SStefano Zampini . global - the type of global ordering for the rows of G 249a13144ffSStefano Zampini - conforming - whether the mesh is conforming or not 250a13144ffSStefano Zampini 251a13144ffSStefano Zampini Level: advanced 252a13144ffSStefano Zampini 253a13144ffSStefano Zampini Notes: The discrete gradient matrix G is used to analyze the subdomain edges, and it should not contain any zero entry. 254495a2a07SStefano Zampini For variable order spaces, the order should be set to zero. 2551e0482f5SStefano Zampini If global is true, the rows of G should be given in global ordering for the whole dofs; 2561e0482f5SStefano Zampini if false, the ordering should be global for the Nedelec field. 2571e0482f5SStefano 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 2581e0482f5SStefano Zampini and geid the one for the Nedelec field. 259a13144ffSStefano Zampini 260495a2a07SStefano Zampini .seealso: PCBDDC,PCBDDCSetDofsSplitting(),PCBDDCSetDofsSplittingLocal() 261a13144ffSStefano Zampini @*/ 2621e0482f5SStefano Zampini PetscErrorCode PCBDDCSetDiscreteGradient(PC pc, Mat G, PetscInt order, PetscInt field, PetscBool global, PetscBool conforming) 263a13144ffSStefano Zampini { 264a13144ffSStefano Zampini PetscErrorCode ierr; 265a13144ffSStefano Zampini 266a13144ffSStefano Zampini PetscFunctionBegin; 267a13144ffSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 268a13144ffSStefano Zampini PetscValidHeaderSpecific(G,MAT_CLASSID,2); 269a13144ffSStefano Zampini PetscValidLogicalCollectiveInt(pc,order,3); 2701e0482f5SStefano Zampini PetscValidLogicalCollectiveInt(pc,field,4); 2711e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,global,5); 2721e0482f5SStefano Zampini PetscValidLogicalCollectiveBool(pc,conforming,6); 2731e0482f5SStefano Zampini PetscCheckSameComm(pc,1,G,2); 2741e0482f5SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDiscreteGradient_C",(PC,Mat,PetscInt,PetscInt,PetscBool,PetscBool),(pc,G,order,field,global,conforming));CHKERRQ(ierr); 275a13144ffSStefano Zampini PetscFunctionReturn(0); 276a13144ffSStefano Zampini } 277a13144ffSStefano Zampini 278a198735bSStefano Zampini #undef __FUNCT__ 279a198735bSStefano Zampini #define __FUNCT__ "PCBDDCSetDivergenceMat_BDDC" 2808ae0ca82SStefano Zampini static PetscErrorCode PCBDDCSetDivergenceMat_BDDC(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 281a198735bSStefano Zampini { 282a198735bSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 283a198735bSStefano Zampini PetscErrorCode ierr; 2846b78500eSPatrick Sanan 285a198735bSStefano Zampini PetscFunctionBegin; 286a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)divudotp);CHKERRQ(ierr); 287a198735bSStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 288a198735bSStefano Zampini pcbddc->divudotp = divudotp; 2898ae0ca82SStefano Zampini pcbddc->divudotp_trans = trans; 290a198735bSStefano Zampini pcbddc->compute_nonetflux = PETSC_TRUE; 291a198735bSStefano Zampini if (vl2l) { 292a198735bSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2l);CHKERRQ(ierr); 293fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 294a198735bSStefano Zampini pcbddc->divudotp_vl2l = vl2l; 295a198735bSStefano Zampini } 296a198735bSStefano Zampini PetscFunctionReturn(0); 297a198735bSStefano Zampini } 2983d996552SStefano Zampini 299a198735bSStefano Zampini #undef __FUNCT__ 300a198735bSStefano Zampini #define __FUNCT__ "PCBDDCSetDivergenceMat" 301a198735bSStefano Zampini /*@ 302a198735bSStefano Zampini PCBDDCSetDivergenceMat - Sets the linear operator representing \int_\Omega \div {\bf u} \cdot p dx 303a198735bSStefano Zampini 304a198735bSStefano Zampini Collective on PC 305a198735bSStefano Zampini 306a198735bSStefano Zampini Input Parameters: 307a198735bSStefano Zampini + pc - the preconditioning context 308a198735bSStefano Zampini . divudotp - the matrix (must be of type MATIS) 3098ae0ca82SStefano Zampini . trans - if trans if false (resp. true), then pressures are in the test (trial) space and velocities are in the trial (test) space. 310bb05f991SStefano Zampini - vl2l - optional IS describing the local (wrt the local mat in divudotp) to local (wrt the local mat in pc->pmat) map for the velocities 311a198735bSStefano Zampini 312a198735bSStefano Zampini Level: advanced 313a198735bSStefano Zampini 3148ae0ca82SStefano Zampini Notes: This auxiliary matrix is used to compute quadrature weights representing the net-flux across subdomain boundaries 315a198735bSStefano Zampini 316a198735bSStefano Zampini .seealso: PCBDDC 317a198735bSStefano Zampini @*/ 3188ae0ca82SStefano Zampini PetscErrorCode PCBDDCSetDivergenceMat(PC pc, Mat divudotp, PetscBool trans, IS vl2l) 319a198735bSStefano Zampini { 320a198735bSStefano Zampini PetscBool ismatis; 321a198735bSStefano Zampini PetscErrorCode ierr; 322a198735bSStefano Zampini 323a198735bSStefano Zampini PetscFunctionBegin; 324a198735bSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 325a198735bSStefano Zampini PetscValidHeaderSpecific(divudotp,MAT_CLASSID,2); 326a198735bSStefano Zampini PetscCheckSameComm(pc,1,divudotp,2); 3278ae0ca82SStefano Zampini PetscValidLogicalCollectiveBool(pc,trans,3); 3288ae0ca82SStefano Zampini if (vl2l) PetscValidHeaderSpecific(divudotp,IS_CLASSID,4); 329a198735bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)divudotp,MATIS,&ismatis);CHKERRQ(ierr); 330a198735bSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Divergence matrix needs to be of type MATIS"); 3318ae0ca82SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDivergenceMat_C",(PC,Mat,PetscBool,IS),(pc,divudotp,trans,vl2l));CHKERRQ(ierr); 332a198735bSStefano Zampini PetscFunctionReturn(0); 333a198735bSStefano Zampini } 3342d505d7fSStefano Zampini 335674ae819SStefano Zampini #undef __FUNCT__ 336906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCSetChangeOfBasisMat_BDDC" 3371dd7afcfSStefano Zampini static PetscErrorCode PCBDDCSetChangeOfBasisMat_BDDC(PC pc, Mat change, PetscBool interior) 338b9b85e73SStefano Zampini { 339b9b85e73SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 340b9b85e73SStefano Zampini PetscErrorCode ierr; 341b9b85e73SStefano Zampini 342b9b85e73SStefano Zampini PetscFunctionBegin; 343b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)change);CHKERRQ(ierr); 34456282151SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 345b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = change; 3461dd7afcfSStefano Zampini pcbddc->change_interior = interior; 347b9b85e73SStefano Zampini PetscFunctionReturn(0); 348b9b85e73SStefano Zampini } 349b9b85e73SStefano Zampini #undef __FUNCT__ 350906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCSetChangeOfBasisMat" 351b9b85e73SStefano Zampini /*@ 352906d46d4SStefano Zampini PCBDDCSetChangeOfBasisMat - Set user defined change of basis for dofs 353b9b85e73SStefano Zampini 354b9b85e73SStefano Zampini Collective on PC 355b9b85e73SStefano Zampini 356b9b85e73SStefano Zampini Input Parameters: 357b9b85e73SStefano Zampini + pc - the preconditioning context 3581dd7afcfSStefano Zampini . change - the change of basis matrix 3591dd7afcfSStefano Zampini - interior - whether or not the change of basis modifies interior dofs 360b9b85e73SStefano Zampini 361b9b85e73SStefano Zampini Level: intermediate 362b9b85e73SStefano Zampini 363b9b85e73SStefano Zampini Notes: 364b9b85e73SStefano Zampini 365b9b85e73SStefano Zampini .seealso: PCBDDC 366b9b85e73SStefano Zampini @*/ 3671dd7afcfSStefano Zampini PetscErrorCode PCBDDCSetChangeOfBasisMat(PC pc, Mat change, PetscBool interior) 368b9b85e73SStefano Zampini { 369b9b85e73SStefano Zampini PetscErrorCode ierr; 370b9b85e73SStefano Zampini 371b9b85e73SStefano Zampini PetscFunctionBegin; 372b9b85e73SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 373b9b85e73SStefano Zampini PetscValidHeaderSpecific(change,MAT_CLASSID,2); 374906d46d4SStefano Zampini PetscCheckSameComm(pc,1,change,2); 375906d46d4SStefano Zampini if (pc->mat) { 376906d46d4SStefano Zampini PetscInt rows_c,cols_c,rows,cols; 377906d46d4SStefano Zampini ierr = MatGetSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 378906d46d4SStefano Zampini ierr = MatGetSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 3796c4ed002SBarry Smith 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); 3806c4ed002SBarry Smith 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); 381906d46d4SStefano Zampini ierr = MatGetLocalSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 382906d46d4SStefano Zampini ierr = MatGetLocalSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 3836c4ed002SBarry Smith 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); 3846c4ed002SBarry Smith 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); 385906d46d4SStefano Zampini } 3861dd7afcfSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetChangeOfBasisMat_C",(PC,Mat,PetscBool),(pc,change,interior));CHKERRQ(ierr); 387b9b85e73SStefano Zampini PetscFunctionReturn(0); 388b9b85e73SStefano Zampini } 3892d505d7fSStefano Zampini 390b9b85e73SStefano Zampini #undef __FUNCT__ 39130368db7SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesIS_BDDC" 39230368db7SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesIS_BDDC(PC pc, IS PrimalVertices) 39330368db7SStefano Zampini { 39430368db7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 39556282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 39630368db7SStefano Zampini PetscErrorCode ierr; 39730368db7SStefano Zampini 39830368db7SStefano Zampini PetscFunctionBegin; 39956282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 40056282151SStefano Zampini if (pcbddc->user_primal_vertices) { 40156282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices,&isequal);CHKERRQ(ierr); 40256282151SStefano Zampini } 40330368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 40430368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 40530368db7SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 40656282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 40730368db7SStefano Zampini PetscFunctionReturn(0); 40830368db7SStefano Zampini } 40930368db7SStefano Zampini #undef __FUNCT__ 41030368db7SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesIS" 41130368db7SStefano Zampini /*@ 41230368db7SStefano Zampini PCBDDCSetPrimalVerticesIS - Set additional user defined primal vertices in PCBDDC 41330368db7SStefano Zampini 41430368db7SStefano Zampini Collective 41530368db7SStefano Zampini 41630368db7SStefano Zampini Input Parameters: 41730368db7SStefano Zampini + pc - the preconditioning context 41830368db7SStefano Zampini - PrimalVertices - index set of primal vertices in global numbering (can be empty) 41930368db7SStefano Zampini 42030368db7SStefano Zampini Level: intermediate 42130368db7SStefano Zampini 42230368db7SStefano Zampini Notes: 42330368db7SStefano Zampini Any process can list any global node 42430368db7SStefano Zampini 42530368db7SStefano Zampini .seealso: PCBDDC 42630368db7SStefano Zampini @*/ 42730368db7SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesIS(PC pc, IS PrimalVertices) 42830368db7SStefano Zampini { 42930368db7SStefano Zampini PetscErrorCode ierr; 43030368db7SStefano Zampini 43130368db7SStefano Zampini PetscFunctionBegin; 43230368db7SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 43330368db7SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 43430368db7SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 43530368db7SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 43630368db7SStefano Zampini PetscFunctionReturn(0); 43730368db7SStefano Zampini } 4382d505d7fSStefano Zampini 43930368db7SStefano Zampini #undef __FUNCT__ 440674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS_BDDC" 441674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 442674ae819SStefano Zampini { 443674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 44456282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 445674ae819SStefano Zampini PetscErrorCode ierr; 4461e6b0712SBarry Smith 447674ae819SStefano Zampini PetscFunctionBegin; 44856282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 44956282151SStefano Zampini if (pcbddc->user_primal_vertices_local) { 45056282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices_local,&isequal);CHKERRQ(ierr); 45156282151SStefano Zampini } 452674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 45330368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 45430368db7SStefano Zampini pcbddc->user_primal_vertices_local = PrimalVertices; 45556282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 456674ae819SStefano Zampini PetscFunctionReturn(0); 457674ae819SStefano Zampini } 458674ae819SStefano Zampini #undef __FUNCT__ 459674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS" 460674ae819SStefano Zampini /*@ 46128509bceSStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC 462674ae819SStefano Zampini 46317eb1463SStefano Zampini Collective 464674ae819SStefano Zampini 465674ae819SStefano Zampini Input Parameters: 466674ae819SStefano Zampini + pc - the preconditioning context 46717eb1463SStefano Zampini - PrimalVertices - index set of primal vertices in local numbering (can be empty) 468674ae819SStefano Zampini 469674ae819SStefano Zampini Level: intermediate 470674ae819SStefano Zampini 471674ae819SStefano Zampini Notes: 472674ae819SStefano Zampini 473674ae819SStefano Zampini .seealso: PCBDDC 474674ae819SStefano Zampini @*/ 475674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 476674ae819SStefano Zampini { 477674ae819SStefano Zampini PetscErrorCode ierr; 478674ae819SStefano Zampini 479674ae819SStefano Zampini PetscFunctionBegin; 480674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 481674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 48217eb1463SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 483674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 484674ae819SStefano Zampini PetscFunctionReturn(0); 485674ae819SStefano Zampini } 4862d505d7fSStefano Zampini 4870c7d97c5SJed Brown #undef __FUNCT__ 4884fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio_BDDC" 4894fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 4904fad6a16SStefano Zampini { 4914fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4924fad6a16SStefano Zampini 4934fad6a16SStefano Zampini PetscFunctionBegin; 4944fad6a16SStefano Zampini pcbddc->coarsening_ratio = k; 4954fad6a16SStefano Zampini PetscFunctionReturn(0); 4964fad6a16SStefano Zampini } 4971e6b0712SBarry Smith 4984fad6a16SStefano Zampini #undef __FUNCT__ 4994fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio" 5004fad6a16SStefano Zampini /*@ 50128509bceSStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel 5024fad6a16SStefano Zampini 5034fad6a16SStefano Zampini Logically collective on PC 5044fad6a16SStefano Zampini 5054fad6a16SStefano Zampini Input Parameters: 5064fad6a16SStefano Zampini + pc - the preconditioning context 50728509bceSStefano Zampini - k - coarsening ratio (H/h at the coarser level) 5084fad6a16SStefano Zampini 5090f202f7eSStefano Zampini Options Database Keys: 5100f202f7eSStefano Zampini . -pc_bddc_coarsening_ratio 5114fad6a16SStefano Zampini 5124fad6a16SStefano Zampini Level: intermediate 5134fad6a16SStefano Zampini 5144fad6a16SStefano Zampini Notes: 5150f202f7eSStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level 5164fad6a16SStefano Zampini 5170f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetLevels() 5184fad6a16SStefano Zampini @*/ 5194fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 5204fad6a16SStefano Zampini { 5214fad6a16SStefano Zampini PetscErrorCode ierr; 5224fad6a16SStefano Zampini 5234fad6a16SStefano Zampini PetscFunctionBegin; 5244fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5252b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,k,2); 5264fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 5274fad6a16SStefano Zampini PetscFunctionReturn(0); 5284fad6a16SStefano Zampini } 5292b510759SStefano Zampini 530b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */ 5312b510759SStefano Zampini #undef __FUNCT__ 532b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet_BDDC" 533b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg) 534b8ffe317SStefano Zampini { 535b8ffe317SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 536b8ffe317SStefano Zampini 537b8ffe317SStefano Zampini PetscFunctionBegin; 53885c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = flg; 539b8ffe317SStefano Zampini PetscFunctionReturn(0); 540b8ffe317SStefano Zampini } 541b8ffe317SStefano Zampini 542b8ffe317SStefano Zampini #undef __FUNCT__ 543b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet" 544b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg) 5452b510759SStefano Zampini { 5462b510759SStefano Zampini PetscErrorCode ierr; 5472b510759SStefano Zampini 5482b510759SStefano Zampini PetscFunctionBegin; 5492b510759SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 550b8ffe317SStefano Zampini PetscValidLogicalCollectiveBool(pc,flg,2); 551b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr); 5522b510759SStefano Zampini PetscFunctionReturn(0); 5532b510759SStefano Zampini } 5541e6b0712SBarry Smith 5554fad6a16SStefano Zampini #undef __FUNCT__ 5562b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel_BDDC" 5572b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level) 5584fad6a16SStefano Zampini { 5594fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5604fad6a16SStefano Zampini 5614fad6a16SStefano Zampini PetscFunctionBegin; 5622b510759SStefano Zampini pcbddc->current_level = level; 5634fad6a16SStefano Zampini PetscFunctionReturn(0); 5644fad6a16SStefano Zampini } 5651e6b0712SBarry Smith 5664fad6a16SStefano Zampini #undef __FUNCT__ 567b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel" 568b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 569b8ffe317SStefano Zampini { 570b8ffe317SStefano Zampini PetscErrorCode ierr; 571b8ffe317SStefano Zampini 572b8ffe317SStefano Zampini PetscFunctionBegin; 573b8ffe317SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 574b8ffe317SStefano Zampini PetscValidLogicalCollectiveInt(pc,level,2); 575b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr); 576b8ffe317SStefano Zampini PetscFunctionReturn(0); 577b8ffe317SStefano Zampini } 578b8ffe317SStefano Zampini 579b8ffe317SStefano Zampini #undef __FUNCT__ 5802b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels_BDDC" 5812b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels) 5822b510759SStefano Zampini { 5832b510759SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5842b510759SStefano Zampini 5852b510759SStefano Zampini PetscFunctionBegin; 5862b510759SStefano Zampini pcbddc->max_levels = levels; 5872b510759SStefano Zampini PetscFunctionReturn(0); 5882b510759SStefano Zampini } 5892b510759SStefano Zampini 5902b510759SStefano Zampini #undef __FUNCT__ 5912b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels" 5924fad6a16SStefano Zampini /*@ 59328509bceSStefano Zampini PCBDDCSetLevels - Sets the maximum number of levels for multilevel 5944fad6a16SStefano Zampini 5954fad6a16SStefano Zampini Logically collective on PC 5964fad6a16SStefano Zampini 5974fad6a16SStefano Zampini Input Parameters: 5984fad6a16SStefano Zampini + pc - the preconditioning context 59928509bceSStefano Zampini - levels - the maximum number of levels (max 9) 6004fad6a16SStefano Zampini 6010f202f7eSStefano Zampini Options Database Keys: 6020f202f7eSStefano Zampini . -pc_bddc_levels 6034fad6a16SStefano Zampini 6044fad6a16SStefano Zampini Level: intermediate 6054fad6a16SStefano Zampini 6064fad6a16SStefano Zampini Notes: 6070f202f7eSStefano Zampini Default value is 0, i.e. traditional one-level BDDC 6084fad6a16SStefano Zampini 6090f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetCoarseningRatio() 6104fad6a16SStefano Zampini @*/ 6112b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels) 6124fad6a16SStefano Zampini { 6134fad6a16SStefano Zampini PetscErrorCode ierr; 6144fad6a16SStefano Zampini 6154fad6a16SStefano Zampini PetscFunctionBegin; 6164fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6172b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,levels,2); 618312be037SStefano Zampini if (levels > 99) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Maximum number of levels for bddc is 99\n"); 6192b510759SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr); 6204fad6a16SStefano Zampini PetscFunctionReturn(0); 6214fad6a16SStefano Zampini } 6221e6b0712SBarry Smith 6234fad6a16SStefano Zampini #undef __FUNCT__ 6243b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC" 6253b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 6263b03a366Sstefano_zampini { 6273b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 62856282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 6293b03a366Sstefano_zampini PetscErrorCode ierr; 6303b03a366Sstefano_zampini 6313b03a366Sstefano_zampini PetscFunctionBegin; 63256282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 63356282151SStefano Zampini if (pcbddc->DirichletBoundaries) { 63456282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundaries,&isequal);CHKERRQ(ierr); 63556282151SStefano Zampini } 636785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 637785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 6383b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 63936e030ebSStefano Zampini pcbddc->DirichletBoundaries = DirichletBoundaries; 64056282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 6413b03a366Sstefano_zampini PetscFunctionReturn(0); 6423b03a366Sstefano_zampini } 6431e6b0712SBarry Smith 6443b03a366Sstefano_zampini #undef __FUNCT__ 6453b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries" 6463b03a366Sstefano_zampini /*@ 64728509bceSStefano Zampini PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem. 6483b03a366Sstefano_zampini 649785d1243SStefano Zampini Collective 6503b03a366Sstefano_zampini 6513b03a366Sstefano_zampini Input Parameters: 6523b03a366Sstefano_zampini + pc - the preconditioning context 653785d1243SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries 6543b03a366Sstefano_zampini 6553b03a366Sstefano_zampini Level: intermediate 6563b03a366Sstefano_zampini 6570f202f7eSStefano Zampini Notes: 6580f202f7eSStefano Zampini Provide the information if you used MatZeroRows/Columns routines. Any process can list any global node 6593b03a366Sstefano_zampini 6600f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundariesLocal(), MatZeroRows(), MatZeroRowsColumns() 6613b03a366Sstefano_zampini @*/ 6623b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 6633b03a366Sstefano_zampini { 6643b03a366Sstefano_zampini PetscErrorCode ierr; 6653b03a366Sstefano_zampini 6663b03a366Sstefano_zampini PetscFunctionBegin; 6673b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 668674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 669785d1243SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 6703b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 6713b03a366Sstefano_zampini PetscFunctionReturn(0); 6723b03a366Sstefano_zampini } 6731e6b0712SBarry Smith 6743b03a366Sstefano_zampini #undef __FUNCT__ 67582ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal_BDDC" 67682ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries) 6770c7d97c5SJed Brown { 6780c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 67956282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 6800c7d97c5SJed Brown PetscErrorCode ierr; 6810c7d97c5SJed Brown 6820c7d97c5SJed Brown PetscFunctionBegin; 68356282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 68456282151SStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 68556282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundariesLocal,&isequal);CHKERRQ(ierr); 68656282151SStefano Zampini } 687785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 688785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 6890c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 690785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = DirichletBoundaries; 69156282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 6920c7d97c5SJed Brown PetscFunctionReturn(0); 6930c7d97c5SJed Brown } 6940c7d97c5SJed Brown 6950c7d97c5SJed Brown #undef __FUNCT__ 69682ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal" 6979c0446d6SStefano Zampini /*@ 69882ba6b80SStefano Zampini PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering. 6999c0446d6SStefano Zampini 700785d1243SStefano Zampini Collective 70153cdbc3dSStefano Zampini 70253cdbc3dSStefano Zampini Input Parameters: 70353cdbc3dSStefano Zampini + pc - the preconditioning context 70482ba6b80SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering) 70553cdbc3dSStefano Zampini 70653cdbc3dSStefano Zampini Level: intermediate 70753cdbc3dSStefano Zampini 7089c0446d6SStefano Zampini Notes: 70953cdbc3dSStefano Zampini 7100f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundaries(), MatZeroRows(), MatZeroRowsColumns() 71153cdbc3dSStefano Zampini @*/ 71282ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries) 7130c7d97c5SJed Brown { 7140c7d97c5SJed Brown PetscErrorCode ierr; 7150c7d97c5SJed Brown 7160c7d97c5SJed Brown PetscFunctionBegin; 7170c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 7180c7d97c5SJed Brown PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 71982ba6b80SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 72082ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 7210c7d97c5SJed Brown PetscFunctionReturn(0); 7220c7d97c5SJed Brown } 7230c7d97c5SJed Brown 7240c7d97c5SJed Brown #undef __FUNCT__ 7250c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 72653cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 7270c7d97c5SJed Brown { 7280c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 72956282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 73053cdbc3dSStefano Zampini PetscErrorCode ierr; 7310c7d97c5SJed Brown 7320c7d97c5SJed Brown PetscFunctionBegin; 73356282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 73456282151SStefano Zampini if (pcbddc->NeumannBoundaries) { 73556282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundaries,&isequal);CHKERRQ(ierr); 73656282151SStefano Zampini } 737785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 738785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 73953cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 74036e030ebSStefano Zampini pcbddc->NeumannBoundaries = NeumannBoundaries; 74156282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7420c7d97c5SJed Brown PetscFunctionReturn(0); 7430c7d97c5SJed Brown } 7441e6b0712SBarry Smith 7450c7d97c5SJed Brown #undef __FUNCT__ 7460c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 74757527edcSJed Brown /*@ 74828509bceSStefano Zampini PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem. 74957527edcSJed Brown 750785d1243SStefano Zampini Collective 75157527edcSJed Brown 75257527edcSJed Brown Input Parameters: 75357527edcSJed Brown + pc - the preconditioning context 754785d1243SStefano Zampini - NeumannBoundaries - parallel IS defining the Neumann boundaries 75557527edcSJed Brown 75657527edcSJed Brown Level: intermediate 75757527edcSJed Brown 7580f202f7eSStefano Zampini Notes: 7590f202f7eSStefano Zampini Any process can list any global node 76057527edcSJed Brown 7610f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundariesLocal() 76257527edcSJed Brown @*/ 76353cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 7640c7d97c5SJed Brown { 7650c7d97c5SJed Brown PetscErrorCode ierr; 7660c7d97c5SJed Brown 7670c7d97c5SJed Brown PetscFunctionBegin; 7680c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 769674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 770785d1243SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 77153cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 77253cdbc3dSStefano Zampini PetscFunctionReturn(0); 77353cdbc3dSStefano Zampini } 7741e6b0712SBarry Smith 77553cdbc3dSStefano Zampini #undef __FUNCT__ 77682ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal_BDDC" 77782ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries) 7780c7d97c5SJed Brown { 7790c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 78056282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 7810c7d97c5SJed Brown PetscErrorCode ierr; 7820c7d97c5SJed Brown 7830c7d97c5SJed Brown PetscFunctionBegin; 78456282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 78556282151SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 78656282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundariesLocal,&isequal);CHKERRQ(ierr); 78756282151SStefano Zampini } 788785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 789785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 7900c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 791785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = NeumannBoundaries; 79256282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7930c7d97c5SJed Brown PetscFunctionReturn(0); 7940c7d97c5SJed Brown } 7950c7d97c5SJed Brown 7960c7d97c5SJed Brown #undef __FUNCT__ 79782ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal" 7980c7d97c5SJed Brown /*@ 79982ba6b80SStefano Zampini PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering. 8000c7d97c5SJed Brown 801785d1243SStefano Zampini Collective 8020c7d97c5SJed Brown 8030c7d97c5SJed Brown Input Parameters: 8040c7d97c5SJed Brown + pc - the preconditioning context 80582ba6b80SStefano Zampini - NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering) 8060c7d97c5SJed Brown 8070c7d97c5SJed Brown Level: intermediate 8080c7d97c5SJed Brown 8090c7d97c5SJed Brown Notes: 8100c7d97c5SJed Brown 8110f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundaries() 8120c7d97c5SJed Brown @*/ 81382ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries) 8140c7d97c5SJed Brown { 8150c7d97c5SJed Brown PetscErrorCode ierr; 8160c7d97c5SJed Brown 8170c7d97c5SJed Brown PetscFunctionBegin; 8180c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 8190c7d97c5SJed Brown PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 82082ba6b80SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 82182ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 82253cdbc3dSStefano Zampini PetscFunctionReturn(0); 82353cdbc3dSStefano Zampini } 82453cdbc3dSStefano Zampini 82553cdbc3dSStefano Zampini #undef __FUNCT__ 826da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC" 827da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 828da1bb401SStefano Zampini { 829da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 830da1bb401SStefano Zampini 831da1bb401SStefano Zampini PetscFunctionBegin; 832da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 833da1bb401SStefano Zampini PetscFunctionReturn(0); 834da1bb401SStefano Zampini } 8351e6b0712SBarry Smith 836da1bb401SStefano Zampini #undef __FUNCT__ 837da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries" 838da1bb401SStefano Zampini /*@ 839785d1243SStefano Zampini PCBDDCGetDirichletBoundaries - Get parallel IS for Dirichlet boundaries 840da1bb401SStefano Zampini 841785d1243SStefano Zampini Collective 842785d1243SStefano Zampini 843785d1243SStefano Zampini Input Parameters: 844785d1243SStefano Zampini . pc - the preconditioning context 845785d1243SStefano Zampini 846785d1243SStefano Zampini Output Parameters: 847785d1243SStefano Zampini . DirichletBoundaries - index set defining the Dirichlet boundaries 848785d1243SStefano Zampini 849785d1243SStefano Zampini Level: intermediate 850785d1243SStefano Zampini 8510f202f7eSStefano Zampini Notes: 8520f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetDirichletBoundaries 853785d1243SStefano Zampini 854785d1243SStefano Zampini .seealso: PCBDDC 855785d1243SStefano Zampini @*/ 856785d1243SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 857785d1243SStefano Zampini { 858785d1243SStefano Zampini PetscErrorCode ierr; 859785d1243SStefano Zampini 860785d1243SStefano Zampini PetscFunctionBegin; 861785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 862785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 863785d1243SStefano Zampini PetscFunctionReturn(0); 864785d1243SStefano Zampini } 865785d1243SStefano Zampini 866785d1243SStefano Zampini #undef __FUNCT__ 867785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal_BDDC" 868785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries) 869785d1243SStefano Zampini { 870785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 871785d1243SStefano Zampini 872785d1243SStefano Zampini PetscFunctionBegin; 873785d1243SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundariesLocal; 874785d1243SStefano Zampini PetscFunctionReturn(0); 875785d1243SStefano Zampini } 876785d1243SStefano Zampini 877785d1243SStefano Zampini #undef __FUNCT__ 87882ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal" 879da1bb401SStefano Zampini /*@ 88082ba6b80SStefano Zampini PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering) 881da1bb401SStefano Zampini 882785d1243SStefano Zampini Collective 883da1bb401SStefano Zampini 884da1bb401SStefano Zampini Input Parameters: 88528509bceSStefano Zampini . pc - the preconditioning context 886da1bb401SStefano Zampini 887da1bb401SStefano Zampini Output Parameters: 88828509bceSStefano Zampini . DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 889da1bb401SStefano Zampini 890da1bb401SStefano Zampini Level: intermediate 891da1bb401SStefano Zampini 892da1bb401SStefano Zampini Notes: 8930f202f7eSStefano Zampini The IS returned could be the same passed in earlier by the user (if provided with PCBDDCSetDirichletBoundariesLocal) or a global-to-local map of the global IS (if provided with PCBDDCSetDirichletBoundaries). 8940f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 895da1bb401SStefano Zampini 896da1bb401SStefano Zampini .seealso: PCBDDC 897da1bb401SStefano Zampini @*/ 89882ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries) 899da1bb401SStefano Zampini { 900da1bb401SStefano Zampini PetscErrorCode ierr; 901da1bb401SStefano Zampini 902da1bb401SStefano Zampini PetscFunctionBegin; 903da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 90482ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 905da1bb401SStefano Zampini PetscFunctionReturn(0); 906da1bb401SStefano Zampini } 9071e6b0712SBarry Smith 908da1bb401SStefano Zampini #undef __FUNCT__ 90953cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 91053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 91153cdbc3dSStefano Zampini { 91253cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 91353cdbc3dSStefano Zampini 91453cdbc3dSStefano Zampini PetscFunctionBegin; 91553cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 91653cdbc3dSStefano Zampini PetscFunctionReturn(0); 91753cdbc3dSStefano Zampini } 9181e6b0712SBarry Smith 91953cdbc3dSStefano Zampini #undef __FUNCT__ 92053cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 92153cdbc3dSStefano Zampini /*@ 922785d1243SStefano Zampini PCBDDCGetNeumannBoundaries - Get parallel IS for Neumann boundaries 92353cdbc3dSStefano Zampini 924785d1243SStefano Zampini Collective 925785d1243SStefano Zampini 926785d1243SStefano Zampini Input Parameters: 927785d1243SStefano Zampini . pc - the preconditioning context 928785d1243SStefano Zampini 929785d1243SStefano Zampini Output Parameters: 930785d1243SStefano Zampini . NeumannBoundaries - index set defining the Neumann boundaries 931785d1243SStefano Zampini 932785d1243SStefano Zampini Level: intermediate 933785d1243SStefano Zampini 9340f202f7eSStefano Zampini Notes: 9350f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetNeumannBoundaries 936785d1243SStefano Zampini 937785d1243SStefano Zampini .seealso: PCBDDC 938785d1243SStefano Zampini @*/ 939785d1243SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 940785d1243SStefano Zampini { 941785d1243SStefano Zampini PetscErrorCode ierr; 942785d1243SStefano Zampini 943785d1243SStefano Zampini PetscFunctionBegin; 944785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 945785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 946785d1243SStefano Zampini PetscFunctionReturn(0); 947785d1243SStefano Zampini } 948785d1243SStefano Zampini 949785d1243SStefano Zampini #undef __FUNCT__ 950785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal_BDDC" 951785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries) 952785d1243SStefano Zampini { 953785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 954785d1243SStefano Zampini 955785d1243SStefano Zampini PetscFunctionBegin; 956785d1243SStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundariesLocal; 957785d1243SStefano Zampini PetscFunctionReturn(0); 958785d1243SStefano Zampini } 959785d1243SStefano Zampini 960785d1243SStefano Zampini #undef __FUNCT__ 96182ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal" 96253cdbc3dSStefano Zampini /*@ 96382ba6b80SStefano Zampini PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering) 96453cdbc3dSStefano Zampini 965785d1243SStefano Zampini Collective 96653cdbc3dSStefano Zampini 96753cdbc3dSStefano Zampini Input Parameters: 96828509bceSStefano Zampini . pc - the preconditioning context 96953cdbc3dSStefano Zampini 97053cdbc3dSStefano Zampini Output Parameters: 97128509bceSStefano Zampini . NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 97253cdbc3dSStefano Zampini 97353cdbc3dSStefano Zampini Level: intermediate 97453cdbc3dSStefano Zampini 97553cdbc3dSStefano Zampini Notes: 9760f202f7eSStefano 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). 9770f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 97853cdbc3dSStefano Zampini 97953cdbc3dSStefano Zampini .seealso: PCBDDC 98053cdbc3dSStefano Zampini @*/ 98182ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries) 98253cdbc3dSStefano Zampini { 98353cdbc3dSStefano Zampini PetscErrorCode ierr; 98453cdbc3dSStefano Zampini 98553cdbc3dSStefano Zampini PetscFunctionBegin; 98653cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 98782ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 9880c7d97c5SJed Brown PetscFunctionReturn(0); 9890c7d97c5SJed Brown } 9901e6b0712SBarry Smith 99136e030ebSStefano Zampini #undef __FUNCT__ 992da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC" 9931a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 99436e030ebSStefano Zampini { 99536e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 996da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 99756282151SStefano Zampini PetscBool same_data = PETSC_FALSE; 998da1bb401SStefano Zampini PetscErrorCode ierr; 99936e030ebSStefano Zampini 100036e030ebSStefano Zampini PetscFunctionBegin; 10018687889aSStefano Zampini if (!nvtxs) { 100204194a47SStefano Zampini if (copymode == PETSC_OWN_POINTER) { 100304194a47SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 100404194a47SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 100504194a47SStefano Zampini } 10068687889aSStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 10078687889aSStefano Zampini PetscFunctionReturn(0); 10088687889aSStefano Zampini } 10092d505d7fSStefano Zampini if (mat_graph->nvtxs_csr == nvtxs && mat_graph->freecsr) { /* we own the data */ 101056282151SStefano Zampini if (mat_graph->xadj == xadj && mat_graph->adjncy == adjncy) same_data = PETSC_TRUE; 101156282151SStefano Zampini if (!same_data && mat_graph->xadj[nvtxs] == xadj[nvtxs]) { 10122d505d7fSStefano Zampini ierr = PetscMemcmp(xadj,mat_graph->xadj,(nvtxs+1)*sizeof(PetscInt),&same_data);CHKERRQ(ierr); 10132d505d7fSStefano Zampini if (same_data) { 10142d505d7fSStefano Zampini ierr = PetscMemcmp(adjncy,mat_graph->adjncy,xadj[nvtxs]*sizeof(PetscInt),&same_data);CHKERRQ(ierr); 10152d505d7fSStefano Zampini } 101656282151SStefano Zampini } 101756282151SStefano Zampini } 101856282151SStefano Zampini if (!same_data) { 1019674ae819SStefano Zampini /* free old CSR */ 1020674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 1021674ae819SStefano Zampini /* get CSR into graph structure */ 1022da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 1023854ce69bSBarry Smith ierr = PetscMalloc1(nvtxs+1,&mat_graph->xadj);CHKERRQ(ierr); 1024785e854fSJed Brown ierr = PetscMalloc1(xadj[nvtxs],&mat_graph->adjncy);CHKERRQ(ierr); 1025674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 1026674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 1027a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 1028da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 10291a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 10301a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 1031a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_TRUE; 1032a1dbd327SStefano Zampini } else if (copymode == PETSC_USE_POINTER) { 1033a1dbd327SStefano Zampini mat_graph->xadj = (PetscInt*)xadj; 1034a1dbd327SStefano Zampini mat_graph->adjncy = (PetscInt*)adjncy; 1035a1dbd327SStefano Zampini mat_graph->freecsr = PETSC_FALSE; 1036a1dbd327SStefano Zampini } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d",copymode); 1037575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 103856282151SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 103956282151SStefano Zampini } 104036e030ebSStefano Zampini PetscFunctionReturn(0); 104136e030ebSStefano Zampini } 10421e6b0712SBarry Smith 104336e030ebSStefano Zampini #undef __FUNCT__ 1044da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph" 104536e030ebSStefano Zampini /*@ 104654fffbccSStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local degrees of freedom. 104736e030ebSStefano Zampini 104836e030ebSStefano Zampini Not collective 104936e030ebSStefano Zampini 105036e030ebSStefano Zampini Input Parameters: 105154fffbccSStefano Zampini + pc - the preconditioning context. 105254fffbccSStefano Zampini . nvtxs - number of local vertices of the graph (i.e., the number of local dofs). 105354fffbccSStefano Zampini . xadj, adjncy - the connectivity of the dofs in CSR format. 105454fffbccSStefano Zampini - copymode - supported modes are PETSC_COPY_VALUES, PETSC_USE_POINTER or PETSC_OWN_POINTER. 105536e030ebSStefano Zampini 105636e030ebSStefano Zampini Level: intermediate 105736e030ebSStefano Zampini 105854fffbccSStefano Zampini Notes: A dof is considered connected with all local dofs if xadj[dof+1]-xadj[dof] == 1 and adjncy[xadj[dof]] is negative. 105936e030ebSStefano Zampini 106028509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode 106136e030ebSStefano Zampini @*/ 10621a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 106336e030ebSStefano Zampini { 1064575ad6abSStefano Zampini void (*f)(void) = 0; 106536e030ebSStefano Zampini PetscErrorCode ierr; 106636e030ebSStefano Zampini 106736e030ebSStefano Zampini PetscFunctionBegin; 106836e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 10698687889aSStefano Zampini if (nvtxs) { 1070674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 1071*1633d1f0SStefano Zampini if (xadj[nvtxs]) PetscValidIntPointer(adjncy,4); 10728687889aSStefano Zampini } 10731a83f524SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 1074575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 1075575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 1076575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 1077575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 1078575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 1079da1bb401SStefano Zampini } 108036e030ebSStefano Zampini PetscFunctionReturn(0); 108136e030ebSStefano Zampini } 10821e6b0712SBarry Smith 10839c0446d6SStefano Zampini #undef __FUNCT__ 108463602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal_BDDC" 108563602bcaSStefano Zampini static PetscErrorCode PCBDDCSetDofsSplittingLocal_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 108663602bcaSStefano Zampini { 108763602bcaSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 108863602bcaSStefano Zampini PetscInt i; 108956282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 109063602bcaSStefano Zampini PetscErrorCode ierr; 109163602bcaSStefano Zampini 109263602bcaSStefano Zampini PetscFunctionBegin; 109356282151SStefano Zampini if (pcbddc->n_ISForDofsLocal == n_is) { 109456282151SStefano Zampini for (i=0;i<n_is;i++) { 109556282151SStefano Zampini PetscBool isequalt; 109656282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofsLocal[i],&isequalt);CHKERRQ(ierr); 109756282151SStefano Zampini if (!isequalt) break; 109856282151SStefano Zampini } 109956282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 110056282151SStefano Zampini } 110156282151SStefano Zampini for (i=0;i<n_is;i++) { 110256282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 110356282151SStefano Zampini } 110463602bcaSStefano Zampini /* Destroy ISes if they were already set */ 110563602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 110663602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 110763602bcaSStefano Zampini } 110863602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 110963602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 111063602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 111163602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 111263602bcaSStefano Zampini } 111363602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 111463602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 111563602bcaSStefano Zampini /* allocate space then set */ 1116d02579f5SStefano Zampini if (n_is) { 1117d02579f5SStefano Zampini ierr = PetscMalloc1(n_is,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1118d02579f5SStefano Zampini } 111963602bcaSStefano Zampini for (i=0;i<n_is;i++) { 112063602bcaSStefano Zampini pcbddc->ISForDofsLocal[i] = ISForDofs[i]; 112163602bcaSStefano Zampini } 112263602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = n_is; 112363602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 112456282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 112563602bcaSStefano Zampini PetscFunctionReturn(0); 112663602bcaSStefano Zampini } 112763602bcaSStefano Zampini 112863602bcaSStefano Zampini #undef __FUNCT__ 112963602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal" 113063602bcaSStefano Zampini /*@ 113163602bcaSStefano Zampini PCBDDCSetDofsSplittingLocal - Set index sets defining fields of the local subdomain matrix 113263602bcaSStefano Zampini 113363602bcaSStefano Zampini Collective 113463602bcaSStefano Zampini 113563602bcaSStefano Zampini Input Parameters: 113663602bcaSStefano Zampini + pc - the preconditioning context 11370f202f7eSStefano Zampini . n_is - number of index sets defining the fields 11380f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in local ordering 113963602bcaSStefano Zampini 114063602bcaSStefano Zampini Level: intermediate 114163602bcaSStefano Zampini 11420f202f7eSStefano Zampini Notes: 11430f202f7eSStefano Zampini n_is should be the same among processes. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 114463602bcaSStefano Zampini 114563602bcaSStefano Zampini .seealso: PCBDDC 114663602bcaSStefano Zampini @*/ 114763602bcaSStefano Zampini PetscErrorCode PCBDDCSetDofsSplittingLocal(PC pc,PetscInt n_is, IS ISForDofs[]) 114863602bcaSStefano Zampini { 114963602bcaSStefano Zampini PetscInt i; 115063602bcaSStefano Zampini PetscErrorCode ierr; 115163602bcaSStefano Zampini 115263602bcaSStefano Zampini PetscFunctionBegin; 115363602bcaSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 115463602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 115563602bcaSStefano Zampini for (i=0;i<n_is;i++) { 115663602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 115763602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 115863602bcaSStefano Zampini } 1159e71e7a71SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplittingLocal_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 116063602bcaSStefano Zampini PetscFunctionReturn(0); 116163602bcaSStefano Zampini } 116263602bcaSStefano Zampini 116363602bcaSStefano Zampini #undef __FUNCT__ 11649c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 11659c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 11669c0446d6SStefano Zampini { 11679c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 11689c0446d6SStefano Zampini PetscInt i; 116956282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 11709c0446d6SStefano Zampini PetscErrorCode ierr; 11719c0446d6SStefano Zampini 11729c0446d6SStefano Zampini PetscFunctionBegin; 117356282151SStefano Zampini if (pcbddc->n_ISForDofs == n_is) { 117456282151SStefano Zampini for (i=0;i<n_is;i++) { 117556282151SStefano Zampini PetscBool isequalt; 117656282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofs[i],&isequalt);CHKERRQ(ierr); 117756282151SStefano Zampini if (!isequalt) break; 117856282151SStefano Zampini } 117956282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 118056282151SStefano Zampini } 118156282151SStefano Zampini for (i=0;i<n_is;i++) { 118256282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 118356282151SStefano Zampini } 1184da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 11859c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 11869c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 11879c0446d6SStefano Zampini } 1188d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 118963602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 119063602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 119163602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 119263602bcaSStefano Zampini } 119363602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 119463602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 1195da1bb401SStefano Zampini /* allocate space then set */ 1196d02579f5SStefano Zampini if (n_is) { 1197785e854fSJed Brown ierr = PetscMalloc1(n_is,&pcbddc->ISForDofs);CHKERRQ(ierr); 1198d02579f5SStefano Zampini } 11999c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 1200da1bb401SStefano Zampini pcbddc->ISForDofs[i] = ISForDofs[i]; 12019c0446d6SStefano Zampini } 12029c0446d6SStefano Zampini pcbddc->n_ISForDofs = n_is; 120363602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 120456282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 12059c0446d6SStefano Zampini PetscFunctionReturn(0); 12069c0446d6SStefano Zampini } 12071e6b0712SBarry Smith 12089c0446d6SStefano Zampini #undef __FUNCT__ 12099c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 12109c0446d6SStefano Zampini /*@ 121163602bcaSStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of the global matrix 12129c0446d6SStefano Zampini 121363602bcaSStefano Zampini Collective 12149c0446d6SStefano Zampini 12159c0446d6SStefano Zampini Input Parameters: 12169c0446d6SStefano Zampini + pc - the preconditioning context 12170f202f7eSStefano Zampini . n_is - number of index sets defining the fields 12180f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in global ordering 12199c0446d6SStefano Zampini 12209c0446d6SStefano Zampini Level: intermediate 12219c0446d6SStefano Zampini 12220f202f7eSStefano Zampini Notes: 12230f202f7eSStefano Zampini Any process can list any global node. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 12249c0446d6SStefano Zampini 12259c0446d6SStefano Zampini .seealso: PCBDDC 12269c0446d6SStefano Zampini @*/ 12279c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 12289c0446d6SStefano Zampini { 12292b510759SStefano Zampini PetscInt i; 12309c0446d6SStefano Zampini PetscErrorCode ierr; 12319c0446d6SStefano Zampini 12329c0446d6SStefano Zampini PetscFunctionBegin; 12339c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 123463602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 12352b510759SStefano Zampini for (i=0;i<n_is;i++) { 123663602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 123763602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 12382b510759SStefano Zampini } 12399c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 12409c0446d6SStefano Zampini PetscFunctionReturn(0); 12419c0446d6SStefano Zampini } 1242906d46d4SStefano Zampini 1243534831adSStefano Zampini #undef __FUNCT__ 1244534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC" 1245534831adSStefano Zampini /* 1246534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 1247534831adSStefano Zampini guess if a transformation of basis approach has been selected. 12489c0446d6SStefano Zampini 1249534831adSStefano Zampini Input Parameter: 1250534831adSStefano Zampini + pc - the preconditioner contex 1251534831adSStefano Zampini 1252534831adSStefano Zampini Application Interface Routine: PCPreSolve() 1253534831adSStefano Zampini 1254534831adSStefano Zampini Notes: 1255534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 1256534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1257534831adSStefano Zampini */ 1258534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1259534831adSStefano Zampini { 1260534831adSStefano Zampini PetscErrorCode ierr; 1261534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1262534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 12633972b0daSStefano Zampini Vec used_vec; 126427b6a85dSStefano Zampini PetscBool save_rhs = PETSC_TRUE, benign_correction_computed; 1265534831adSStefano Zampini 1266534831adSStefano Zampini PetscFunctionBegin; 12671f4df5f7SStefano Zampini /* if we are working with CG, one dirichlet solve can be avoided during Krylov iterations */ 126885c4d303SStefano Zampini if (ksp) { 12691f4df5f7SStefano Zampini PetscBool iscg, isgroppcg, ispipecg, ispipecgrr; 127085c4d303SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr); 127127b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPGROPPCG,&isgroppcg);CHKERRQ(ierr); 127227b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECG,&ispipecg);CHKERRQ(ierr); 1273f94e96cbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECGRR,&ispipecgrr);CHKERRQ(ierr); 12741f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static || (!iscg && !isgroppcg && !ispipecg && !ispipecgrr)) { 127585c4d303SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 127685c4d303SStefano Zampini } 127785c4d303SStefano Zampini } 1278fc17d649SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static) { 1279fc17d649SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 1280fc17d649SStefano Zampini } 12811f4df5f7SStefano Zampini 128285c4d303SStefano Zampini /* Creates parallel work vectors used in presolve */ 128362a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 128462a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 128562a6ff1dSStefano Zampini } 128662a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 128762a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 128862a6ff1dSStefano Zampini } 12898d00608fSStefano Zampini 129027b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_FALSE; 12913972b0daSStefano Zampini if (x) { 12923972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 12933972b0daSStefano Zampini used_vec = x; 12948d00608fSStefano Zampini } else { /* it can only happen when calling PCBDDCMatFETIDPGetRHS */ 12953972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 12963972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 12973972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 129827b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 1299266e20e9SStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 1300266e20e9SStefano Zampini save_rhs = PETSC_FALSE; 1301266e20e9SStefano Zampini pcbddc->eliminate_dirdofs = PETSC_TRUE; 13023972b0daSStefano Zampini } 13038efcfb23SStefano Zampini 13048efcfb23SStefano Zampini /* hack into ksp data structure since PCPreSolve comes earlier than setting to zero the guess in src/ksp/ksp/interface/itfunc.c */ 13053972b0daSStefano Zampini if (ksp) { 1306a0cb1b98SStefano Zampini /* store the flag for the initial guess since it will be restored back during PCPostSolve_BDDC */ 13078efcfb23SStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 13088efcfb23SStefano Zampini if (!pcbddc->ksp_guess_nonzero) { 13093972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 13103972b0daSStefano Zampini } 13113972b0daSStefano Zampini } 13123308cffdSStefano Zampini 13138d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 13143972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 131570c64980SStefano Zampini if (rhs && pcbddc->eliminate_dirdofs) { 13163975b054SStefano Zampini IS dirIS = NULL; 13173975b054SStefano Zampini 1318a07ea27aSStefano Zampini /* DirichletBoundariesLocal may not be consistent among neighbours; gets a dirichlet dofs IS from graph (may be cached) */ 13193975b054SStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 13203975b054SStefano Zampini if (dirIS) { 1321906d46d4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1322785d1243SStefano Zampini PetscInt dirsize,i,*is_indices; 13232b095fd8SStefano Zampini PetscScalar *array_x; 13242b095fd8SStefano Zampini const PetscScalar *array_diagonal; 1325785d1243SStefano Zampini 13263972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 13273972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 1328e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1329e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1330e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1331e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 133282ba6b80SStefano Zampini ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr); 13333972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 13342b095fd8SStefano Zampini ierr = VecGetArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 13353972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 13362fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 13373972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 13382b095fd8SStefano Zampini ierr = VecRestoreArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 13393972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 1340e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1341e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13428d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 13431b968477SStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 13448efcfb23SStefano Zampini } 1345a07ea27aSStefano Zampini } 1346b76ba322SStefano Zampini 13478efcfb23SStefano Zampini /* remove the computed solution or the initial guess from the rhs */ 13488d00608fSStefano Zampini if (pcbddc->rhs_change || (ksp && pcbddc->ksp_guess_nonzero) ) { 134927b6a85dSStefano Zampini /* save the original rhs */ 135027b6a85dSStefano Zampini if (save_rhs) { 135127b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 135227b6a85dSStefano Zampini save_rhs = PETSC_FALSE; 13538d00608fSStefano Zampini } 13548d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 13553972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 135627b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,used_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 13573972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 13588efcfb23SStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 135927b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 13607acc28cbSStefano Zampini if (ksp) { 13617acc28cbSStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_FALSE);CHKERRQ(ierr); 13627acc28cbSStefano Zampini } 13633308cffdSStefano Zampini } 13648efcfb23SStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 1365b76ba322SStefano Zampini 1366fc17d649SStefano Zampini /* compute initial vector in benign space if needed 136727b6a85dSStefano Zampini and remove non-benign solution from the rhs */ 136827b6a85dSStefano Zampini benign_correction_computed = PETSC_FALSE; 136927b6a85dSStefano Zampini if (rhs && pcbddc->benign_compute_correction && pcbddc->benign_have_null) { 13701f4df5f7SStefano Zampini /* compute u^*_h using ideas similar to those in Xuemin Tu's PhD thesis (see Section 4.8.1) 13711f4df5f7SStefano Zampini Recursively apply BDDC in the multilevel case */ 13720369aaf7SStefano Zampini if (!pcbddc->benign_vec) { 13730369aaf7SStefano Zampini ierr = VecDuplicate(rhs,&pcbddc->benign_vec);CHKERRQ(ierr); 13740369aaf7SStefano Zampini } 13754fee134fSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_TRUE; 137627b6a85dSStefano Zampini if (!pcbddc->benign_skip_correction) { 13771dd7afcfSStefano Zampini ierr = PCApply_BDDC(pc,rhs,pcbddc->benign_vec);CHKERRQ(ierr); 13783bca92a6SStefano Zampini benign_correction_computed = PETSC_TRUE; 13791f4df5f7SStefano Zampini if (pcbddc->temp_solution_used) { 13801f4df5f7SStefano Zampini ierr = VecAXPY(pcbddc->temp_solution,1.0,pcbddc->benign_vec);CHKERRQ(ierr); 13811f4df5f7SStefano Zampini } 13821f4df5f7SStefano Zampini ierr = VecScale(pcbddc->benign_vec,-1.0);CHKERRQ(ierr); 138327b6a85dSStefano Zampini /* store the original rhs if not done earlier */ 138427b6a85dSStefano Zampini if (save_rhs) { 138527b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 138692e3dcfbSStefano Zampini } 138727b6a85dSStefano Zampini if (pcbddc->rhs_change) { 13880369aaf7SStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,rhs,rhs);CHKERRQ(ierr); 138927b6a85dSStefano Zampini } else { 139027b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 139127b6a85dSStefano Zampini } 13920369aaf7SStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 139327b6a85dSStefano Zampini } 139427b6a85dSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_FALSE; 13950369aaf7SStefano Zampini } 13962d4c4fecSStefano Zampini 13972d4c4fecSStefano Zampini /* dbg output */ 1398a198735bSStefano Zampini if (pcbddc->dbg_flag && benign_correction_computed) { 13991f4df5f7SStefano Zampini Vec v; 14001f4df5f7SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&v);CHKERRQ(ierr); 14011f4df5f7SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,v);CHKERRQ(ierr); 14021f4df5f7SStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,v,PETSC_TRUE);CHKERRQ(ierr); 1403a198735bSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"LEVEL %d: is the correction benign?\n",pcbddc->current_level);CHKERRQ(ierr); 14042d4c4fecSStefano Zampini ierr = PetscScalarView(pcbddc->benign_n,pcbddc->benign_p0,PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pc)));CHKERRQ(ierr); 14051f4df5f7SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 14061f4df5f7SStefano Zampini } 14070369aaf7SStefano Zampini 14080369aaf7SStefano Zampini /* set initial guess if using PCG */ 14098ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 14100369aaf7SStefano Zampini if (x && pcbddc->use_exact_dirichlet_trick) { 14110369aaf7SStefano Zampini ierr = VecSet(x,0.0);CHKERRQ(ierr); 14121dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 141327b6a85dSStefano Zampini if (benign_correction_computed) { /* we have already saved the changed rhs */ 14141dd7afcfSStefano Zampini ierr = VecLockPop(pcis->vec1_global);CHKERRQ(ierr); 14151dd7afcfSStefano Zampini } else { 14161dd7afcfSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,pcis->vec1_global);CHKERRQ(ierr); 14171dd7afcfSStefano Zampini } 14181dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14191dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14201dd7afcfSStefano Zampini } else { 14210369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14220369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14231dd7afcfSStefano Zampini } 14240369aaf7SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 14251dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 14261dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.);CHKERRQ(ierr); 14271dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 14281dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 14291dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x);CHKERRQ(ierr); 14301dd7afcfSStefano Zampini } else { 14310369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 14320369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 14331dd7afcfSStefano Zampini } 14340369aaf7SStefano Zampini if (ksp) { 14350369aaf7SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 14360369aaf7SStefano Zampini } 14378ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_TRUE; 1438266e20e9SStefano Zampini } else if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior && benign_correction_computed && pcbddc->use_exact_dirichlet_trick) { 1439266e20e9SStefano Zampini ierr = VecLockPop(pcis->vec1_global);CHKERRQ(ierr); 14400369aaf7SStefano Zampini } 1441534831adSStefano Zampini PetscFunctionReturn(0); 1442534831adSStefano Zampini } 1443906d46d4SStefano Zampini 1444534831adSStefano Zampini #undef __FUNCT__ 1445534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC" 1446534831adSStefano Zampini /* 1447534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 1448534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 1449534831adSStefano Zampini 1450534831adSStefano Zampini Input Parameter: 1451534831adSStefano Zampini + pc - the preconditioner contex 1452534831adSStefano Zampini 1453534831adSStefano Zampini Application Interface Routine: PCPostSolve() 1454534831adSStefano Zampini 1455534831adSStefano Zampini Notes: 1456534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 1457534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1458534831adSStefano Zampini */ 1459534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1460534831adSStefano Zampini { 1461534831adSStefano Zampini PetscErrorCode ierr; 1462534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1463534831adSStefano Zampini 1464534831adSStefano Zampini PetscFunctionBegin; 14653972b0daSStefano Zampini /* add solution removed in presolve */ 14666bcfc461SStefano Zampini if (x && pcbddc->rhs_change) { 146727b6a85dSStefano Zampini if (pcbddc->temp_solution_used) { 14683425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 146927b6a85dSStefano Zampini } else if (pcbddc->benign_compute_correction) { 147027b6a85dSStefano Zampini ierr = VecAXPY(x,-1.0,pcbddc->benign_vec);CHKERRQ(ierr); 14713425bc38SStefano Zampini } 147227b6a85dSStefano Zampini } 147327b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_FALSE; 147427b6a85dSStefano Zampini 1475266e20e9SStefano Zampini /* restore rhs to its original state (not needed for FETI-DP) */ 14768d00608fSStefano Zampini if (rhs && pcbddc->rhs_change) { 147727b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 1478fb223d50SStefano Zampini } 14798d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 14808efcfb23SStefano Zampini /* restore ksp guess state */ 14818efcfb23SStefano Zampini if (ksp) { 14828efcfb23SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 14838efcfb23SStefano Zampini } 14848ae0ca82SStefano Zampini /* reset flag for exact dirichlet trick */ 14858ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 1486534831adSStefano Zampini PetscFunctionReturn(0); 1487534831adSStefano Zampini } 148853cdbc3dSStefano Zampini #undef __FUNCT__ 148953cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 14900c7d97c5SJed Brown /* 14910c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 14920c7d97c5SJed Brown by setting data structures and options. 14930c7d97c5SJed Brown 14940c7d97c5SJed Brown Input Parameter: 149553cdbc3dSStefano Zampini + pc - the preconditioner context 14960c7d97c5SJed Brown 14970c7d97c5SJed Brown Application Interface Routine: PCSetUp() 14980c7d97c5SJed Brown 14990c7d97c5SJed Brown Notes: 15000c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 15010c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 15020c7d97c5SJed Brown */ 150353cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 15040c7d97c5SJed Brown { 15050c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1506c703fcc7SStefano Zampini PCBDDCSubSchurs sub_schurs; 15075e8657edSStefano Zampini Mat_IS* matis; 150808122e43SStefano Zampini MatNullSpace nearnullspace; 1509c9ed8603SStefano Zampini IS zerodiag = NULL; 151091e8d312SStefano Zampini PetscInt nrows,ncols; 1511c703fcc7SStefano Zampini PetscBool computesubschurs; 15128de1fae6SStefano Zampini PetscBool computeconstraintsmatrix; 15135e8657edSStefano Zampini PetscBool new_nearnullspace_provided,ismatis; 1514c703fcc7SStefano Zampini PetscErrorCode ierr; 15150c7d97c5SJed Brown 15160c7d97c5SJed Brown PetscFunctionBegin; 15175e8657edSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATIS,&ismatis);CHKERRQ(ierr); 15186c4ed002SBarry Smith if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner requires matrix of type MATIS"); 151991e8d312SStefano Zampini ierr = MatGetSize(pc->pmat,&nrows,&ncols);CHKERRQ(ierr); 15206c4ed002SBarry Smith if (nrows != ncols) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PCBDDC preconditioner requires a square preconditioning matrix"); 15215e8657edSStefano Zampini matis = (Mat_IS*)pc->pmat->data; 1522f4ddd8eeSStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other future nonoverlapping preconditioners */ 15233b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 152471582508SStefano Zampini Also, BDDC builds its own KSP for the Dirichlet problem */ 1525c703fcc7SStefano Zampini if (pc->setupcalled && pc->flag != SAME_NONZERO_PATTERN) pcbddc->recompute_topography = PETSC_TRUE; 1526c83e1ba7SStefano Zampini if (pcbddc->recompute_topography) { 1527c83e1ba7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 1528c83e1ba7SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1529c83e1ba7SStefano Zampini } else { 15308de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_FALSE; 1531c83e1ba7SStefano Zampini } 1532b087196eSStefano Zampini 1533b087196eSStefano Zampini /* check parameters' compatibility */ 1534b7ab4a40SStefano Zampini if (!pcbddc->use_deluxe_scaling) pcbddc->deluxe_zerorows = PETSC_FALSE; 15359d54b7f4SStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_threshold > 0.0); 1536bf3a8328SStefano Zampini pcbddc->adaptive_userdefined = (PetscBool)(pcbddc->adaptive_selection && pcbddc->adaptive_userdefined); 1537862806e4SStefano Zampini if (pcbddc->adaptive_selection) pcbddc->use_faces = PETSC_TRUE; 1538862806e4SStefano Zampini 15395a95e1ceSStefano Zampini computesubschurs = (PetscBool)(pcbddc->adaptive_selection || pcbddc->use_deluxe_scaling); 154016909a7fSStefano Zampini if (pcbddc->switch_static) { 154116909a7fSStefano Zampini PetscBool ismatis; 154216909a7fSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->mat,MATIS,&ismatis);CHKERRQ(ierr); 154316909a7fSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"When the static switch is one, the iteration matrix should be of type MATIS"); 154416909a7fSStefano Zampini } 154516909a7fSStefano Zampini 154671582508SStefano Zampini /* activate all connected components if the netflux has been requested */ 1547bb05f991SStefano Zampini if (pcbddc->compute_nonetflux) { 1548bb05f991SStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 1549bb05f991SStefano Zampini pcbddc->use_edges = PETSC_TRUE; 1550bb05f991SStefano Zampini pcbddc->use_faces = PETSC_TRUE; 1551bb05f991SStefano Zampini } 1552bb05f991SStefano Zampini 1553f4ddd8eeSStefano Zampini /* Get stdout for dbg */ 155470cf5478SStefano Zampini if (pcbddc->dbg_flag) { 155570cf5478SStefano Zampini if (!pcbddc->dbg_viewer) { 155658a03d70SStefano Zampini pcbddc->dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pc)); 15571575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 1558f4ddd8eeSStefano Zampini } 155958a03d70SStefano Zampini ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1560f4ddd8eeSStefano Zampini } 1561f4ddd8eeSStefano Zampini 1562c703fcc7SStefano Zampini /* process topology information */ 156371582508SStefano Zampini if (pcbddc->recompute_topography) { 156471582508SStefano Zampini ierr = PCBDDCComputeLocalTopologyInfo(pc);CHKERRQ(ierr); 1565c83e1ba7SStefano Zampini /* detect local disconnected subdomains if requested (use matis->A) */ 1566c83e1ba7SStefano Zampini if (pcbddc->detect_disconnected) { 1567c83e1ba7SStefano Zampini PetscInt i; 1568c83e1ba7SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 1569c83e1ba7SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 1570c83e1ba7SStefano Zampini } 1571c83e1ba7SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 1572c83e1ba7SStefano Zampini ierr = MatDetectDisconnectedComponents(matis->A,PETSC_FALSE,&pcbddc->n_local_subs,&pcbddc->local_subs);CHKERRQ(ierr); 1573c83e1ba7SStefano Zampini } 1574c703fcc7SStefano Zampini if (pcbddc->discretegradient) { 1575a13144ffSStefano Zampini ierr = PCBDDCNedelecSupport(pc);CHKERRQ(ierr); 1576a13144ffSStefano Zampini } 1577c703fcc7SStefano Zampini } 1578a13144ffSStefano Zampini 1579c703fcc7SStefano Zampini /* change basis if requested by the user */ 15805e8657edSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 15815e8657edSStefano Zampini /* use_change_of_basis flag is used to automatically compute a change of basis from constraints */ 15825e8657edSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 15835e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 15845e8657edSStefano Zampini } else { 1585b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 15865e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 15875e8657edSStefano Zampini pcbddc->local_mat = matis->A; 1588d16cbb6bSStefano Zampini } 1589d16cbb6bSStefano Zampini 15904f1b2e48SStefano Zampini /* 1591c703fcc7SStefano Zampini Compute change of basis on local pressures (aka zerodiag dofs) with the benign trick 15924f1b2e48SStefano Zampini This should come earlier then PCISSetUp for extracting the correct subdomain matrices 15934f1b2e48SStefano Zampini */ 15941dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 1595d16cbb6bSStefano Zampini if (pcbddc->benign_saddle_point) { 15969f47a83aSStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 15979f47a83aSStefano Zampini 159805b28244SStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->use_change_of_basis || !computesubschurs) pcbddc->benign_change_explicit = PETSC_TRUE; 1599669cc0f4SStefano Zampini /* detect local saddle point and change the basis in pcbddc->local_mat (TODO: reuse case) */ 1600339f8db1SStefano Zampini ierr = PCBDDCBenignDetectSaddlePoint(pc,&zerodiag);CHKERRQ(ierr); 1601a3df083aSStefano Zampini /* pop B0 mat from local mat */ 1602c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 16031dd7afcfSStefano Zampini /* give pcis a hint to not reuse submatrices during PCISCreate */ 16041dd7afcfSStefano Zampini if (pc->flag == SAME_NONZERO_PATTERN && pcis->reusesubmatrices == PETSC_TRUE) { 16051dd7afcfSStefano Zampini if (pcbddc->benign_n && (pcbddc->benign_change_explicit || pcbddc->dbg_flag)) { 16061dd7afcfSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 16071dd7afcfSStefano Zampini } else { 1608a3df083aSStefano Zampini pcis->reusesubmatrices = PETSC_TRUE; 16091dd7afcfSStefano Zampini } 1610a3df083aSStefano Zampini } else { 16119f47a83aSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 1612674ae819SStefano Zampini } 1613a3df083aSStefano Zampini } 161427b6a85dSStefano Zampini 1615c703fcc7SStefano Zampini /* propagate relevant information -> TODO remove*/ 16164f1b2e48SStefano Zampini #if !defined(PETSC_USE_COMPLEX) /* workaround for reals */ 16173301b35fSStefano Zampini if (matis->A->symmetric_set) { 16183301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 16193301b35fSStefano Zampini } 1620e496cd5dSStefano Zampini #endif 162106a4e24aSStefano Zampini if (matis->A->symmetric_set) { 162206a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 162306a4e24aSStefano Zampini } 162406a4e24aSStefano Zampini if (matis->A->spd_set) { 162506a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SPD,matis->A->spd);CHKERRQ(ierr); 162606a4e24aSStefano Zampini } 1627e496cd5dSStefano Zampini 16285e8657edSStefano Zampini /* Set up all the "iterative substructuring" common block without computing solvers */ 16295e8657edSStefano Zampini { 16305e8657edSStefano Zampini Mat temp_mat; 16315e8657edSStefano Zampini 16325e8657edSStefano Zampini temp_mat = matis->A; 16335e8657edSStefano Zampini matis->A = pcbddc->local_mat; 16345e8657edSStefano Zampini ierr = PCISSetUp(pc,PETSC_FALSE);CHKERRQ(ierr); 16355e8657edSStefano Zampini pcbddc->local_mat = matis->A; 16365e8657edSStefano Zampini matis->A = temp_mat; 16375e8657edSStefano Zampini } 1638684f6988SStefano Zampini 163981d14e9dSStefano Zampini /* Analyze interface */ 164064ac59b8SStefano Zampini if (!pcbddc->graphanalyzed) { 1641674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 16428de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1643345ecf6cSStefano Zampini if (pcbddc->adaptive_selection && !pcbddc->use_deluxe_scaling && !pcbddc->mat_graph->twodim) { 1644345ecf6cSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute the adaptive primal space for a problem with 3D edges without deluxe scaling"); 1645345ecf6cSStefano Zampini } 1646a198735bSStefano Zampini if (pcbddc->compute_nonetflux) { 1647669cc0f4SStefano Zampini MatNullSpace nnfnnsp; 1648669cc0f4SStefano Zampini 16498ae0ca82SStefano Zampini ierr = PCBDDCComputeNoNetFlux(pc->pmat,pcbddc->divudotp,pcbddc->divudotp_trans,pcbddc->divudotp_vl2l,pcbddc->mat_graph,&nnfnnsp);CHKERRQ(ierr); 165071582508SStefano Zampini /* TODO what if a nearnullspace is already attached? */ 1651669cc0f4SStefano Zampini ierr = MatSetNearNullSpace(pc->pmat,nnfnnsp);CHKERRQ(ierr); 1652669cc0f4SStefano Zampini ierr = MatNullSpaceDestroy(&nnfnnsp);CHKERRQ(ierr); 1653669cc0f4SStefano Zampini } 1654674ae819SStefano Zampini } 1655fb8d54d4SStefano Zampini 16565408967cSStefano Zampini /* check existence of a divergence free extension, i.e. 16575408967cSStefano Zampini b(v_I,p_0) = 0 for all v_I (raise error if not). 16585408967cSStefano Zampini Also, check that PCBDDCBenignGetOrSetP0 works */ 16595408967cSStefano Zampini #if defined(PETSC_USE_DEBUG) 166009f581a4SStefano Zampini if (pcbddc->benign_saddle_point) { 16615408967cSStefano Zampini ierr = PCBDDCBenignCheck(pc,zerodiag);CHKERRQ(ierr); 166209f581a4SStefano Zampini } 16635408967cSStefano Zampini #endif 16644f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 166506f24817SStefano Zampini 1666b96c3477SStefano Zampini /* Setup local dirichlet solver ksp_D and sub_schurs solvers */ 1667c703fcc7SStefano Zampini if (computesubschurs && pcbddc->recompute_topography) { 166808122e43SStefano Zampini ierr = PCBDDCInitSubSchurs(pc);CHKERRQ(ierr); 1669b1b3d7a2SStefano Zampini } 16709d54b7f4SStefano Zampini /* SetUp Scaling operator (scaling matrices could be needed in SubSchursSetUp)*/ 16719d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) { 16729d54b7f4SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 16739d54b7f4SStefano Zampini } 1674c703fcc7SStefano Zampini 1675c703fcc7SStefano Zampini /* finish setup solvers and do adaptive selection of constraints */ 1676b334f244SStefano Zampini sub_schurs = pcbddc->sub_schurs; 1677b334f244SStefano Zampini if (sub_schurs && sub_schurs->schur_explicit) { 16782070dbb6SStefano Zampini if (computesubschurs) { 167908122e43SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 16802070dbb6SStefano Zampini } 1681d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 1682d5574798SStefano Zampini } else { 1683d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 16842070dbb6SStefano Zampini if (computesubschurs) { 1685d5574798SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 1686d5574798SStefano Zampini } 16872070dbb6SStefano Zampini } 168808122e43SStefano Zampini if (pcbddc->adaptive_selection) { 168908122e43SStefano Zampini ierr = PCBDDCAdaptiveSelection(pc);CHKERRQ(ierr); 16908de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1691b7eb3628SStefano Zampini } 1692684f6988SStefano Zampini 1693f4ddd8eeSStefano Zampini /* infer if NullSpace object attached to Mat via MatSetNearNullSpace has changed */ 1694fb8d54d4SStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1695f4ddd8eeSStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullspace);CHKERRQ(ierr); 1696f4ddd8eeSStefano Zampini if (pcbddc->onearnullspace) { /* already used nearnullspace */ 1697f4ddd8eeSStefano Zampini if (!nearnullspace) { /* near null space attached to mat has been destroyed */ 1698f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1699f4ddd8eeSStefano Zampini } else { 1700f4ddd8eeSStefano Zampini /* determine if the two nullspaces are different (should be lightweight) */ 1701f4ddd8eeSStefano Zampini if (nearnullspace != pcbddc->onearnullspace) { 1702f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1703165b64e2SStefano Zampini } else { /* maybe the user has changed the content of the nearnullspace so check vectors ObjectStateId */ 1704f4ddd8eeSStefano Zampini PetscInt i; 1705165b64e2SStefano Zampini const Vec *nearnullvecs; 1706165b64e2SStefano Zampini PetscObjectState state; 1707165b64e2SStefano Zampini PetscInt nnsp_size; 1708165b64e2SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullspace,NULL,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1709f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1710f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&state);CHKERRQ(ierr); 1711165b64e2SStefano Zampini if (pcbddc->onearnullvecs_state[i] != state) { 1712f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1713f4ddd8eeSStefano Zampini break; 1714f4ddd8eeSStefano Zampini } 1715f4ddd8eeSStefano Zampini } 1716f4ddd8eeSStefano Zampini } 1717f4ddd8eeSStefano Zampini } 1718f4ddd8eeSStefano Zampini } else { 1719f4ddd8eeSStefano Zampini if (!nearnullspace) { /* both nearnullspaces are null */ 1720f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1721f4ddd8eeSStefano Zampini } else { /* nearnullspace attached later */ 1722f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1723f4ddd8eeSStefano Zampini } 1724f4ddd8eeSStefano Zampini } 1725f4ddd8eeSStefano Zampini 1726f4ddd8eeSStefano Zampini /* Setup constraints and related work vectors */ 1727727cdba6SStefano Zampini /* reset primal space flags */ 1728f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 1729727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 17308de1fae6SStefano Zampini if (computeconstraintsmatrix || new_nearnullspace_provided) { 1731727cdba6SStefano Zampini /* It also sets the primal space flags */ 1732674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 17339543d0ffSStefano Zampini } 1734e7b262bdSStefano Zampini /* Allocate needed local vectors (which depends on quantities defined during ConstraintsSetUp) */ 1735f4ddd8eeSStefano Zampini ierr = PCBDDCSetUpLocalWorkVectors(pc);CHKERRQ(ierr); 17365e8657edSStefano Zampini 17375e8657edSStefano Zampini if (pcbddc->use_change_of_basis) { 17385e8657edSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 17395e8657edSStefano Zampini 17405e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 17414f1b2e48SStefano Zampini if (pcbddc->benign_change) { 17421dd7afcfSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 1743c263805aSStefano Zampini /* pop B0 from pcbddc->local_mat */ 1744c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 1745c263805aSStefano Zampini } 17465e8657edSStefano Zampini /* get submatrices */ 17475e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 17485e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 17495e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 17505e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 17515e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 17525e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 17533975b054SStefano Zampini /* set flag in pcis to not reuse submatrices during PCISCreate */ 17543975b054SStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 17559c6a02ceSStefano Zampini } else if (!pcbddc->user_ChangeOfBasisMatrix && !pcbddc->benign_change) { 1756b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 17575e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 17585e8657edSStefano Zampini pcbddc->local_mat = matis->A; 17595e8657edSStefano Zampini } 1760b96c3477SStefano Zampini /* SetUp coarse and local Neumann solvers */ 176199cc7994SStefano Zampini ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr); 1762b96c3477SStefano Zampini /* SetUp Scaling operator */ 17639d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1764674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 17650c7d97c5SJed Brown } 1766c703fcc7SStefano Zampini 17671dd7afcfSStefano Zampini /* mark topography as done */ 176856282151SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 17690369aaf7SStefano Zampini 17701dd7afcfSStefano Zampini /* wrap pcis->A_IB and pcis->A_BI if we did not change explicitly the variables on the pressures */ 17711dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_FALSE);CHKERRQ(ierr); 17721dd7afcfSStefano Zampini 177358a03d70SStefano Zampini if (pcbddc->dbg_flag) { 177458a03d70SStefano Zampini ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 17752b510759SStefano Zampini } 17760c7d97c5SJed Brown PetscFunctionReturn(0); 17770c7d97c5SJed Brown } 17780c7d97c5SJed Brown 17790c7d97c5SJed Brown /* 178050efa1b5SStefano Zampini PCApply_BDDC - Applies the BDDC operator to a vector. 17810c7d97c5SJed Brown 17820c7d97c5SJed Brown Input Parameters: 17830f202f7eSStefano Zampini + pc - the preconditioner context 17840f202f7eSStefano Zampini - r - input vector (global) 17850c7d97c5SJed Brown 17860c7d97c5SJed Brown Output Parameter: 17870c7d97c5SJed Brown . z - output vector (global) 17880c7d97c5SJed Brown 17890c7d97c5SJed Brown Application Interface Routine: PCApply() 17900c7d97c5SJed Brown */ 17910c7d97c5SJed Brown #undef __FUNCT__ 17920c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 179353cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 17940c7d97c5SJed Brown { 17950c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 17960c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1797b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 17980c7d97c5SJed Brown PetscErrorCode ierr; 17993b03a366Sstefano_zampini const PetscScalar one = 1.0; 18003b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 18012617d88aSStefano Zampini const PetscScalar zero = 0.0; 18020c7d97c5SJed Brown 18030c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 18040c7d97c5SJed Brown NN interface preconditioner changed to BDDC 1805b097fa66SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static == PETSC_TRUE) */ 18060c7d97c5SJed Brown 18070c7d97c5SJed Brown PetscFunctionBegin; 18081dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 18091dd7afcfSStefano Zampini Vec swap; 181027b6a85dSStefano Zampini 181127b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 18121dd7afcfSStefano Zampini swap = pcbddc->work_change; 18131dd7afcfSStefano Zampini pcbddc->work_change = r; 18141dd7afcfSStefano Zampini r = swap; 18151dd7afcfSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 18168ae0ca82SStefano Zampini if (pcbddc->benign_apply_coarse_only && pcbddc->exact_dirichlet_trick_app && pcbddc->change_interior) { 18171dd7afcfSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 18181dd7afcfSStefano Zampini ierr = VecLockPush(pcis->vec1_global);CHKERRQ(ierr); 18191dd7afcfSStefano Zampini } 18201dd7afcfSStefano Zampini } 182127b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 1822015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1823efc2fbd9SStefano Zampini } 18248ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 1825b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 18260c7d97c5SJed Brown /* First Dirichlet solve */ 18270c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18280c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18290c7d97c5SJed Brown /* 18300c7d97c5SJed Brown Assembling right hand side for BDDC operator 1831b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 1832674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 18330c7d97c5SJed Brown */ 1834b097fa66SStefano Zampini if (n_D) { 1835b097fa66SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 18360c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 183716909a7fSStefano Zampini if (pcbddc->switch_static) { 183816909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 183916909a7fSStefano Zampini 184016909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 184116909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 184216909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 184316909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 184416909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 184516909a7fSStefano Zampini } else { 184616909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 184716909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 184816909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 184916909a7fSStefano Zampini } 185016909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 185116909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 185216909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 185316909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 185416909a7fSStefano Zampini } else { 1855b097fa66SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 185616909a7fSStefano Zampini } 1857b097fa66SStefano Zampini } else { 1858b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1859b097fa66SStefano Zampini } 18600c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 18610c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1862674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 1863b76ba322SStefano Zampini } else { 18644fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 1865674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 1866b76ba322SStefano Zampini } 18674fee134fSStefano Zampini } 1868b76ba322SStefano Zampini 18692617d88aSStefano Zampini /* Apply interface preconditioner 18702617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1871dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 18722617d88aSStefano Zampini 1873674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 1874674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 18750c7d97c5SJed Brown 18763b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 18770c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18780c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1879b097fa66SStefano Zampini if (n_B) { 188016909a7fSStefano Zampini if (pcbddc->switch_static) { 188116909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 188216909a7fSStefano Zampini 188316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 188416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 188516909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 188616909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 188716909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 188816909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 188916909a7fSStefano Zampini } else { 189016909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 189116909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 189216909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 189316909a7fSStefano Zampini } 189416909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 189516909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 189616909a7fSStefano Zampini } else { 18970c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 189816909a7fSStefano Zampini } 189916909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 190016909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 190116909a7fSStefano Zampini 190216909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 190316909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 190416909a7fSStefano Zampini } else { 190516909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 190616909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 190716909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 190816909a7fSStefano Zampini } 1909b097fa66SStefano Zampini } 1910df187020SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 1911efc2fbd9SStefano Zampini 19128ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 1913b097fa66SStefano Zampini if (pcbddc->switch_static) { 1914b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 1915b097fa66SStefano Zampini } else { 1916b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 1917b097fa66SStefano Zampini } 19180c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19190c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1920b097fa66SStefano Zampini } else { 1921b097fa66SStefano Zampini if (pcbddc->switch_static) { 1922b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 1923b097fa66SStefano Zampini } else { 1924b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 1925b097fa66SStefano Zampini } 1926b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1927b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1928b097fa66SStefano Zampini } 192927b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 19301dd7afcfSStefano Zampini if (pcbddc->benign_apply_coarse_only) { 19311dd7afcfSStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 19321dd7afcfSStefano Zampini } 1933015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 1934efc2fbd9SStefano Zampini } 19351f4df5f7SStefano Zampini 19361dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1937f913dca9SStefano Zampini pcbddc->work_change = r; 19381dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 19391dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 19401dd7afcfSStefano Zampini } 19410c7d97c5SJed Brown PetscFunctionReturn(0); 19420c7d97c5SJed Brown } 194350efa1b5SStefano Zampini 194450efa1b5SStefano Zampini /* 194550efa1b5SStefano Zampini PCApplyTranspose_BDDC - Applies the transpose of the BDDC operator to a vector. 194650efa1b5SStefano Zampini 194750efa1b5SStefano Zampini Input Parameters: 19480f202f7eSStefano Zampini + pc - the preconditioner context 19490f202f7eSStefano Zampini - r - input vector (global) 195050efa1b5SStefano Zampini 195150efa1b5SStefano Zampini Output Parameter: 195250efa1b5SStefano Zampini . z - output vector (global) 195350efa1b5SStefano Zampini 195450efa1b5SStefano Zampini Application Interface Routine: PCApplyTranspose() 195550efa1b5SStefano Zampini */ 195650efa1b5SStefano Zampini #undef __FUNCT__ 195750efa1b5SStefano Zampini #define __FUNCT__ "PCApplyTranspose_BDDC" 195850efa1b5SStefano Zampini PetscErrorCode PCApplyTranspose_BDDC(PC pc,Vec r,Vec z) 195950efa1b5SStefano Zampini { 196050efa1b5SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 196150efa1b5SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1962b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 196350efa1b5SStefano Zampini PetscErrorCode ierr; 196450efa1b5SStefano Zampini const PetscScalar one = 1.0; 196550efa1b5SStefano Zampini const PetscScalar m_one = -1.0; 196650efa1b5SStefano Zampini const PetscScalar zero = 0.0; 196750efa1b5SStefano Zampini 196850efa1b5SStefano Zampini PetscFunctionBegin; 19691dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 19701dd7afcfSStefano Zampini Vec swap; 197127b6a85dSStefano Zampini 197227b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 19731dd7afcfSStefano Zampini swap = pcbddc->work_change; 19741dd7afcfSStefano Zampini pcbddc->work_change = r; 19751dd7afcfSStefano Zampini r = swap; 197627b6a85dSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 19778ae0ca82SStefano Zampini if (pcbddc->benign_apply_coarse_only && pcbddc->exact_dirichlet_trick_app && pcbddc->change_interior) { 197827b6a85dSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 197927b6a85dSStefano Zampini ierr = VecLockPush(pcis->vec1_global);CHKERRQ(ierr); 19801dd7afcfSStefano Zampini } 198127b6a85dSStefano Zampini } 198227b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 1983537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1984537c1cdfSStefano Zampini } 19858ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 1986b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 198750efa1b5SStefano Zampini /* First Dirichlet solve */ 198850efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 198950efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 199050efa1b5SStefano Zampini /* 199150efa1b5SStefano Zampini Assembling right hand side for BDDC operator 1992b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 199350efa1b5SStefano Zampini - pcis->vec1_B the interface part of the global vector z 199450efa1b5SStefano Zampini */ 1995b097fa66SStefano Zampini if (n_D) { 1996b097fa66SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 199750efa1b5SStefano Zampini ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 199816909a7fSStefano Zampini if (pcbddc->switch_static) { 199916909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 200016909a7fSStefano Zampini 200116909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 200216909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 200316909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 200416909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 200516909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 200616909a7fSStefano Zampini } else { 200716909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 200816909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 200916909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 201016909a7fSStefano Zampini } 201116909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 201216909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 201316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 201416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 201516909a7fSStefano Zampini } else { 2016b097fa66SStefano Zampini ierr = MatMultTranspose(pcis->A_IB,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 201716909a7fSStefano Zampini } 2018b097fa66SStefano Zampini } else { 2019b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 2020b097fa66SStefano Zampini } 202150efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 202250efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 202350efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 202450efa1b5SStefano Zampini } else { 202550efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 202650efa1b5SStefano Zampini } 202750efa1b5SStefano Zampini 202850efa1b5SStefano Zampini /* Apply interface preconditioner 202950efa1b5SStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 2030dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_TRUE);CHKERRQ(ierr); 203150efa1b5SStefano Zampini 203250efa1b5SStefano Zampini /* Apply transpose of partition of unity operator */ 203350efa1b5SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 203450efa1b5SStefano Zampini 203550efa1b5SStefano Zampini /* Second Dirichlet solve and assembling of output */ 203650efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 203750efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2038b097fa66SStefano Zampini if (n_B) { 203916909a7fSStefano Zampini if (pcbddc->switch_static) { 204016909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 204116909a7fSStefano Zampini 204216909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 204316909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 204416909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 204516909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 204616909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 204716909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 204816909a7fSStefano Zampini } else { 204916909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 205016909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 205116909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 205216909a7fSStefano Zampini } 205316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 205416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 205516909a7fSStefano Zampini } else { 205650efa1b5SStefano Zampini ierr = MatMultTranspose(pcis->A_BI,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 205716909a7fSStefano Zampini } 205816909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 205916909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 206016909a7fSStefano Zampini 206116909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 206216909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 206316909a7fSStefano Zampini } else { 206416909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 206516909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 206616909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 206716909a7fSStefano Zampini } 2068b097fa66SStefano Zampini } 2069b0147a47SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 20708ae0ca82SStefano Zampini if (!pcbddc->exact_dirichlet_trick_app && !pcbddc->benign_apply_coarse_only) { 2071b097fa66SStefano Zampini if (pcbddc->switch_static) { 2072b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 2073b097fa66SStefano Zampini } else { 2074b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 2075b097fa66SStefano Zampini } 207650efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 207750efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2078b097fa66SStefano Zampini } else { 2079b097fa66SStefano Zampini if (pcbddc->switch_static) { 2080b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 2081b097fa66SStefano Zampini } else { 2082b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 2083b097fa66SStefano Zampini } 2084b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2085b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2086b097fa66SStefano Zampini } 208727b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 2088537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 2089537c1cdfSStefano Zampini } 20901dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2091f913dca9SStefano Zampini pcbddc->work_change = r; 20921dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 20931dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 20941dd7afcfSStefano Zampini } 209550efa1b5SStefano Zampini PetscFunctionReturn(0); 209650efa1b5SStefano Zampini } 2097674ae819SStefano Zampini 2098da1bb401SStefano Zampini #undef __FUNCT__ 2099da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC" 2100da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 2101da1bb401SStefano Zampini { 2102da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2103da1bb401SStefano Zampini PetscErrorCode ierr; 2104da1bb401SStefano Zampini 2105da1bb401SStefano Zampini PetscFunctionBegin; 2106674ae819SStefano Zampini /* free BDDC custom data */ 2107674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 2108674ae819SStefano Zampini /* destroy objects related to topography */ 2109674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 2110674ae819SStefano Zampini /* free allocated graph structure */ 2111da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr); 2112b96c3477SStefano Zampini /* free allocated sub schurs structure */ 2113b96c3477SStefano Zampini ierr = PetscFree(pcbddc->sub_schurs);CHKERRQ(ierr); 211434a97f8cSStefano Zampini /* destroy objects for scaling operator */ 2115674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 211634a97f8cSStefano Zampini ierr = PetscFree(pcbddc->deluxe_ctx);CHKERRQ(ierr); 2117674ae819SStefano Zampini /* free solvers stuff */ 2118674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 211962a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 212062a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 212162a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 21221dd7afcfSStefano Zampini /* free data created by PCIS */ 21231dd7afcfSStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 21243425bc38SStefano Zampini /* remove functions */ 2125a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",NULL);CHKERRQ(ierr); 2126a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",NULL);CHKERRQ(ierr); 2127906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",NULL);CHKERRQ(ierr); 2128674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 212930368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",NULL);CHKERRQ(ierr); 2130bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 21312b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr); 2132b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr); 21332b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr); 2134bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 213582ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2136bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 213782ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2138bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 213982ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2140bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 2141785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2142bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 214363602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",NULL);CHKERRQ(ierr); 2144bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 2145bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 2146bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 2147bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 2148a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",NULL);CHKERRQ(ierr); 2149674ae819SStefano Zampini /* Free the private data structure */ 2150674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 2151da1bb401SStefano Zampini PetscFunctionReturn(0); 2152da1bb401SStefano Zampini } 21531e6b0712SBarry Smith 21543425bc38SStefano Zampini #undef __FUNCT__ 2155a06fd7f2SStefano Zampini #define __FUNCT__ "PCPreSolveChangeRHS_BDDC" 2156a06fd7f2SStefano Zampini static PetscErrorCode PCPreSolveChangeRHS_BDDC(PC pc, PetscBool* change) 2157a06fd7f2SStefano Zampini { 2158a06fd7f2SStefano Zampini PetscFunctionBegin; 2159a06fd7f2SStefano Zampini *change = PETSC_TRUE; 2160a06fd7f2SStefano Zampini PetscFunctionReturn(0); 2161a06fd7f2SStefano Zampini } 2162a06fd7f2SStefano Zampini 2163a06fd7f2SStefano Zampini #undef __FUNCT__ 21643425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC" 21653425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 21663425bc38SStefano Zampini { 2167674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 2168266e20e9SStefano Zampini Vec work; 21693425bc38SStefano Zampini PC_IS* pcis; 21703425bc38SStefano Zampini PC_BDDC* pcbddc; 21713425bc38SStefano Zampini PetscErrorCode ierr; 21720c7d97c5SJed Brown 21733425bc38SStefano Zampini PetscFunctionBegin; 21743425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 21753425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 21763425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 21773425bc38SStefano Zampini 2178c08af4c6SStefano Zampini /* 2179c08af4c6SStefano Zampini change of basis for physical rhs if needed 2180c08af4c6SStefano Zampini It also changes the rhs in case of dirichlet boundaries 2181c08af4c6SStefano Zampini */ 21823738a8e6SStefano Zampini if (!pcbddc->original_rhs) { 21833738a8e6SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 21843738a8e6SStefano Zampini } 21853738a8e6SStefano Zampini ierr = VecCopy(standard_rhs,pcbddc->original_rhs);CHKERRQ(ierr); 21863738a8e6SStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,pcbddc->original_rhs,NULL);CHKERRQ(ierr); 2187fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 21883738a8e6SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcbddc->original_rhs,pcbddc->work_change);CHKERRQ(ierr); 21893738a8e6SStefano Zampini work = pcbddc->work_change; 2190fc17d649SStefano Zampini } else { 21913738a8e6SStefano Zampini work = pcbddc->original_rhs; 2192fc17d649SStefano Zampini } 21933425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 2194266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2195266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2196fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 2197fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 2198266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2199266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2200674ae819SStefano Zampini /* Apply partition of unity */ 22013425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 2202266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 22038eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 22043425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 22053425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 22063425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 22073425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 2208266e20e9SStefano Zampini ierr = VecSet(work,0.0);CHKERRQ(ierr); 2209266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2210266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2211266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 2212266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2213266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22143425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 22153425bc38SStefano Zampini } 22163425bc38SStefano Zampini /* BDDC rhs */ 22173425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 22188eeda7d8SStefano Zampini if (pcbddc->switch_static) { 22193425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 22203425bc38SStefano Zampini } 2221fc17d649SStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 22223425bc38SStefano Zampini /* apply BDDC */ 2223dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2224266e20e9SStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 22253425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 22263425bc38SStefano Zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 22273425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 22283425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22293425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22303425bc38SStefano Zampini PetscFunctionReturn(0); 22313425bc38SStefano Zampini } 22321e6b0712SBarry Smith 22333425bc38SStefano Zampini #undef __FUNCT__ 22343425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS" 22353425bc38SStefano Zampini /*@ 22360f202f7eSStefano Zampini PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETI-DP linear system using the physical right-hand side 22373425bc38SStefano Zampini 22383425bc38SStefano Zampini Collective 22393425bc38SStefano Zampini 22403425bc38SStefano Zampini Input Parameters: 22410f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix object obtained by a call to PCBDDCCreateFETIDPOperators 22420f202f7eSStefano Zampini - standard_rhs - the right-hand side of the original linear system 22433425bc38SStefano Zampini 22443425bc38SStefano Zampini Output Parameters: 22450f202f7eSStefano Zampini . fetidp_flux_rhs - the right-hand side for the FETI-DP linear system 22463425bc38SStefano Zampini 22473425bc38SStefano Zampini Level: developer 22483425bc38SStefano Zampini 22493425bc38SStefano Zampini Notes: 22503425bc38SStefano Zampini 22510f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetSolution 22523425bc38SStefano Zampini @*/ 22533425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 22543425bc38SStefano Zampini { 2255674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 22563425bc38SStefano Zampini PetscErrorCode ierr; 22573425bc38SStefano Zampini 22583425bc38SStefano Zampini PetscFunctionBegin; 2259266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2260266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_rhs,VEC_CLASSID,2); 2261266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_rhs,VEC_CLASSID,3); 22623425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2263163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 22643425bc38SStefano Zampini PetscFunctionReturn(0); 22653425bc38SStefano Zampini } 22661e6b0712SBarry Smith 22673425bc38SStefano Zampini #undef __FUNCT__ 22683425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC" 22693425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 22703425bc38SStefano Zampini { 2271674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 22723425bc38SStefano Zampini PC_IS* pcis; 22733425bc38SStefano Zampini PC_BDDC* pcbddc; 22743425bc38SStefano Zampini PetscErrorCode ierr; 22753425bc38SStefano Zampini 22763425bc38SStefano Zampini PetscFunctionBegin; 22773425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 22783425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 22793425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 22803425bc38SStefano Zampini 22813425bc38SStefano Zampini /* apply B_delta^T */ 22823425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 22833425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 22843425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 22853425bc38SStefano Zampini /* compute rhs for BDDC application */ 22863425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 22878eeda7d8SStefano Zampini if (pcbddc->switch_static) { 22883425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 22893425bc38SStefano Zampini } 2290fc17d649SStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 22913425bc38SStefano Zampini /* apply BDDC */ 2292dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 22933425bc38SStefano Zampini /* put values into standard global vector */ 22943425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 22953425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 22968eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 22973425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 22983425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 229900f6b531SStefano Zampini ierr = VecAYPX(pcis->vec1_D,-1.0,mat_ctx->temp_solution_D);CHKERRQ(ierr); 230000f6b531SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); 23013425bc38SStefano Zampini } 23023425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23033425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2304266e20e9SStefano Zampini /* add p0 solution to final solution */ 2305266e20e9SStefano Zampini ierr = PCBDDCBenignGetOrSetP0(mat_ctx->pc,standard_sol,PETSC_FALSE);CHKERRQ(ierr); 2306fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2307fc17d649SStefano Zampini Vec v2; 2308fc17d649SStefano Zampini ierr = VecDuplicate(standard_sol,&v2);CHKERRQ(ierr); 2309fc17d649SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,standard_sol,v2);CHKERRQ(ierr); 2310fc17d649SStefano Zampini ierr = VecCopy(v2,standard_sol);CHKERRQ(ierr); 2311fc17d649SStefano Zampini ierr = VecDestroy(&v2);CHKERRQ(ierr); 2312fc17d649SStefano Zampini } 23133308cffdSStefano Zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 23143425bc38SStefano Zampini PetscFunctionReturn(0); 23153425bc38SStefano Zampini } 23161e6b0712SBarry Smith 23173425bc38SStefano Zampini #undef __FUNCT__ 23183425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution" 23193425bc38SStefano Zampini /*@ 23200f202f7eSStefano Zampini PCBDDCMatFETIDPGetSolution - Compute the physical solution using the solution of the FETI-DP linear system 23213425bc38SStefano Zampini 23223425bc38SStefano Zampini Collective 23233425bc38SStefano Zampini 23243425bc38SStefano Zampini Input Parameters: 23250f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix obtained by a call to PCBDDCCreateFETIDPOperators 23260f202f7eSStefano Zampini - fetidp_flux_sol - the solution of the FETI-DP linear system 23273425bc38SStefano Zampini 23283425bc38SStefano Zampini Output Parameters: 23290f202f7eSStefano Zampini . standard_sol - the solution defined on the physical domain 23303425bc38SStefano Zampini 23313425bc38SStefano Zampini Level: developer 23323425bc38SStefano Zampini 23333425bc38SStefano Zampini Notes: 23343425bc38SStefano Zampini 23350f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetRHS 23363425bc38SStefano Zampini @*/ 23373425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 23383425bc38SStefano Zampini { 2339674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 23403425bc38SStefano Zampini PetscErrorCode ierr; 23413425bc38SStefano Zampini 23423425bc38SStefano Zampini PetscFunctionBegin; 2343266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2344266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_sol,VEC_CLASSID,2); 2345266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_sol,VEC_CLASSID,3); 23463425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2347163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 23483425bc38SStefano Zampini PetscFunctionReturn(0); 23493425bc38SStefano Zampini } 23501e6b0712SBarry Smith 2351f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec); 2352edf7251bSStefano Zampini extern PetscErrorCode FETIDPMatMultTranspose(Mat,Vec,Vec); 2353f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat); 2354f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec); 2355edf7251bSStefano Zampini extern PetscErrorCode FETIDPPCApplyTranspose(PC,Vec,Vec); 2356f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC); 2357674ae819SStefano Zampini 23583425bc38SStefano Zampini #undef __FUNCT__ 23593425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC" 23601720468bSStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, PetscBool fully_redundant, Mat *fetidp_mat, PC *fetidp_pc) 23613425bc38SStefano Zampini { 2362674ae819SStefano Zampini 2363674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 23643425bc38SStefano Zampini Mat newmat; 2365674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 23663425bc38SStefano Zampini PC newpc; 2367ce94432eSBarry Smith MPI_Comm comm; 23683425bc38SStefano Zampini PetscErrorCode ierr; 23693425bc38SStefano Zampini 23703425bc38SStefano Zampini PetscFunctionBegin; 2371ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 23723425bc38SStefano Zampini /* FETIDP linear matrix */ 23733425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 23741720468bSStefano Zampini fetidpmat_ctx->fully_redundant = fully_redundant; 23753425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 23763425bc38SStefano Zampini ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 23773425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 2378edf7251bSStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT_TRANSPOSE,(void (*)(void))FETIDPMatMultTranspose);CHKERRQ(ierr); 23793425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 23803425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 23813425bc38SStefano Zampini /* FETIDP preconditioner */ 23823425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 23833425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 23843425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 23853425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 23863425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 23873425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 2388edf7251bSStefano Zampini ierr = PCShellSetApplyTranspose(newpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 23893425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 239023ee1639SBarry Smith ierr = PCSetOperators(newpc,newmat,newmat);CHKERRQ(ierr); 23913425bc38SStefano Zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 23923425bc38SStefano Zampini /* return pointers for objects created */ 23933425bc38SStefano Zampini *fetidp_mat=newmat; 23943425bc38SStefano Zampini *fetidp_pc=newpc; 23953425bc38SStefano Zampini PetscFunctionReturn(0); 23963425bc38SStefano Zampini } 23971e6b0712SBarry Smith 23983425bc38SStefano Zampini #undef __FUNCT__ 23993425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators" 24003425bc38SStefano Zampini /*@ 24010f202f7eSStefano Zampini PCBDDCCreateFETIDPOperators - Create FETI-DP operators 24023425bc38SStefano Zampini 24033425bc38SStefano Zampini Collective 24043425bc38SStefano Zampini 24053425bc38SStefano Zampini Input Parameters: 24061720468bSStefano Zampini + pc - the BDDC preconditioning context (setup should have been called before) 24071720468bSStefano Zampini - fully_redundant - true for a fully redundant set of Lagrange multipliers 240828509bceSStefano Zampini 240928509bceSStefano Zampini Output Parameters: 24100f202f7eSStefano Zampini + fetidp_mat - shell FETI-DP matrix object 24110f202f7eSStefano Zampini - fetidp_pc - shell Dirichlet preconditioner for FETI-DP matrix 241228509bceSStefano Zampini 24133425bc38SStefano Zampini Level: developer 24143425bc38SStefano Zampini 24153425bc38SStefano Zampini Notes: 24160f202f7eSStefano Zampini Currently the only operations provided for FETI-DP matrix are MatMult and MatMultTranspose 24173425bc38SStefano Zampini 24180f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCMatFETIDPGetRHS, PCBDDCMatFETIDPGetSolution 24193425bc38SStefano Zampini @*/ 24201720468bSStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, PetscBool fully_redundant, Mat *fetidp_mat, PC *fetidp_pc) 24213425bc38SStefano Zampini { 24223425bc38SStefano Zampini PetscErrorCode ierr; 24233425bc38SStefano Zampini 24243425bc38SStefano Zampini PetscFunctionBegin; 24253425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 24263425bc38SStefano Zampini if (pc->setupcalled) { 24271720468bSStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,PetscBool,Mat*,PC*),(pc,fully_redundant,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 2428f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n"); 24293425bc38SStefano Zampini PetscFunctionReturn(0); 24303425bc38SStefano Zampini } 24310c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2432da1bb401SStefano Zampini /*MC 2433da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 24340c7d97c5SJed Brown 243528509bceSStefano Zampini An implementation of the BDDC preconditioner based on 243628509bceSStefano Zampini 243728509bceSStefano Zampini .vb 243828509bceSStefano Zampini [1] C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 243928509bceSStefano 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 244028509bceSStefano Zampini [3] J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", http://arxiv.org/abs/0712.3977 24410f202f7eSStefano 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 244228509bceSStefano Zampini .ve 244328509bceSStefano Zampini 244428509bceSStefano Zampini The matrix to be preconditioned (Pmat) must be of type MATIS. 244528509bceSStefano Zampini 24460f202f7eSStefano Zampini Currently works with MATIS matrices with local matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers. 244728509bceSStefano Zampini 244828509bceSStefano Zampini It also works with unsymmetric and indefinite problems. 244928509bceSStefano Zampini 2450b6fdb6dfSStefano 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. 2451b6fdb6dfSStefano Zampini 2452c7017625SStefano 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). 245328509bceSStefano Zampini 24540f202f7eSStefano 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() 245530368db7SStefano Zampini Additional information on dofs can be provided by using PCBDDCSetDofsSplitting(), PCBDDCSetDirichletBoundaries(), PCBDDCSetNeumannBoundaries(), and PCBDDCSetPrimalVerticesIS() and their local counterparts. 245628509bceSStefano Zampini 24570f202f7eSStefano Zampini Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace(). Non-singular modes are retained via SVD. 245828509bceSStefano Zampini 24590f202f7eSStefano 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. 24600f202f7eSStefano Zampini User defined change of basis can be passed to PCBDDC by using PCBDDCSetChangeOfBasisMat() 246128509bceSStefano Zampini 24620f202f7eSStefano Zampini The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using a MatPartitioning object. 246328509bceSStefano Zampini 2464df4d28bfSStefano 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. 246528509bceSStefano Zampini 24660f202f7eSStefano 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. 24670f202f7eSStefano Zampini Deluxe scaling is not supported yet for FETI-DP. 24680f202f7eSStefano Zampini 24690f202f7eSStefano Zampini Options Database Keys (some of them, run with -h for a complete list): 24700f202f7eSStefano Zampini 24710f202f7eSStefano Zampini . -pc_bddc_use_vertices <true> - use or not vertices in primal space 24720f202f7eSStefano Zampini . -pc_bddc_use_edges <true> - use or not edges in primal space 24730f202f7eSStefano Zampini . -pc_bddc_use_faces <false> - use or not faces in primal space 24740f202f7eSStefano Zampini . -pc_bddc_symmetric <true> - symmetric computation of primal basis functions. Specify false for unsymmetric problems 24750f202f7eSStefano Zampini . -pc_bddc_use_change_of_basis <false> - use change of basis approach (on edges only) 24760f202f7eSStefano Zampini . -pc_bddc_use_change_on_faces <false> - use change of basis approach on faces if change of basis has been requested 24770f202f7eSStefano Zampini . -pc_bddc_switch_static <false> - switches from M_2 (default) to M_3 operator (see reference article [1]) 247828509bceSStefano Zampini . -pc_bddc_levels <0> - maximum number of levels for multilevel 24790f202f7eSStefano 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) 24800f202f7eSStefano Zampini . -pc_bddc_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) 24810f202f7eSStefano Zampini . -pc_bddc_use_deluxe_scaling <false> - use deluxe scaling 24820f202f7eSStefano 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) 2483df4d28bfSStefano Zampini . -pc_bddc_adaptive_threshold <0.0> - when a value greater than one is specified, adaptive selection of constraints is performed on edges and faces (requires deluxe scaling and MUMPS or MKL_PARDISO installed) 248428509bceSStefano Zampini - -pc_bddc_check_level <0> - set verbosity level of debugging output 248528509bceSStefano Zampini 248628509bceSStefano Zampini Options for Dirichlet, Neumann or coarse solver can be set with 248728509bceSStefano Zampini .vb 248828509bceSStefano Zampini -pc_bddc_dirichlet_ 248928509bceSStefano Zampini -pc_bddc_neumann_ 249028509bceSStefano Zampini -pc_bddc_coarse_ 249128509bceSStefano Zampini .ve 24920f202f7eSStefano Zampini e.g -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg. PCBDDC uses by default KPSPREONLY and PCLU. 249328509bceSStefano Zampini 24940f202f7eSStefano Zampini When using a multilevel approach, solvers' options at the N-th level (N > 1) can be specified as 249528509bceSStefano Zampini .vb 2496312be037SStefano Zampini -pc_bddc_dirichlet_lN_ 2497312be037SStefano Zampini -pc_bddc_neumann_lN_ 2498312be037SStefano Zampini -pc_bddc_coarse_lN_ 249928509bceSStefano Zampini .ve 25000f202f7eSStefano Zampini Note that level number ranges from the finest (0) to the coarsest (N). 25010f202f7eSStefano 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. 25020f202f7eSStefano Zampini .vb 25030f202f7eSStefano Zampini -pc_bddc_coarse_pc_bddc_adaptive_threshold 5 -pc_bddc_coarse_l1_pc_bddc_redistribute 3 25040f202f7eSStefano Zampini .ve 25050f202f7eSStefano 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 2506da1bb401SStefano Zampini 2507da1bb401SStefano Zampini Level: intermediate 2508da1bb401SStefano Zampini 2509b6fdb6dfSStefano Zampini Developer notes: 2510da1bb401SStefano Zampini 2511da1bb401SStefano Zampini Contributed by Stefano Zampini 2512da1bb401SStefano Zampini 2513da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 2514da1bb401SStefano Zampini M*/ 2515b2573a8aSBarry Smith 2516da1bb401SStefano Zampini #undef __FUNCT__ 2517da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC" 25188cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 2519da1bb401SStefano Zampini { 2520da1bb401SStefano Zampini PetscErrorCode ierr; 2521da1bb401SStefano Zampini PC_BDDC *pcbddc; 2522da1bb401SStefano Zampini 2523da1bb401SStefano Zampini PetscFunctionBegin; 2524da1bb401SStefano Zampini /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 2525b00a9115SJed Brown ierr = PetscNewLog(pc,&pcbddc);CHKERRQ(ierr); 2526da1bb401SStefano Zampini pc->data = (void*)pcbddc; 2527da1bb401SStefano Zampini 2528da1bb401SStefano Zampini /* create PCIS data structure */ 2529da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 2530da1bb401SStefano Zampini 253147d04d0dSStefano Zampini /* BDDC customization */ 253208a5cf49SStefano Zampini pcbddc->use_local_adj = PETSC_TRUE; 253347d04d0dSStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 253447d04d0dSStefano Zampini pcbddc->use_edges = PETSC_TRUE; 253547d04d0dSStefano Zampini pcbddc->use_faces = PETSC_FALSE; 253647d04d0dSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 253747d04d0dSStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 253847d04d0dSStefano Zampini pcbddc->switch_static = PETSC_FALSE; 2539fa434743SStefano Zampini pcbddc->use_nnsp_true = PETSC_FALSE; 2540fa434743SStefano Zampini pcbddc->use_qr_single = PETSC_FALSE; 25413301b35fSStefano Zampini pcbddc->symmetric_primal = PETSC_TRUE; 254206a4e24aSStefano Zampini pcbddc->benign_saddle_point = PETSC_FALSE; 254327b6a85dSStefano Zampini pcbddc->benign_have_null = PETSC_FALSE; 254414f95afaSStefano Zampini pcbddc->vertex_size = 1; 254547d04d0dSStefano Zampini pcbddc->dbg_flag = 0; 2546b9d89cd5SStefano Zampini /* private */ 2547727cdba6SStefano Zampini pcbddc->local_primal_size = 0; 25480e6343abSStefano Zampini pcbddc->local_primal_size_cc = 0; 25490e6343abSStefano Zampini pcbddc->local_primal_ref_node = 0; 25500e6343abSStefano Zampini pcbddc->local_primal_ref_mult = 0; 2551e9189074SStefano Zampini pcbddc->n_vertices = 0; 2552727cdba6SStefano Zampini pcbddc->primal_indices_local_idxs = 0; 2553c703fcc7SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 255468457ee5SStefano Zampini pcbddc->coarse_size = -1; 2555f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 2556727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 2557f4ddd8eeSStefano Zampini pcbddc->global_primal_indices = 0; 2558f4ddd8eeSStefano Zampini pcbddc->onearnullspace = 0; 2559f4ddd8eeSStefano Zampini pcbddc->onearnullvecs_state = 0; 2560674ae819SStefano Zampini pcbddc->user_primal_vertices = 0; 256130368db7SStefano Zampini pcbddc->user_primal_vertices_local = 0; 25623972b0daSStefano Zampini pcbddc->temp_solution = 0; 2563534831adSStefano Zampini pcbddc->original_rhs = 0; 2564534831adSStefano Zampini pcbddc->local_mat = 0; 2565534831adSStefano Zampini pcbddc->ChangeOfBasisMatrix = 0; 2566b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = 0; 2567da1bb401SStefano Zampini pcbddc->coarse_vec = 0; 2568da1bb401SStefano Zampini pcbddc->coarse_ksp = 0; 2569da1bb401SStefano Zampini pcbddc->coarse_phi_B = 0; 2570da1bb401SStefano Zampini pcbddc->coarse_phi_D = 0; 257115aaf578SStefano Zampini pcbddc->coarse_psi_B = 0; 257215aaf578SStefano Zampini pcbddc->coarse_psi_D = 0; 2573da1bb401SStefano Zampini pcbddc->vec1_P = 0; 2574da1bb401SStefano Zampini pcbddc->vec1_R = 0; 2575da1bb401SStefano Zampini pcbddc->vec2_R = 0; 2576da1bb401SStefano Zampini pcbddc->local_auxmat1 = 0; 2577da1bb401SStefano Zampini pcbddc->local_auxmat2 = 0; 2578da1bb401SStefano Zampini pcbddc->R_to_B = 0; 2579da1bb401SStefano Zampini pcbddc->R_to_D = 0; 2580da1bb401SStefano Zampini pcbddc->ksp_D = 0; 2581da1bb401SStefano Zampini pcbddc->ksp_R = 0; 2582da1bb401SStefano Zampini pcbddc->NeumannBoundaries = 0; 2583785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = 0; 2584785d1243SStefano Zampini pcbddc->DirichletBoundaries = 0; 2585785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = 0; 258660d44989SStefano Zampini pcbddc->user_provided_isfordofs = PETSC_FALSE; 258760d44989SStefano Zampini pcbddc->n_ISForDofs = 0; 258863602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 2589da1bb401SStefano Zampini pcbddc->ISForDofs = 0; 259063602bcaSStefano Zampini pcbddc->ISForDofsLocal = 0; 2591da1bb401SStefano Zampini pcbddc->ConstraintMatrix = 0; 259285c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 25938ae0ca82SStefano Zampini pcbddc->exact_dirichlet_trick_app = PETSC_FALSE; 259447d04d0dSStefano Zampini pcbddc->coarse_loc_to_glob = 0; 259547d04d0dSStefano Zampini pcbddc->coarsening_ratio = 8; 2596b0c7d250SStefano Zampini pcbddc->coarse_adj_red = 0; 25974fad6a16SStefano Zampini pcbddc->current_level = 0; 25982b510759SStefano Zampini pcbddc->max_levels = 0; 2599323d395dSStefano Zampini pcbddc->use_coarse_estimates = PETSC_FALSE; 260057de7509SStefano Zampini pcbddc->coarse_eqs_per_proc = 1; 2601f3bde8b3SStefano Zampini pcbddc->coarse_subassembling = 0; 26024f1b2e48SStefano Zampini pcbddc->detect_disconnected = PETSC_FALSE; 26034f1b2e48SStefano Zampini pcbddc->n_local_subs = 0; 26044f1b2e48SStefano Zampini pcbddc->local_subs = NULL; 260581d14e9dSStefano Zampini 260681d14e9dSStefano Zampini /* benign subspace trick */ 260781d14e9dSStefano Zampini pcbddc->benign_change = 0; 260827b6a85dSStefano Zampini pcbddc->benign_compute_correction = PETSC_TRUE; 26090369aaf7SStefano Zampini pcbddc->benign_vec = 0; 26100369aaf7SStefano Zampini pcbddc->benign_original_mat = 0; 26110369aaf7SStefano Zampini pcbddc->benign_sf = 0; 26124f1b2e48SStefano Zampini pcbddc->benign_B0 = 0; 26134f1b2e48SStefano Zampini pcbddc->benign_n = 0; 26144f1b2e48SStefano Zampini pcbddc->benign_p0 = NULL; 26154f1b2e48SStefano Zampini pcbddc->benign_p0_lidx = NULL; 26164f1b2e48SStefano Zampini pcbddc->benign_p0_gidx = NULL; 2617b0f5fe93SStefano Zampini pcbddc->benign_null = PETSC_FALSE; 261881d14e9dSStefano Zampini 26191e0482f5SStefano Zampini /* Nedelec */ 26201e0482f5SStefano Zampini pcbddc->nedfield = -1; 26211e0482f5SStefano Zampini pcbddc->nedglobal = PETSC_TRUE; 26221e0482f5SStefano Zampini 2623674ae819SStefano Zampini /* create local graph structure */ 2624674ae819SStefano Zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 2625be12c134Sstefano_zampini pcbddc->graphmaxcount = PETSC_MAX_INT; 2626674ae819SStefano Zampini 2627674ae819SStefano Zampini /* scaling */ 2628674ae819SStefano Zampini pcbddc->work_scaling = 0; 262934a97f8cSStefano Zampini pcbddc->use_deluxe_scaling = PETSC_FALSE; 2630b96c3477SStefano Zampini 2631b334f244SStefano Zampini /* sub schurs options */ 2632b96c3477SStefano Zampini pcbddc->sub_schurs_rebuild = PETSC_FALSE; 2633b96c3477SStefano Zampini pcbddc->sub_schurs_layers = -1; 2634b96c3477SStefano Zampini pcbddc->sub_schurs_use_useradj = PETSC_FALSE; 2635b96c3477SStefano Zampini 2636b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_FALSE; 2637da1bb401SStefano Zampini 2638b7eb3628SStefano Zampini /* adaptivity */ 2639f6f667cfSStefano Zampini pcbddc->adaptive_threshold = 0.0; 264008122e43SStefano Zampini pcbddc->adaptive_nmax = 0; 2641f6f667cfSStefano Zampini pcbddc->adaptive_nmin = 0; 2642b7eb3628SStefano Zampini 2643da1bb401SStefano Zampini /* function pointers */ 2644da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 264593bd9ae7SStefano Zampini pc->ops->applytranspose = PCApplyTranspose_BDDC; 2646da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 2647da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 2648da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 26496b78500eSPatrick Sanan pc->ops->view = PCView_BDDC; 2650da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 2651da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 2652da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 2653534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 2654534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 2655da1bb401SStefano Zampini 2656da1bb401SStefano Zampini /* composing function */ 2657a13144ffSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDiscreteGradient_C",PCBDDCSetDiscreteGradient_BDDC);CHKERRQ(ierr); 2658a198735bSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDivergenceMat_C",PCBDDCSetDivergenceMat_BDDC);CHKERRQ(ierr); 2659906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",PCBDDCSetChangeOfBasisMat_BDDC);CHKERRQ(ierr); 2660674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 266130368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",PCBDDCSetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 2662bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 26632b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr); 2664b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr); 26652b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr); 2666bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 266782ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2668bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 266982ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2670bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 267182ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2672bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 267382ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2674bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 267563602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",PCBDDCSetDofsSplittingLocal_BDDC);CHKERRQ(ierr); 2676bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 2677bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 2678bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 2679bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 2680a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",PCPreSolveChangeRHS_BDDC);CHKERRQ(ierr); 2681da1bb401SStefano Zampini PetscFunctionReturn(0); 2682da1bb401SStefano Zampini } 26833425bc38SStefano Zampini 2684