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 FETIDP 18eb97c9d2SStefano Zampini - Move FETIDP code to its own classes 19eb97c9d2SStefano Zampini 20eb97c9d2SStefano Zampini MATIS related operations contained in BDDC code 21eb97c9d2SStefano Zampini - Provide general case for subassembling 22eb97c9d2SStefano Zampini 2353cdbc3dSStefano Zampini */ 240c7d97c5SJed Brown 25ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 26ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 273b03a366Sstefano_zampini #include <petscblaslapack.h> 28674ae819SStefano Zampini 290369aaf7SStefano Zampini /* temporarily declare it */ 300369aaf7SStefano Zampini PetscErrorCode PCApply_BDDC(PC,Vec,Vec); 310369aaf7SStefano Zampini 320c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 330c7d97c5SJed Brown #undef __FUNCT__ 340c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC" 354416b707SBarry Smith PetscErrorCode PCSetFromOptions_BDDC(PetscOptionItems *PetscOptionsObject,PC pc) 360c7d97c5SJed Brown { 370c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 380c7d97c5SJed Brown PetscErrorCode ierr; 390c7d97c5SJed Brown 400c7d97c5SJed Brown PetscFunctionBegin; 41e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"BDDC options");CHKERRQ(ierr); 428eeda7d8SStefano Zampini /* Verbose debugging */ 43c7017625SStefano 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); 44c7017625SStefano 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); 45c7017625SStefano 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); 46c7017625SStefano 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); 478eeda7d8SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_check_level","Verbose output for PCBDDC (intended for debug)","none",pcbddc->dbg_flag,&pcbddc->dbg_flag,NULL);CHKERRQ(ierr); 486b78500eSPatrick Sanan /* Primal space customization */ 4908a5cf49SStefano 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); 508eeda7d8SStefano 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); 518eeda7d8SStefano 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); 528eeda7d8SStefano 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); 5314f95afaSStefano 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); 546661aa1dSStefano 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); 5514f95afaSStefano 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); 568eeda7d8SStefano Zampini /* Change of basis */ 57b9b85e73SStefano 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); 58b9b85e73SStefano 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); 59674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 60674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 61674ae819SStefano Zampini } 628eeda7d8SStefano Zampini /* Switch between M_2 (default) and M_3 preconditioners (as defined by C. Dohrmann in the ref. article) */ 638eeda7d8SStefano 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); 6457de7509SStefano 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); 650298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr); 662b510759SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr); 67323d395dSStefano 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); 68674ae819SStefano 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); 69b96c3477SStefano 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); 70b96c3477SStefano 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); 71b96c3477SStefano 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); 72683d3df6SStefano 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); 73bf3a8328SStefano 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); 74bf3a8328SStefano 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); 754c6709b3SStefano 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); 7608122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmin","Minimum number of constraints per connected components","none",pcbddc->adaptive_nmin,&pcbddc->adaptive_nmin,NULL);CHKERRQ(ierr); 7708122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmax","Maximum number of constraints per connected components","none",pcbddc->adaptive_nmax,&pcbddc->adaptive_nmax,NULL);CHKERRQ(ierr); 783301b35fSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_symmetric","Symmetric computation of primal basis functions","none",pcbddc->symmetric_primal,&pcbddc->symmetric_primal,NULL);CHKERRQ(ierr); 79b0c7d250SStefano 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); 80b3afcdbeSStefano 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); 81b3afcdbeSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_benign_nonetflux","Automatic computation of no-net-flux quadrature weights","none",pcbddc->benign_compute_nonetflux,&pcbddc->benign_compute_nonetflux,NULL);CHKERRQ(ierr); 82e9627c49SStefano 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); 8327b6a85dSStefano 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); 844f1b2e48SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_detect_disconnected","Detects disconnected subdomains","none",pcbddc->detect_disconnected,&pcbddc->detect_disconnected,NULL);CHKERRQ(ierr); 8570c64980SStefano 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); 860c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 870c7d97c5SJed Brown PetscFunctionReturn(0); 880c7d97c5SJed Brown } 896b78500eSPatrick Sanan 906b78500eSPatrick Sanan /* -------------------------------------------------------------------------- */ 916b78500eSPatrick Sanan #undef __FUNCT__ 926b78500eSPatrick Sanan #define __FUNCT__ "PCView_BDDC" 936b78500eSPatrick Sanan static PetscErrorCode PCView_BDDC(PC pc,PetscViewer viewer) 946b78500eSPatrick Sanan { 956b78500eSPatrick Sanan PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 96e9627c49SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 976b78500eSPatrick Sanan PetscErrorCode ierr; 986b78500eSPatrick Sanan PetscBool isascii,isstring; 99e9627c49SStefano Zampini PetscSubcomm subcomm; 100e9627c49SStefano Zampini PetscViewer subviewer; 1016b78500eSPatrick Sanan 1026b78500eSPatrick Sanan PetscFunctionBegin; 1036b78500eSPatrick Sanan ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1046b78500eSPatrick Sanan ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 1056b78500eSPatrick Sanan /* Nothing printed for the String viewer */ 1066b78500eSPatrick Sanan /* ASCII viewer */ 1076b78500eSPatrick Sanan if (isascii) { 108*4b2aedd3SStefano Zampini PetscMPIInt color,rank,size; 109345ecf6cSStefano Zampini Petsc64bitInt loc[6],gsum[5],gmax[5],gmin[5],totbenign; 110e9627c49SStefano Zampini PetscScalar interface_size; 111e9627c49SStefano Zampini PetscReal ratio1=0.,ratio2=0.; 112e9627c49SStefano Zampini Vec counter; 1136b78500eSPatrick Sanan 114e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use verbose output: %d\n",pcbddc->dbg_flag);CHKERRQ(ierr); 115e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use user-defined CSR: %d\n",!!pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 1166b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use local mat graph: %d\n",pcbddc->use_local_adj);CHKERRQ(ierr); 117e9627c49SStefano Zampini if (pcbddc->mat_graph->twodim) { 118e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Connectivity graph topological dimension: 2\n");CHKERRQ(ierr); 119e9627c49SStefano Zampini } else { 120e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Connectivity graph topological dimension: 3\n");CHKERRQ(ierr); 121e9627c49SStefano Zampini } 122e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use vertices: %d (vertext size %d)\n",pcbddc->use_vertices,pcbddc->vertex_size);CHKERRQ(ierr); 1236b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use edges: %d\n",pcbddc->use_edges);CHKERRQ(ierr); 1246b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use faces: %d\n",pcbddc->use_faces);CHKERRQ(ierr); 1256b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use true near null space: %d\n",pcbddc->use_nnsp_true);CHKERRQ(ierr); 1266b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use QR for single constraints on cc: %d\n",pcbddc->use_qr_single);CHKERRQ(ierr); 1276b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use change of basis on local edge nodes: %d\n",pcbddc->use_change_of_basis);CHKERRQ(ierr); 1286b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use change of basis on local face nodes: %d\n",pcbddc->use_change_on_faces);CHKERRQ(ierr); 12927b6a85dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: User defined change of basis matrix: %d\n",!!pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 13027b6a85dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Has change of basis matrix: %d\n",!!pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 13127b6a85dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Eliminate dirichlet boundary dofs: %d\n",pcbddc->eliminate_dirdofs);CHKERRQ(ierr); 1326b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Switch on static condensation ops around the interface preconditioner: %d\n",pcbddc->switch_static);CHKERRQ(ierr); 13327b6a85dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use exact dirichlet trick: %d\n",pcbddc->use_exact_dirichlet_trick);CHKERRQ(ierr); 1346b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Multilevel max levels: %d\n",pcbddc->max_levels);CHKERRQ(ierr); 135e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Multilevel coarsening ratio: %d\n",pcbddc->coarsening_ratio);CHKERRQ(ierr); 1366b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use estimated eigs for coarse problem: %d\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 1376b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use deluxe scaling: %d\n",pcbddc->use_deluxe_scaling);CHKERRQ(ierr); 138e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use deluxe zerorows: %d\n",pcbddc->deluxe_zerorows);CHKERRQ(ierr); 1396b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Rebuild interface graph for Schur principal minors: %d\n",pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 1406b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Number of dofs' layers for the computation of principal minors: %d\n",pcbddc->sub_schurs_layers);CHKERRQ(ierr); 1416b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use user CSR graph to compute successive layers: %d\n",pcbddc->sub_schurs_use_useradj);CHKERRQ(ierr); 142e9627c49SStefano 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); 1436b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Min constraints / connected component: %d\n",pcbddc->adaptive_nmin);CHKERRQ(ierr); 1446b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Max constraints / connected component: %d\n",pcbddc->adaptive_nmax);CHKERRQ(ierr); 145e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Invert exact Schur complement for adaptive selection: %d\n",pcbddc->sub_schurs_exact_schur);CHKERRQ(ierr); 1466b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Symmetric computation of primal basis functions: %d\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 1476b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Num. Procs. to map coarse adjacency list: %d\n",pcbddc->coarse_adj_red);CHKERRQ(ierr); 148e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Coarse eqs per proc (significant at the coarsest level): %d\n",pcbddc->coarse_eqs_per_proc);CHKERRQ(ierr); 149e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Detect disconnected: %d\n",pcbddc->detect_disconnected);CHKERRQ(ierr); 150fc17d649SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Benign subspace trick: %d (change explicit %d)\n",pcbddc->benign_saddle_point,pcbddc->benign_change_explicit);CHKERRQ(ierr); 15127b6a85dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Benign subspace trick is active: %d (algebraic computation of no-net-flux %d)\n",pcbddc->benign_have_null,pcbddc->benign_compute_nonetflux);CHKERRQ(ierr); 1526b78500eSPatrick Sanan 153345ecf6cSStefano Zampini /* compute some numbers on the domain decomposition */ 154e9627c49SStefano Zampini ierr = VecSet(pcis->vec1_B,1.0);CHKERRQ(ierr); 155e9627c49SStefano Zampini ierr = MatCreateVecs(pc->pmat,&counter,0);CHKERRQ(ierr); 156e9627c49SStefano Zampini ierr = VecSet(counter,0.0);CHKERRQ(ierr); 157e9627c49SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 158e9627c49SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 159e9627c49SStefano Zampini ierr = VecSum(counter,&interface_size);CHKERRQ(ierr); 160e9627c49SStefano Zampini ierr = VecDestroy(&counter);CHKERRQ(ierr); 161e9627c49SStefano Zampini gsum[0] = 1; 162345ecf6cSStefano Zampini gsum[1] = gsum[2] = gsum[3] = gsum[4] = 0; 163e9627c49SStefano Zampini loc[0] = !!pcis->n; 164e9627c49SStefano Zampini loc[1] = pcis->n - pcis->n_B; 165e9627c49SStefano Zampini loc[2] = pcis->n_B; 166e9627c49SStefano Zampini loc[3] = pcbddc->local_primal_size; 167345ecf6cSStefano Zampini loc[4] = pcis->n; 168345ecf6cSStefano Zampini loc[5] = pcbddc->benign_n; 169345ecf6cSStefano Zampini ierr = MPI_Reduce(loc,gsum,5,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 170345ecf6cSStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = -1; 171345ecf6cSStefano Zampini ierr = MPI_Reduce(loc,gmax,5,MPIU_INT64,MPI_MAX,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 172345ecf6cSStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = loc[4] = PETSC_MAX_INT; 173345ecf6cSStefano Zampini ierr = MPI_Reduce(loc,gmin,5,MPIU_INT64,MPI_MIN,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 174345ecf6cSStefano Zampini ierr = MPI_Reduce(&loc[5],&totbenign,1,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 175e9627c49SStefano Zampini if (pcbddc->coarse_size) { 176e9627c49SStefano Zampini ratio1 = pc->pmat->rmap->N/(1.*pcbddc->coarse_size); 177e9627c49SStefano Zampini ratio2 = PetscRealPart(interface_size)/pcbddc->coarse_size; 178e9627c49SStefano Zampini } 179e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: ********************************** STATISTICS AT LEVEL %d **********************************\n",pcbddc->current_level);CHKERRQ(ierr); 180e9627c49SStefano 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); 181e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Coarsening ratios: all/coarse %d interface/coarse %d\n",(PetscInt)ratio1,(PetscInt)ratio2);CHKERRQ(ierr); 182e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Active processes : %d\n",(PetscInt)gsum[0]);CHKERRQ(ierr); 183345ecf6cSStefano Zampini if (pcbddc->benign_have_null) { 184345ecf6cSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Benign subs : %d\n",(PetscInt)totbenign);CHKERRQ(ierr); 185345ecf6cSStefano Zampini } 186e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Dofs type :\tMIN\tMAX\tMEAN\n",(PetscInt)gmin[1],(PetscInt)gmax[1],(PetscInt)(gsum[1]/gsum[0]));CHKERRQ(ierr); 187e9627c49SStefano 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); 188e9627c49SStefano 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); 189e9627c49SStefano 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); 190345ecf6cSStefano 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); 19127b6a85dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: ********************************** COARSE PROBLEM DETAILS *********************************\n",pcbddc->current_level);CHKERRQ(ierr); 19227b6a85dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 193e9627c49SStefano Zampini 194e9627c49SStefano Zampini /* the coarse problem can be handled with a different communicator */ 195e9627c49SStefano Zampini if (pcbddc->coarse_ksp) color = 1; 196e9627c49SStefano Zampini else color = 0; 197e9627c49SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 198*4b2aedd3SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 199e9627c49SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)pc),&subcomm);CHKERRQ(ierr); 200*4b2aedd3SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,PetscMin(size,2));CHKERRQ(ierr); 201e9627c49SStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 202e9627c49SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 203e9627c49SStefano Zampini if (color == 1) { 204e9627c49SStefano Zampini ierr = KSPView(pcbddc->coarse_ksp,subviewer);CHKERRQ(ierr); 205e9627c49SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 206e9627c49SStefano Zampini } 207e9627c49SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 208e9627c49SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 209e9627c49SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 210e9627c49SStefano Zampini } 2116b78500eSPatrick Sanan PetscFunctionReturn(0); 2126b78500eSPatrick Sanan } 2136b78500eSPatrick Sanan 2140c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 215674ae819SStefano Zampini #undef __FUNCT__ 216906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCSetChangeOfBasisMat_BDDC" 2171dd7afcfSStefano Zampini static PetscErrorCode PCBDDCSetChangeOfBasisMat_BDDC(PC pc, Mat change, PetscBool interior) 218b9b85e73SStefano Zampini { 219b9b85e73SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 220b9b85e73SStefano Zampini PetscErrorCode ierr; 221b9b85e73SStefano Zampini 222b9b85e73SStefano Zampini PetscFunctionBegin; 223b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)change);CHKERRQ(ierr); 22456282151SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 225b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = change; 2261dd7afcfSStefano Zampini pcbddc->change_interior = interior; 227b9b85e73SStefano Zampini PetscFunctionReturn(0); 228b9b85e73SStefano Zampini } 229b9b85e73SStefano Zampini #undef __FUNCT__ 230906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCSetChangeOfBasisMat" 231b9b85e73SStefano Zampini /*@ 232906d46d4SStefano Zampini PCBDDCSetChangeOfBasisMat - Set user defined change of basis for dofs 233b9b85e73SStefano Zampini 234b9b85e73SStefano Zampini Collective on PC 235b9b85e73SStefano Zampini 236b9b85e73SStefano Zampini Input Parameters: 237b9b85e73SStefano Zampini + pc - the preconditioning context 2381dd7afcfSStefano Zampini . change - the change of basis matrix 2391dd7afcfSStefano Zampini - interior - whether or not the change of basis modifies interior dofs 240b9b85e73SStefano Zampini 241b9b85e73SStefano Zampini Level: intermediate 242b9b85e73SStefano Zampini 243b9b85e73SStefano Zampini Notes: 244b9b85e73SStefano Zampini 245b9b85e73SStefano Zampini .seealso: PCBDDC 246b9b85e73SStefano Zampini @*/ 2471dd7afcfSStefano Zampini PetscErrorCode PCBDDCSetChangeOfBasisMat(PC pc, Mat change, PetscBool interior) 248b9b85e73SStefano Zampini { 249b9b85e73SStefano Zampini PetscErrorCode ierr; 250b9b85e73SStefano Zampini 251b9b85e73SStefano Zampini PetscFunctionBegin; 252b9b85e73SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 253b9b85e73SStefano Zampini PetscValidHeaderSpecific(change,MAT_CLASSID,2); 254906d46d4SStefano Zampini PetscCheckSameComm(pc,1,change,2); 255906d46d4SStefano Zampini if (pc->mat) { 256906d46d4SStefano Zampini PetscInt rows_c,cols_c,rows,cols; 257906d46d4SStefano Zampini ierr = MatGetSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 258906d46d4SStefano Zampini ierr = MatGetSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 2596c4ed002SBarry 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); 2606c4ed002SBarry 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); 261906d46d4SStefano Zampini ierr = MatGetLocalSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 262906d46d4SStefano Zampini ierr = MatGetLocalSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 2636c4ed002SBarry 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); 2646c4ed002SBarry 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); 265906d46d4SStefano Zampini } 2661dd7afcfSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetChangeOfBasisMat_C",(PC,Mat,PetscBool),(pc,change,interior));CHKERRQ(ierr); 267b9b85e73SStefano Zampini PetscFunctionReturn(0); 268b9b85e73SStefano Zampini } 269b9b85e73SStefano Zampini /* -------------------------------------------------------------------------- */ 270b9b85e73SStefano Zampini #undef __FUNCT__ 27130368db7SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesIS_BDDC" 27230368db7SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesIS_BDDC(PC pc, IS PrimalVertices) 27330368db7SStefano Zampini { 27430368db7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 27556282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 27630368db7SStefano Zampini PetscErrorCode ierr; 27730368db7SStefano Zampini 27830368db7SStefano Zampini PetscFunctionBegin; 27956282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 28056282151SStefano Zampini if (pcbddc->user_primal_vertices) { 28156282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices,&isequal);CHKERRQ(ierr); 28256282151SStefano Zampini } 28330368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 28430368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 28530368db7SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 28656282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 28730368db7SStefano Zampini PetscFunctionReturn(0); 28830368db7SStefano Zampini } 28930368db7SStefano Zampini #undef __FUNCT__ 29030368db7SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesIS" 29130368db7SStefano Zampini /*@ 29230368db7SStefano Zampini PCBDDCSetPrimalVerticesIS - Set additional user defined primal vertices in PCBDDC 29330368db7SStefano Zampini 29430368db7SStefano Zampini Collective 29530368db7SStefano Zampini 29630368db7SStefano Zampini Input Parameters: 29730368db7SStefano Zampini + pc - the preconditioning context 29830368db7SStefano Zampini - PrimalVertices - index set of primal vertices in global numbering (can be empty) 29930368db7SStefano Zampini 30030368db7SStefano Zampini Level: intermediate 30130368db7SStefano Zampini 30230368db7SStefano Zampini Notes: 30330368db7SStefano Zampini Any process can list any global node 30430368db7SStefano Zampini 30530368db7SStefano Zampini .seealso: PCBDDC 30630368db7SStefano Zampini @*/ 30730368db7SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesIS(PC pc, IS PrimalVertices) 30830368db7SStefano Zampini { 30930368db7SStefano Zampini PetscErrorCode ierr; 31030368db7SStefano Zampini 31130368db7SStefano Zampini PetscFunctionBegin; 31230368db7SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 31330368db7SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 31430368db7SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 31530368db7SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 31630368db7SStefano Zampini PetscFunctionReturn(0); 31730368db7SStefano Zampini } 31830368db7SStefano Zampini /* -------------------------------------------------------------------------- */ 31930368db7SStefano Zampini #undef __FUNCT__ 320674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS_BDDC" 321674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 322674ae819SStefano Zampini { 323674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 32456282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 325674ae819SStefano Zampini PetscErrorCode ierr; 3261e6b0712SBarry Smith 327674ae819SStefano Zampini PetscFunctionBegin; 32856282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 32956282151SStefano Zampini if (pcbddc->user_primal_vertices_local) { 33056282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices_local,&isequal);CHKERRQ(ierr); 33156282151SStefano Zampini } 332674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 33330368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 33430368db7SStefano Zampini pcbddc->user_primal_vertices_local = PrimalVertices; 33556282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 336674ae819SStefano Zampini PetscFunctionReturn(0); 337674ae819SStefano Zampini } 338674ae819SStefano Zampini #undef __FUNCT__ 339674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS" 340674ae819SStefano Zampini /*@ 34128509bceSStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC 342674ae819SStefano Zampini 34317eb1463SStefano Zampini Collective 344674ae819SStefano Zampini 345674ae819SStefano Zampini Input Parameters: 346674ae819SStefano Zampini + pc - the preconditioning context 34717eb1463SStefano Zampini - PrimalVertices - index set of primal vertices in local numbering (can be empty) 348674ae819SStefano Zampini 349674ae819SStefano Zampini Level: intermediate 350674ae819SStefano Zampini 351674ae819SStefano Zampini Notes: 352674ae819SStefano Zampini 353674ae819SStefano Zampini .seealso: PCBDDC 354674ae819SStefano Zampini @*/ 355674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 356674ae819SStefano Zampini { 357674ae819SStefano Zampini PetscErrorCode ierr; 358674ae819SStefano Zampini 359674ae819SStefano Zampini PetscFunctionBegin; 360674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 361674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 36217eb1463SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 363674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 364674ae819SStefano Zampini PetscFunctionReturn(0); 365674ae819SStefano Zampini } 366674ae819SStefano Zampini /* -------------------------------------------------------------------------- */ 3670c7d97c5SJed Brown #undef __FUNCT__ 3684fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio_BDDC" 3694fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 3704fad6a16SStefano Zampini { 3714fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3724fad6a16SStefano Zampini 3734fad6a16SStefano Zampini PetscFunctionBegin; 3744fad6a16SStefano Zampini pcbddc->coarsening_ratio = k; 3754fad6a16SStefano Zampini PetscFunctionReturn(0); 3764fad6a16SStefano Zampini } 3771e6b0712SBarry Smith 3784fad6a16SStefano Zampini #undef __FUNCT__ 3794fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio" 3804fad6a16SStefano Zampini /*@ 38128509bceSStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel 3824fad6a16SStefano Zampini 3834fad6a16SStefano Zampini Logically collective on PC 3844fad6a16SStefano Zampini 3854fad6a16SStefano Zampini Input Parameters: 3864fad6a16SStefano Zampini + pc - the preconditioning context 38728509bceSStefano Zampini - k - coarsening ratio (H/h at the coarser level) 3884fad6a16SStefano Zampini 3890f202f7eSStefano Zampini Options Database Keys: 3900f202f7eSStefano Zampini . -pc_bddc_coarsening_ratio 3914fad6a16SStefano Zampini 3924fad6a16SStefano Zampini Level: intermediate 3934fad6a16SStefano Zampini 3944fad6a16SStefano Zampini Notes: 3950f202f7eSStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level 3964fad6a16SStefano Zampini 3970f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetLevels() 3984fad6a16SStefano Zampini @*/ 3994fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 4004fad6a16SStefano Zampini { 4014fad6a16SStefano Zampini PetscErrorCode ierr; 4024fad6a16SStefano Zampini 4034fad6a16SStefano Zampini PetscFunctionBegin; 4044fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 4052b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,k,2); 4064fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 4074fad6a16SStefano Zampini PetscFunctionReturn(0); 4084fad6a16SStefano Zampini } 4092b510759SStefano Zampini 410b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */ 4112b510759SStefano Zampini #undef __FUNCT__ 412b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet_BDDC" 413b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg) 414b8ffe317SStefano Zampini { 415b8ffe317SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 416b8ffe317SStefano Zampini 417b8ffe317SStefano Zampini PetscFunctionBegin; 41885c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = flg; 419b8ffe317SStefano Zampini PetscFunctionReturn(0); 420b8ffe317SStefano Zampini } 421b8ffe317SStefano Zampini 422b8ffe317SStefano Zampini #undef __FUNCT__ 423b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet" 424b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg) 4252b510759SStefano Zampini { 4262b510759SStefano Zampini PetscErrorCode ierr; 4272b510759SStefano Zampini 4282b510759SStefano Zampini PetscFunctionBegin; 4292b510759SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 430b8ffe317SStefano Zampini PetscValidLogicalCollectiveBool(pc,flg,2); 431b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr); 4322b510759SStefano Zampini PetscFunctionReturn(0); 4332b510759SStefano Zampini } 4341e6b0712SBarry Smith 4354fad6a16SStefano Zampini #undef __FUNCT__ 4362b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel_BDDC" 4372b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level) 4384fad6a16SStefano Zampini { 4394fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4404fad6a16SStefano Zampini 4414fad6a16SStefano Zampini PetscFunctionBegin; 4422b510759SStefano Zampini pcbddc->current_level = level; 4434fad6a16SStefano Zampini PetscFunctionReturn(0); 4444fad6a16SStefano Zampini } 4451e6b0712SBarry Smith 4464fad6a16SStefano Zampini #undef __FUNCT__ 447b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel" 448b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 449b8ffe317SStefano Zampini { 450b8ffe317SStefano Zampini PetscErrorCode ierr; 451b8ffe317SStefano Zampini 452b8ffe317SStefano Zampini PetscFunctionBegin; 453b8ffe317SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 454b8ffe317SStefano Zampini PetscValidLogicalCollectiveInt(pc,level,2); 455b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr); 456b8ffe317SStefano Zampini PetscFunctionReturn(0); 457b8ffe317SStefano Zampini } 458b8ffe317SStefano Zampini 459b8ffe317SStefano Zampini #undef __FUNCT__ 4602b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels_BDDC" 4612b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels) 4622b510759SStefano Zampini { 4632b510759SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4642b510759SStefano Zampini 4652b510759SStefano Zampini PetscFunctionBegin; 4662b510759SStefano Zampini pcbddc->max_levels = levels; 4672b510759SStefano Zampini PetscFunctionReturn(0); 4682b510759SStefano Zampini } 4692b510759SStefano Zampini 4702b510759SStefano Zampini #undef __FUNCT__ 4712b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels" 4724fad6a16SStefano Zampini /*@ 47328509bceSStefano Zampini PCBDDCSetLevels - Sets the maximum number of levels for multilevel 4744fad6a16SStefano Zampini 4754fad6a16SStefano Zampini Logically collective on PC 4764fad6a16SStefano Zampini 4774fad6a16SStefano Zampini Input Parameters: 4784fad6a16SStefano Zampini + pc - the preconditioning context 47928509bceSStefano Zampini - levels - the maximum number of levels (max 9) 4804fad6a16SStefano Zampini 4810f202f7eSStefano Zampini Options Database Keys: 4820f202f7eSStefano Zampini . -pc_bddc_levels 4834fad6a16SStefano Zampini 4844fad6a16SStefano Zampini Level: intermediate 4854fad6a16SStefano Zampini 4864fad6a16SStefano Zampini Notes: 4870f202f7eSStefano Zampini Default value is 0, i.e. traditional one-level BDDC 4884fad6a16SStefano Zampini 4890f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetCoarseningRatio() 4904fad6a16SStefano Zampini @*/ 4912b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels) 4924fad6a16SStefano Zampini { 4934fad6a16SStefano Zampini PetscErrorCode ierr; 4944fad6a16SStefano Zampini 4954fad6a16SStefano Zampini PetscFunctionBegin; 4964fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 4972b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,levels,2); 498312be037SStefano Zampini if (levels > 99) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Maximum number of levels for bddc is 99\n"); 4992b510759SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr); 5004fad6a16SStefano Zampini PetscFunctionReturn(0); 5014fad6a16SStefano Zampini } 5024fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 5031e6b0712SBarry Smith 5044fad6a16SStefano Zampini #undef __FUNCT__ 5053b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC" 5063b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 5073b03a366Sstefano_zampini { 5083b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 50956282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 5103b03a366Sstefano_zampini PetscErrorCode ierr; 5113b03a366Sstefano_zampini 5123b03a366Sstefano_zampini PetscFunctionBegin; 51356282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 51456282151SStefano Zampini if (pcbddc->DirichletBoundaries) { 51556282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundaries,&isequal);CHKERRQ(ierr); 51656282151SStefano Zampini } 517785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 518785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 5193b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 52036e030ebSStefano Zampini pcbddc->DirichletBoundaries = DirichletBoundaries; 52156282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 5223b03a366Sstefano_zampini PetscFunctionReturn(0); 5233b03a366Sstefano_zampini } 5241e6b0712SBarry Smith 5253b03a366Sstefano_zampini #undef __FUNCT__ 5263b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries" 5273b03a366Sstefano_zampini /*@ 52828509bceSStefano Zampini PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem. 5293b03a366Sstefano_zampini 530785d1243SStefano Zampini Collective 5313b03a366Sstefano_zampini 5323b03a366Sstefano_zampini Input Parameters: 5333b03a366Sstefano_zampini + pc - the preconditioning context 534785d1243SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries 5353b03a366Sstefano_zampini 5363b03a366Sstefano_zampini Level: intermediate 5373b03a366Sstefano_zampini 5380f202f7eSStefano Zampini Notes: 5390f202f7eSStefano Zampini Provide the information if you used MatZeroRows/Columns routines. Any process can list any global node 5403b03a366Sstefano_zampini 5410f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundariesLocal(), MatZeroRows(), MatZeroRowsColumns() 5423b03a366Sstefano_zampini @*/ 5433b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 5443b03a366Sstefano_zampini { 5453b03a366Sstefano_zampini PetscErrorCode ierr; 5463b03a366Sstefano_zampini 5473b03a366Sstefano_zampini PetscFunctionBegin; 5483b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 549674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 550785d1243SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 5513b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 5523b03a366Sstefano_zampini PetscFunctionReturn(0); 5533b03a366Sstefano_zampini } 5543b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 5551e6b0712SBarry Smith 5563b03a366Sstefano_zampini #undef __FUNCT__ 55782ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal_BDDC" 55882ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries) 5590c7d97c5SJed Brown { 5600c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 56156282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 5620c7d97c5SJed Brown PetscErrorCode ierr; 5630c7d97c5SJed Brown 5640c7d97c5SJed Brown PetscFunctionBegin; 56556282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 56656282151SStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 56756282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundariesLocal,&isequal);CHKERRQ(ierr); 56856282151SStefano Zampini } 569785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 570785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 5710c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 572785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = DirichletBoundaries; 57356282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 5740c7d97c5SJed Brown PetscFunctionReturn(0); 5750c7d97c5SJed Brown } 5760c7d97c5SJed Brown 5770c7d97c5SJed Brown #undef __FUNCT__ 57882ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal" 5799c0446d6SStefano Zampini /*@ 58082ba6b80SStefano Zampini PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering. 5819c0446d6SStefano Zampini 582785d1243SStefano Zampini Collective 58353cdbc3dSStefano Zampini 58453cdbc3dSStefano Zampini Input Parameters: 58553cdbc3dSStefano Zampini + pc - the preconditioning context 58682ba6b80SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering) 58753cdbc3dSStefano Zampini 58853cdbc3dSStefano Zampini Level: intermediate 58953cdbc3dSStefano Zampini 5909c0446d6SStefano Zampini Notes: 59153cdbc3dSStefano Zampini 5920f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundaries(), MatZeroRows(), MatZeroRowsColumns() 59353cdbc3dSStefano Zampini @*/ 59482ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries) 5950c7d97c5SJed Brown { 5960c7d97c5SJed Brown PetscErrorCode ierr; 5970c7d97c5SJed Brown 5980c7d97c5SJed Brown PetscFunctionBegin; 5990c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6000c7d97c5SJed Brown PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 60182ba6b80SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 60282ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 6030c7d97c5SJed Brown PetscFunctionReturn(0); 6040c7d97c5SJed Brown } 6050c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 6060c7d97c5SJed Brown 6070c7d97c5SJed Brown #undef __FUNCT__ 6080c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 60953cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 6100c7d97c5SJed Brown { 6110c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 61256282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 61353cdbc3dSStefano Zampini PetscErrorCode ierr; 6140c7d97c5SJed Brown 6150c7d97c5SJed Brown PetscFunctionBegin; 61656282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 61756282151SStefano Zampini if (pcbddc->NeumannBoundaries) { 61856282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundaries,&isequal);CHKERRQ(ierr); 61956282151SStefano Zampini } 620785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 621785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 62253cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 62336e030ebSStefano Zampini pcbddc->NeumannBoundaries = NeumannBoundaries; 62456282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 6250c7d97c5SJed Brown PetscFunctionReturn(0); 6260c7d97c5SJed Brown } 6271e6b0712SBarry Smith 6280c7d97c5SJed Brown #undef __FUNCT__ 6290c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 63057527edcSJed Brown /*@ 63128509bceSStefano Zampini PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem. 63257527edcSJed Brown 633785d1243SStefano Zampini Collective 63457527edcSJed Brown 63557527edcSJed Brown Input Parameters: 63657527edcSJed Brown + pc - the preconditioning context 637785d1243SStefano Zampini - NeumannBoundaries - parallel IS defining the Neumann boundaries 63857527edcSJed Brown 63957527edcSJed Brown Level: intermediate 64057527edcSJed Brown 6410f202f7eSStefano Zampini Notes: 6420f202f7eSStefano Zampini Any process can list any global node 64357527edcSJed Brown 6440f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundariesLocal() 64557527edcSJed Brown @*/ 64653cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 6470c7d97c5SJed Brown { 6480c7d97c5SJed Brown PetscErrorCode ierr; 6490c7d97c5SJed Brown 6500c7d97c5SJed Brown PetscFunctionBegin; 6510c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 652674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 653785d1243SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 65453cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 65553cdbc3dSStefano Zampini PetscFunctionReturn(0); 65653cdbc3dSStefano Zampini } 65753cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 6581e6b0712SBarry Smith 65953cdbc3dSStefano Zampini #undef __FUNCT__ 66082ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal_BDDC" 66182ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries) 6620c7d97c5SJed Brown { 6630c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 66456282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 6650c7d97c5SJed Brown PetscErrorCode ierr; 6660c7d97c5SJed Brown 6670c7d97c5SJed Brown PetscFunctionBegin; 66856282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 66956282151SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 67056282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundariesLocal,&isequal);CHKERRQ(ierr); 67156282151SStefano Zampini } 672785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 673785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 6740c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 675785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = NeumannBoundaries; 67656282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 6770c7d97c5SJed Brown PetscFunctionReturn(0); 6780c7d97c5SJed Brown } 6790c7d97c5SJed Brown 6800c7d97c5SJed Brown #undef __FUNCT__ 68182ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal" 6820c7d97c5SJed Brown /*@ 68382ba6b80SStefano Zampini PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering. 6840c7d97c5SJed Brown 685785d1243SStefano Zampini Collective 6860c7d97c5SJed Brown 6870c7d97c5SJed Brown Input Parameters: 6880c7d97c5SJed Brown + pc - the preconditioning context 68982ba6b80SStefano Zampini - NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering) 6900c7d97c5SJed Brown 6910c7d97c5SJed Brown Level: intermediate 6920c7d97c5SJed Brown 6930c7d97c5SJed Brown Notes: 6940c7d97c5SJed Brown 6950f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundaries() 6960c7d97c5SJed Brown @*/ 69782ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries) 6980c7d97c5SJed Brown { 6990c7d97c5SJed Brown PetscErrorCode ierr; 7000c7d97c5SJed Brown 7010c7d97c5SJed Brown PetscFunctionBegin; 7020c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 7030c7d97c5SJed Brown PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 70482ba6b80SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 70582ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 70653cdbc3dSStefano Zampini PetscFunctionReturn(0); 70753cdbc3dSStefano Zampini } 70853cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 70953cdbc3dSStefano Zampini 71053cdbc3dSStefano Zampini #undef __FUNCT__ 711da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC" 712da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 713da1bb401SStefano Zampini { 714da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 715da1bb401SStefano Zampini 716da1bb401SStefano Zampini PetscFunctionBegin; 717da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 718da1bb401SStefano Zampini PetscFunctionReturn(0); 719da1bb401SStefano Zampini } 7201e6b0712SBarry Smith 721da1bb401SStefano Zampini #undef __FUNCT__ 722da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries" 723da1bb401SStefano Zampini /*@ 724785d1243SStefano Zampini PCBDDCGetDirichletBoundaries - Get parallel IS for Dirichlet boundaries 725da1bb401SStefano Zampini 726785d1243SStefano Zampini Collective 727785d1243SStefano Zampini 728785d1243SStefano Zampini Input Parameters: 729785d1243SStefano Zampini . pc - the preconditioning context 730785d1243SStefano Zampini 731785d1243SStefano Zampini Output Parameters: 732785d1243SStefano Zampini . DirichletBoundaries - index set defining the Dirichlet boundaries 733785d1243SStefano Zampini 734785d1243SStefano Zampini Level: intermediate 735785d1243SStefano Zampini 7360f202f7eSStefano Zampini Notes: 7370f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetDirichletBoundaries 738785d1243SStefano Zampini 739785d1243SStefano Zampini .seealso: PCBDDC 740785d1243SStefano Zampini @*/ 741785d1243SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 742785d1243SStefano Zampini { 743785d1243SStefano Zampini PetscErrorCode ierr; 744785d1243SStefano Zampini 745785d1243SStefano Zampini PetscFunctionBegin; 746785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 747785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 748785d1243SStefano Zampini PetscFunctionReturn(0); 749785d1243SStefano Zampini } 750785d1243SStefano Zampini /* -------------------------------------------------------------------------- */ 751785d1243SStefano Zampini 752785d1243SStefano Zampini #undef __FUNCT__ 753785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal_BDDC" 754785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries) 755785d1243SStefano Zampini { 756785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 757785d1243SStefano Zampini 758785d1243SStefano Zampini PetscFunctionBegin; 759785d1243SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundariesLocal; 760785d1243SStefano Zampini PetscFunctionReturn(0); 761785d1243SStefano Zampini } 762785d1243SStefano Zampini 763785d1243SStefano Zampini #undef __FUNCT__ 76482ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal" 765da1bb401SStefano Zampini /*@ 76682ba6b80SStefano Zampini PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering) 767da1bb401SStefano Zampini 768785d1243SStefano Zampini Collective 769da1bb401SStefano Zampini 770da1bb401SStefano Zampini Input Parameters: 77128509bceSStefano Zampini . pc - the preconditioning context 772da1bb401SStefano Zampini 773da1bb401SStefano Zampini Output Parameters: 77428509bceSStefano Zampini . DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 775da1bb401SStefano Zampini 776da1bb401SStefano Zampini Level: intermediate 777da1bb401SStefano Zampini 778da1bb401SStefano Zampini Notes: 7790f202f7eSStefano 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). 7800f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 781da1bb401SStefano Zampini 782da1bb401SStefano Zampini .seealso: PCBDDC 783da1bb401SStefano Zampini @*/ 78482ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries) 785da1bb401SStefano Zampini { 786da1bb401SStefano Zampini PetscErrorCode ierr; 787da1bb401SStefano Zampini 788da1bb401SStefano Zampini PetscFunctionBegin; 789da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 79082ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 791da1bb401SStefano Zampini PetscFunctionReturn(0); 792da1bb401SStefano Zampini } 793da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 7941e6b0712SBarry Smith 795da1bb401SStefano Zampini #undef __FUNCT__ 79653cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 79753cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 79853cdbc3dSStefano Zampini { 79953cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 80053cdbc3dSStefano Zampini 80153cdbc3dSStefano Zampini PetscFunctionBegin; 80253cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 80353cdbc3dSStefano Zampini PetscFunctionReturn(0); 80453cdbc3dSStefano Zampini } 8051e6b0712SBarry Smith 80653cdbc3dSStefano Zampini #undef __FUNCT__ 80753cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 80853cdbc3dSStefano Zampini /*@ 809785d1243SStefano Zampini PCBDDCGetNeumannBoundaries - Get parallel IS for Neumann boundaries 81053cdbc3dSStefano Zampini 811785d1243SStefano Zampini Collective 812785d1243SStefano Zampini 813785d1243SStefano Zampini Input Parameters: 814785d1243SStefano Zampini . pc - the preconditioning context 815785d1243SStefano Zampini 816785d1243SStefano Zampini Output Parameters: 817785d1243SStefano Zampini . NeumannBoundaries - index set defining the Neumann boundaries 818785d1243SStefano Zampini 819785d1243SStefano Zampini Level: intermediate 820785d1243SStefano Zampini 8210f202f7eSStefano Zampini Notes: 8220f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetNeumannBoundaries 823785d1243SStefano Zampini 824785d1243SStefano Zampini .seealso: PCBDDC 825785d1243SStefano Zampini @*/ 826785d1243SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 827785d1243SStefano Zampini { 828785d1243SStefano Zampini PetscErrorCode ierr; 829785d1243SStefano Zampini 830785d1243SStefano Zampini PetscFunctionBegin; 831785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 832785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 833785d1243SStefano Zampini PetscFunctionReturn(0); 834785d1243SStefano Zampini } 835785d1243SStefano Zampini /* -------------------------------------------------------------------------- */ 836785d1243SStefano Zampini 837785d1243SStefano Zampini #undef __FUNCT__ 838785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal_BDDC" 839785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries) 840785d1243SStefano Zampini { 841785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 842785d1243SStefano Zampini 843785d1243SStefano Zampini PetscFunctionBegin; 844785d1243SStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundariesLocal; 845785d1243SStefano Zampini PetscFunctionReturn(0); 846785d1243SStefano Zampini } 847785d1243SStefano Zampini 848785d1243SStefano Zampini #undef __FUNCT__ 84982ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal" 85053cdbc3dSStefano Zampini /*@ 85182ba6b80SStefano Zampini PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering) 85253cdbc3dSStefano Zampini 853785d1243SStefano Zampini Collective 85453cdbc3dSStefano Zampini 85553cdbc3dSStefano Zampini Input Parameters: 85628509bceSStefano Zampini . pc - the preconditioning context 85753cdbc3dSStefano Zampini 85853cdbc3dSStefano Zampini Output Parameters: 85928509bceSStefano Zampini . NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 86053cdbc3dSStefano Zampini 86153cdbc3dSStefano Zampini Level: intermediate 86253cdbc3dSStefano Zampini 86353cdbc3dSStefano Zampini Notes: 8640f202f7eSStefano 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). 8650f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 86653cdbc3dSStefano Zampini 86753cdbc3dSStefano Zampini .seealso: PCBDDC 86853cdbc3dSStefano Zampini @*/ 86982ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries) 87053cdbc3dSStefano Zampini { 87153cdbc3dSStefano Zampini PetscErrorCode ierr; 87253cdbc3dSStefano Zampini 87353cdbc3dSStefano Zampini PetscFunctionBegin; 87453cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 87582ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 8760c7d97c5SJed Brown PetscFunctionReturn(0); 8770c7d97c5SJed Brown } 87836e030ebSStefano Zampini /* -------------------------------------------------------------------------- */ 8791e6b0712SBarry Smith 88036e030ebSStefano Zampini #undef __FUNCT__ 881da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC" 8821a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 88336e030ebSStefano Zampini { 88436e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 885da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 88656282151SStefano Zampini PetscBool same_data = PETSC_FALSE; 887da1bb401SStefano Zampini PetscErrorCode ierr; 88836e030ebSStefano Zampini 88936e030ebSStefano Zampini PetscFunctionBegin; 8908687889aSStefano Zampini if (!nvtxs) { 8918687889aSStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 8928687889aSStefano Zampini PetscFunctionReturn(0); 8938687889aSStefano Zampini } 89456282151SStefano Zampini if (mat_graph->nvtxs_csr == nvtxs) { 89556282151SStefano Zampini if (mat_graph->xadj == xadj && mat_graph->adjncy == adjncy) same_data = PETSC_TRUE; 89656282151SStefano Zampini if (!same_data && mat_graph->xadj[nvtxs] == xadj[nvtxs]) { 89756282151SStefano Zampini ierr = PetscMemcmp(adjncy,mat_graph->adjncy,nvtxs*sizeof(PetscInt),&same_data);CHKERRQ(ierr); 89856282151SStefano Zampini } 89956282151SStefano Zampini } 90056282151SStefano Zampini if (!same_data) { 901674ae819SStefano Zampini /* free old CSR */ 902674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 903674ae819SStefano Zampini /* get CSR into graph structure */ 904da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 905854ce69bSBarry Smith ierr = PetscMalloc1(nvtxs+1,&mat_graph->xadj);CHKERRQ(ierr); 906785e854fSJed Brown ierr = PetscMalloc1(xadj[nvtxs],&mat_graph->adjncy);CHKERRQ(ierr); 907674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 908674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 909da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 9101a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 9111a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 912674ae819SStefano Zampini } 913575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 91456282151SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 91556282151SStefano Zampini } 91636e030ebSStefano Zampini PetscFunctionReturn(0); 91736e030ebSStefano Zampini } 9181e6b0712SBarry Smith 91936e030ebSStefano Zampini #undef __FUNCT__ 920da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph" 92136e030ebSStefano Zampini /*@ 9220f202f7eSStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local matrix 92336e030ebSStefano Zampini 92436e030ebSStefano Zampini Not collective 92536e030ebSStefano Zampini 92636e030ebSStefano Zampini Input Parameters: 92736e030ebSStefano Zampini + pc - the preconditioning context 9280f202f7eSStefano Zampini . nvtxs - number of local vertices of the graph (i.e., the size of the local problem) 92928509bceSStefano Zampini . xadj, adjncy - the CSR graph 93028509bceSStefano Zampini - copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER. 93136e030ebSStefano Zampini 93236e030ebSStefano Zampini Level: intermediate 93336e030ebSStefano Zampini 93436e030ebSStefano Zampini Notes: 93536e030ebSStefano Zampini 93628509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode 93736e030ebSStefano Zampini @*/ 9381a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 93936e030ebSStefano Zampini { 940575ad6abSStefano Zampini void (*f)(void) = 0; 94136e030ebSStefano Zampini PetscErrorCode ierr; 94236e030ebSStefano Zampini 94336e030ebSStefano Zampini PetscFunctionBegin; 94436e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 9458687889aSStefano Zampini if (nvtxs) { 946674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 947d7de1dd9SStefano Zampini PetscValidIntPointer(adjncy,4); 9488687889aSStefano Zampini } 9496c4ed002SBarry Smith if (copymode != PETSC_COPY_VALUES && copymode != PETSC_OWN_POINTER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d",copymode); 9501a83f524SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 951575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 952575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 953575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 954575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 955575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 956da1bb401SStefano Zampini } 95736e030ebSStefano Zampini PetscFunctionReturn(0); 95836e030ebSStefano Zampini } 9599c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 9601e6b0712SBarry Smith 9619c0446d6SStefano Zampini #undef __FUNCT__ 96263602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal_BDDC" 96363602bcaSStefano Zampini static PetscErrorCode PCBDDCSetDofsSplittingLocal_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 96463602bcaSStefano Zampini { 96563602bcaSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 96663602bcaSStefano Zampini PetscInt i; 96756282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 96863602bcaSStefano Zampini PetscErrorCode ierr; 96963602bcaSStefano Zampini 97063602bcaSStefano Zampini PetscFunctionBegin; 97156282151SStefano Zampini if (pcbddc->n_ISForDofsLocal == n_is) { 97256282151SStefano Zampini for (i=0;i<n_is;i++) { 97356282151SStefano Zampini PetscBool isequalt; 97456282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofsLocal[i],&isequalt);CHKERRQ(ierr); 97556282151SStefano Zampini if (!isequalt) break; 97656282151SStefano Zampini } 97756282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 97856282151SStefano Zampini } 97956282151SStefano Zampini for (i=0;i<n_is;i++) { 98056282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 98156282151SStefano Zampini } 98263602bcaSStefano Zampini /* Destroy ISes if they were already set */ 98363602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 98463602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 98563602bcaSStefano Zampini } 98663602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 98763602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 98863602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 98963602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 99063602bcaSStefano Zampini } 99163602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 99263602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 99363602bcaSStefano Zampini /* allocate space then set */ 994d02579f5SStefano Zampini if (n_is) { 995d02579f5SStefano Zampini ierr = PetscMalloc1(n_is,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 996d02579f5SStefano Zampini } 99763602bcaSStefano Zampini for (i=0;i<n_is;i++) { 99863602bcaSStefano Zampini pcbddc->ISForDofsLocal[i] = ISForDofs[i]; 99963602bcaSStefano Zampini } 100063602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = n_is; 100163602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 100256282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 100363602bcaSStefano Zampini PetscFunctionReturn(0); 100463602bcaSStefano Zampini } 100563602bcaSStefano Zampini 100663602bcaSStefano Zampini #undef __FUNCT__ 100763602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal" 100863602bcaSStefano Zampini /*@ 100963602bcaSStefano Zampini PCBDDCSetDofsSplittingLocal - Set index sets defining fields of the local subdomain matrix 101063602bcaSStefano Zampini 101163602bcaSStefano Zampini Collective 101263602bcaSStefano Zampini 101363602bcaSStefano Zampini Input Parameters: 101463602bcaSStefano Zampini + pc - the preconditioning context 10150f202f7eSStefano Zampini . n_is - number of index sets defining the fields 10160f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in local ordering 101763602bcaSStefano Zampini 101863602bcaSStefano Zampini Level: intermediate 101963602bcaSStefano Zampini 10200f202f7eSStefano Zampini Notes: 10210f202f7eSStefano Zampini n_is should be the same among processes. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 102263602bcaSStefano Zampini 102363602bcaSStefano Zampini .seealso: PCBDDC 102463602bcaSStefano Zampini @*/ 102563602bcaSStefano Zampini PetscErrorCode PCBDDCSetDofsSplittingLocal(PC pc,PetscInt n_is, IS ISForDofs[]) 102663602bcaSStefano Zampini { 102763602bcaSStefano Zampini PetscInt i; 102863602bcaSStefano Zampini PetscErrorCode ierr; 102963602bcaSStefano Zampini 103063602bcaSStefano Zampini PetscFunctionBegin; 103163602bcaSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 103263602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 103363602bcaSStefano Zampini for (i=0;i<n_is;i++) { 103463602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 103563602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 103663602bcaSStefano Zampini } 1037e71e7a71SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplittingLocal_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 103863602bcaSStefano Zampini PetscFunctionReturn(0); 103963602bcaSStefano Zampini } 104063602bcaSStefano Zampini /* -------------------------------------------------------------------------- */ 104163602bcaSStefano Zampini 104263602bcaSStefano Zampini #undef __FUNCT__ 10439c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 10449c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 10459c0446d6SStefano Zampini { 10469c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 10479c0446d6SStefano Zampini PetscInt i; 104856282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 10499c0446d6SStefano Zampini PetscErrorCode ierr; 10509c0446d6SStefano Zampini 10519c0446d6SStefano Zampini PetscFunctionBegin; 105256282151SStefano Zampini if (pcbddc->n_ISForDofs == n_is) { 105356282151SStefano Zampini for (i=0;i<n_is;i++) { 105456282151SStefano Zampini PetscBool isequalt; 105556282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofs[i],&isequalt);CHKERRQ(ierr); 105656282151SStefano Zampini if (!isequalt) break; 105756282151SStefano Zampini } 105856282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 105956282151SStefano Zampini } 106056282151SStefano Zampini for (i=0;i<n_is;i++) { 106156282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 106256282151SStefano Zampini } 1063da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 10649c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 10659c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 10669c0446d6SStefano Zampini } 1067d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 106863602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 106963602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 107063602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 107163602bcaSStefano Zampini } 107263602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 107363602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 1074da1bb401SStefano Zampini /* allocate space then set */ 1075d02579f5SStefano Zampini if (n_is) { 1076785e854fSJed Brown ierr = PetscMalloc1(n_is,&pcbddc->ISForDofs);CHKERRQ(ierr); 1077d02579f5SStefano Zampini } 10789c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 1079da1bb401SStefano Zampini pcbddc->ISForDofs[i] = ISForDofs[i]; 10809c0446d6SStefano Zampini } 10819c0446d6SStefano Zampini pcbddc->n_ISForDofs = n_is; 108263602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 108356282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 10849c0446d6SStefano Zampini PetscFunctionReturn(0); 10859c0446d6SStefano Zampini } 10861e6b0712SBarry Smith 10879c0446d6SStefano Zampini #undef __FUNCT__ 10889c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 10899c0446d6SStefano Zampini /*@ 109063602bcaSStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of the global matrix 10919c0446d6SStefano Zampini 109263602bcaSStefano Zampini Collective 10939c0446d6SStefano Zampini 10949c0446d6SStefano Zampini Input Parameters: 10959c0446d6SStefano Zampini + pc - the preconditioning context 10960f202f7eSStefano Zampini . n_is - number of index sets defining the fields 10970f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in global ordering 10989c0446d6SStefano Zampini 10999c0446d6SStefano Zampini Level: intermediate 11009c0446d6SStefano Zampini 11010f202f7eSStefano Zampini Notes: 11020f202f7eSStefano Zampini Any process can list any global node. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 11039c0446d6SStefano Zampini 11049c0446d6SStefano Zampini .seealso: PCBDDC 11059c0446d6SStefano Zampini @*/ 11069c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 11079c0446d6SStefano Zampini { 11082b510759SStefano Zampini PetscInt i; 11099c0446d6SStefano Zampini PetscErrorCode ierr; 11109c0446d6SStefano Zampini 11119c0446d6SStefano Zampini PetscFunctionBegin; 11129c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 111363602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 11142b510759SStefano Zampini for (i=0;i<n_is;i++) { 111563602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 111663602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 11172b510759SStefano Zampini } 11189c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 11199c0446d6SStefano Zampini PetscFunctionReturn(0); 11209c0446d6SStefano Zampini } 1121906d46d4SStefano Zampini 1122da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 1123534831adSStefano Zampini #undef __FUNCT__ 1124534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC" 1125534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 1126534831adSStefano Zampini /* 1127534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 1128534831adSStefano Zampini guess if a transformation of basis approach has been selected. 11299c0446d6SStefano Zampini 1130534831adSStefano Zampini Input Parameter: 1131534831adSStefano Zampini + pc - the preconditioner contex 1132534831adSStefano Zampini 1133534831adSStefano Zampini Application Interface Routine: PCPreSolve() 1134534831adSStefano Zampini 1135534831adSStefano Zampini Notes: 1136534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 1137534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1138534831adSStefano Zampini */ 1139534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1140534831adSStefano Zampini { 1141534831adSStefano Zampini PetscErrorCode ierr; 1142534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1143534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 11443972b0daSStefano Zampini Vec used_vec; 114527b6a85dSStefano Zampini PetscBool save_rhs = PETSC_TRUE, benign_correction_computed; 1146534831adSStefano Zampini 1147534831adSStefano Zampini PetscFunctionBegin; 11481f4df5f7SStefano Zampini /* if we are working with CG, one dirichlet solve can be avoided during Krylov iterations */ 114985c4d303SStefano Zampini if (ksp) { 11501f4df5f7SStefano Zampini PetscBool iscg, isgroppcg, ispipecg, ispipecgrr; 115185c4d303SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr); 115227b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPGROPPCG,&isgroppcg);CHKERRQ(ierr); 115327b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECG,&ispipecg);CHKERRQ(ierr); 1154f94e96cbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECGRR,&ispipecgrr);CHKERRQ(ierr); 11551f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static || (!iscg && !isgroppcg && !ispipecg && !ispipecgrr)) { 115685c4d303SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 115785c4d303SStefano Zampini } 115885c4d303SStefano Zampini } 1159fc17d649SStefano Zampini if (pcbddc->benign_apply_coarse_only || pcbddc->switch_static) { 1160fc17d649SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 1161fc17d649SStefano Zampini } 11621f4df5f7SStefano Zampini 116385c4d303SStefano Zampini /* Creates parallel work vectors used in presolve */ 116462a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 116562a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 116662a6ff1dSStefano Zampini } 116762a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 116862a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 116962a6ff1dSStefano Zampini } 11708d00608fSStefano Zampini 117127b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_FALSE; 11723972b0daSStefano Zampini if (x) { 11733972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 11743972b0daSStefano Zampini used_vec = x; 11758d00608fSStefano Zampini } else { /* it can only happen when calling PCBDDCMatFETIDPGetRHS */ 11763972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 11773972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 11783972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 117927b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 1180266e20e9SStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 1181266e20e9SStefano Zampini save_rhs = PETSC_FALSE; 1182266e20e9SStefano Zampini pcbddc->eliminate_dirdofs = PETSC_TRUE; 11833972b0daSStefano Zampini } 11848efcfb23SStefano Zampini 11858efcfb23SStefano Zampini /* hack into ksp data structure since PCPreSolve comes earlier than setting to zero the guess in src/ksp/ksp/interface/itfunc.c */ 11863972b0daSStefano Zampini if (ksp) { 1187a0cb1b98SStefano Zampini /* store the flag for the initial guess since it will be restored back during PCPostSolve_BDDC */ 11888efcfb23SStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 11898efcfb23SStefano Zampini if (!pcbddc->ksp_guess_nonzero) { 11903972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 11913972b0daSStefano Zampini } 11923972b0daSStefano Zampini } 11933308cffdSStefano Zampini 11948d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 11953972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 119670c64980SStefano Zampini if (rhs && pcbddc->eliminate_dirdofs) { 11973975b054SStefano Zampini IS dirIS = NULL; 11983975b054SStefano Zampini 1199a07ea27aSStefano Zampini /* DirichletBoundariesLocal may not be consistent among neighbours; gets a dirichlet dofs IS from graph (may be cached) */ 12003975b054SStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 12013975b054SStefano Zampini if (dirIS) { 1202906d46d4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1203785d1243SStefano Zampini PetscInt dirsize,i,*is_indices; 12042b095fd8SStefano Zampini PetscScalar *array_x; 12052b095fd8SStefano Zampini const PetscScalar *array_diagonal; 1206785d1243SStefano Zampini 12073972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 12083972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 1209e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1210e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1211e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1212e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 121382ba6b80SStefano Zampini ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr); 12143972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 12152b095fd8SStefano Zampini ierr = VecGetArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 12163972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 12172fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 12183972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 12192b095fd8SStefano Zampini ierr = VecRestoreArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 12203972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 1221e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1222e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 12238d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 12241b968477SStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 12258efcfb23SStefano Zampini } 1226a07ea27aSStefano Zampini } 1227b76ba322SStefano Zampini 12288efcfb23SStefano Zampini /* remove the computed solution or the initial guess from the rhs */ 12298d00608fSStefano Zampini if (pcbddc->rhs_change || (ksp && pcbddc->ksp_guess_nonzero) ) { 123027b6a85dSStefano Zampini /* save the original rhs */ 123127b6a85dSStefano Zampini if (save_rhs) { 123227b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 123327b6a85dSStefano Zampini save_rhs = PETSC_FALSE; 12348d00608fSStefano Zampini } 12358d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 12363972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 123727b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,used_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 12383972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 12398efcfb23SStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 124027b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 12417acc28cbSStefano Zampini if (ksp) { 12427acc28cbSStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_FALSE);CHKERRQ(ierr); 12437acc28cbSStefano Zampini } 12443308cffdSStefano Zampini } 12458efcfb23SStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 1246b76ba322SStefano Zampini 1247fc17d649SStefano Zampini /* compute initial vector in benign space if needed 124827b6a85dSStefano Zampini and remove non-benign solution from the rhs */ 124927b6a85dSStefano Zampini benign_correction_computed = PETSC_FALSE; 125027b6a85dSStefano Zampini if (rhs && pcbddc->benign_compute_correction && pcbddc->benign_have_null) { 12511f4df5f7SStefano Zampini /* compute u^*_h using ideas similar to those in Xuemin Tu's PhD thesis (see Section 4.8.1) 12521f4df5f7SStefano Zampini Recursively apply BDDC in the multilevel case */ 12530369aaf7SStefano Zampini if (!pcbddc->benign_vec) { 12540369aaf7SStefano Zampini ierr = VecDuplicate(rhs,&pcbddc->benign_vec);CHKERRQ(ierr); 12550369aaf7SStefano Zampini } 12564fee134fSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_TRUE; 125727b6a85dSStefano Zampini if (!pcbddc->benign_skip_correction) { 12581dd7afcfSStefano Zampini ierr = PCApply_BDDC(pc,rhs,pcbddc->benign_vec);CHKERRQ(ierr); 12593bca92a6SStefano Zampini benign_correction_computed = PETSC_TRUE; 12601f4df5f7SStefano Zampini if (pcbddc->temp_solution_used) { 12611f4df5f7SStefano Zampini ierr = VecAXPY(pcbddc->temp_solution,1.0,pcbddc->benign_vec);CHKERRQ(ierr); 12621f4df5f7SStefano Zampini } 12631f4df5f7SStefano Zampini ierr = VecScale(pcbddc->benign_vec,-1.0);CHKERRQ(ierr); 126427b6a85dSStefano Zampini /* store the original rhs if not done earlier */ 126527b6a85dSStefano Zampini if (save_rhs) { 126627b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 126727b6a85dSStefano Zampini save_rhs = PETSC_FALSE; 126892e3dcfbSStefano Zampini } 126927b6a85dSStefano Zampini if (pcbddc->rhs_change) { 12700369aaf7SStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,rhs,rhs);CHKERRQ(ierr); 127127b6a85dSStefano Zampini } else { 127227b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 127327b6a85dSStefano Zampini } 12740369aaf7SStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 127527b6a85dSStefano Zampini } 127627b6a85dSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_FALSE; 12770369aaf7SStefano Zampini } 12782d4c4fecSStefano Zampini 12792d4c4fecSStefano Zampini /* dbg output */ 12802d4c4fecSStefano Zampini if (pcbddc->dbg_flag && pcbddc->benign_have_null) { 12811f4df5f7SStefano Zampini Vec v; 12821f4df5f7SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&v);CHKERRQ(ierr); 12831f4df5f7SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,v);CHKERRQ(ierr); 12841f4df5f7SStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,v,PETSC_TRUE);CHKERRQ(ierr); 12852d4c4fecSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"LEVEL %d: IS CORRECTION BENIGN?\n",pcbddc->current_level);CHKERRQ(ierr); 12862d4c4fecSStefano Zampini ierr = PetscScalarView(pcbddc->benign_n,pcbddc->benign_p0,PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pc)));CHKERRQ(ierr); 12871f4df5f7SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 12881f4df5f7SStefano Zampini } 12890369aaf7SStefano Zampini 12900369aaf7SStefano Zampini /* set initial guess if using PCG */ 12910369aaf7SStefano Zampini if (x && pcbddc->use_exact_dirichlet_trick) { 12920369aaf7SStefano Zampini ierr = VecSet(x,0.0);CHKERRQ(ierr); 12931dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 129427b6a85dSStefano Zampini if (benign_correction_computed) { /* we have already saved the changed rhs */ 12951dd7afcfSStefano Zampini ierr = VecLockPop(pcis->vec1_global);CHKERRQ(ierr); 12961dd7afcfSStefano Zampini } else { 12971dd7afcfSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,pcis->vec1_global);CHKERRQ(ierr); 12981dd7afcfSStefano Zampini } 12991dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13001dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13011dd7afcfSStefano Zampini } else { 13020369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13030369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13041dd7afcfSStefano Zampini } 13050369aaf7SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 13061dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 13071dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.);CHKERRQ(ierr); 13081dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13091dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13101dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x);CHKERRQ(ierr); 13111dd7afcfSStefano Zampini } else { 13120369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13130369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13141dd7afcfSStefano Zampini } 13150369aaf7SStefano Zampini if (ksp) { 13160369aaf7SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 13170369aaf7SStefano Zampini } 1318266e20e9SStefano Zampini } else if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior && benign_correction_computed && pcbddc->use_exact_dirichlet_trick) { 1319266e20e9SStefano Zampini ierr = VecLockPop(pcis->vec1_global);CHKERRQ(ierr); 13200369aaf7SStefano Zampini } 1321534831adSStefano Zampini PetscFunctionReturn(0); 1322534831adSStefano Zampini } 1323906d46d4SStefano Zampini 1324534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 1325534831adSStefano Zampini #undef __FUNCT__ 1326534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC" 1327534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 1328534831adSStefano Zampini /* 1329534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 1330534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 1331534831adSStefano Zampini 1332534831adSStefano Zampini Input Parameter: 1333534831adSStefano Zampini + pc - the preconditioner contex 1334534831adSStefano Zampini 1335534831adSStefano Zampini Application Interface Routine: PCPostSolve() 1336534831adSStefano Zampini 1337534831adSStefano Zampini Notes: 1338534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 1339534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1340534831adSStefano Zampini */ 1341534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1342534831adSStefano Zampini { 1343534831adSStefano Zampini PetscErrorCode ierr; 1344534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1345534831adSStefano Zampini 1346534831adSStefano Zampini PetscFunctionBegin; 13473972b0daSStefano Zampini /* add solution removed in presolve */ 13486bcfc461SStefano Zampini if (x && pcbddc->rhs_change) { 134927b6a85dSStefano Zampini if (pcbddc->temp_solution_used) { 13503425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 135127b6a85dSStefano Zampini } else if (pcbddc->benign_compute_correction) { 135227b6a85dSStefano Zampini ierr = VecAXPY(x,-1.0,pcbddc->benign_vec);CHKERRQ(ierr); 13533425bc38SStefano Zampini } 135427b6a85dSStefano Zampini } 135527b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_FALSE; 135627b6a85dSStefano Zampini 1357266e20e9SStefano Zampini /* restore rhs to its original state (not needed for FETI-DP) */ 13588d00608fSStefano Zampini if (rhs && pcbddc->rhs_change) { 135927b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 1360fb223d50SStefano Zampini } 13618d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 13628efcfb23SStefano Zampini /* restore ksp guess state */ 13638efcfb23SStefano Zampini if (ksp) { 13648efcfb23SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 13658efcfb23SStefano Zampini } 1366534831adSStefano Zampini PetscFunctionReturn(0); 1367534831adSStefano Zampini } 1368534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 136953cdbc3dSStefano Zampini #undef __FUNCT__ 137053cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 13710c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 13720c7d97c5SJed Brown /* 13730c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 13740c7d97c5SJed Brown by setting data structures and options. 13750c7d97c5SJed Brown 13760c7d97c5SJed Brown Input Parameter: 137753cdbc3dSStefano Zampini + pc - the preconditioner context 13780c7d97c5SJed Brown 13790c7d97c5SJed Brown Application Interface Routine: PCSetUp() 13800c7d97c5SJed Brown 13810c7d97c5SJed Brown Notes: 13820c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 13830c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 13840c7d97c5SJed Brown */ 138553cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 13860c7d97c5SJed Brown { 13870c7d97c5SJed Brown PetscErrorCode ierr; 13880c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 13895e8657edSStefano Zampini Mat_IS* matis; 139008122e43SStefano Zampini MatNullSpace nearnullspace; 1391c9ed8603SStefano Zampini IS zerodiag = NULL; 139291e8d312SStefano Zampini PetscInt nrows,ncols; 139308122e43SStefano Zampini PetscBool computetopography,computesolvers,computesubschurs; 13948de1fae6SStefano Zampini PetscBool computeconstraintsmatrix; 13955e8657edSStefano Zampini PetscBool new_nearnullspace_provided,ismatis; 13960c7d97c5SJed Brown 13970c7d97c5SJed Brown PetscFunctionBegin; 13985e8657edSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATIS,&ismatis);CHKERRQ(ierr); 13996c4ed002SBarry Smith if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner requires matrix of type MATIS"); 140091e8d312SStefano Zampini ierr = MatGetSize(pc->pmat,&nrows,&ncols);CHKERRQ(ierr); 14016c4ed002SBarry Smith if (nrows != ncols) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PCBDDC preconditioner requires a square preconditioning matrix"); 14025e8657edSStefano Zampini matis = (Mat_IS*)pc->pmat->data; 1403f4ddd8eeSStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other future nonoverlapping preconditioners */ 14043b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 1405fcd409f5SStefano Zampini Also, BDDC directly build the Dirichlet problem */ 1406f4ddd8eeSStefano Zampini /* split work */ 1407674ae819SStefano Zampini if (pc->setupcalled) { 1408d1e9a80fSBarry Smith if (pc->flag == SAME_NONZERO_PATTERN) { 1409674ae819SStefano Zampini computetopography = PETSC_FALSE; 1410674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1411674ae819SStefano Zampini } else { /* DIFFERENT_NONZERO_PATTERN */ 1412674ae819SStefano Zampini computetopography = PETSC_TRUE; 1413674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1414674ae819SStefano Zampini } 1415674ae819SStefano Zampini } else { 1416674ae819SStefano Zampini computetopography = PETSC_TRUE; 1417674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1418674ae819SStefano Zampini } 1419fb180af4SStefano Zampini if (pcbddc->recompute_topography) { 1420fb180af4SStefano Zampini computetopography = PETSC_TRUE; 1421fb180af4SStefano Zampini } 142256282151SStefano Zampini pcbddc->recompute_topography = computetopography; 14238de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_FALSE; 1424b087196eSStefano Zampini 1425b087196eSStefano Zampini /* check parameters' compatibility */ 1426b7ab4a40SStefano Zampini if (!pcbddc->use_deluxe_scaling) pcbddc->deluxe_zerorows = PETSC_FALSE; 14279d54b7f4SStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_threshold > 0.0); 1428bf3a8328SStefano Zampini pcbddc->adaptive_userdefined = (PetscBool)(pcbddc->adaptive_selection && pcbddc->adaptive_userdefined); 1429862806e4SStefano Zampini if (pcbddc->adaptive_selection) pcbddc->use_faces = PETSC_TRUE; 1430862806e4SStefano Zampini 14315a95e1ceSStefano Zampini computesubschurs = (PetscBool)(pcbddc->adaptive_selection || pcbddc->use_deluxe_scaling); 143216909a7fSStefano Zampini if (pcbddc->switch_static) { 143316909a7fSStefano Zampini PetscBool ismatis; 143416909a7fSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->mat,MATIS,&ismatis);CHKERRQ(ierr); 143516909a7fSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"When the static switch is one, the iteration matrix should be of type MATIS"); 143616909a7fSStefano Zampini } 143716909a7fSStefano Zampini 1438f4ddd8eeSStefano Zampini /* Get stdout for dbg */ 143970cf5478SStefano Zampini if (pcbddc->dbg_flag) { 144070cf5478SStefano Zampini if (!pcbddc->dbg_viewer) { 144158a03d70SStefano Zampini pcbddc->dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pc)); 14421575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 1443f4ddd8eeSStefano Zampini } 144458a03d70SStefano Zampini ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1445f4ddd8eeSStefano Zampini } 1446f4ddd8eeSStefano Zampini 14475e8657edSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 14485e8657edSStefano Zampini /* use_change_of_basis flag is used to automatically compute a change of basis from constraints */ 14495e8657edSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 14505e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 14515e8657edSStefano Zampini } else { 1452b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 14535e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 14545e8657edSStefano Zampini pcbddc->local_mat = matis->A; 1455d16cbb6bSStefano Zampini } 1456d16cbb6bSStefano Zampini 14574f1b2e48SStefano Zampini /* detect local disconnected subdomains if requested and not done before */ 14584f1b2e48SStefano Zampini if (pcbddc->detect_disconnected && !pcbddc->n_local_subs) { 14594f1b2e48SStefano Zampini ierr = MatDetectDisconnectedComponents(pcbddc->local_mat,PETSC_FALSE,&pcbddc->n_local_subs,&pcbddc->local_subs);CHKERRQ(ierr); 14604f1b2e48SStefano Zampini } 14614f1b2e48SStefano Zampini 14621f4df5f7SStefano Zampini /* compute topology info in local ordering */ 14631f4df5f7SStefano Zampini if (pcbddc->recompute_topography) { 14641f4df5f7SStefano Zampini ierr = PCBDDCComputeLocalTopologyInfo(pc);CHKERRQ(ierr); 14651f4df5f7SStefano Zampini } 14661f4df5f7SStefano Zampini 14674f1b2e48SStefano Zampini /* 14681dd7afcfSStefano Zampini Compute change of basis on local pressures (aka zerodiag dofs) 14694f1b2e48SStefano Zampini This should come earlier then PCISSetUp for extracting the correct subdomain matrices 14704f1b2e48SStefano Zampini */ 14711dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 1472d16cbb6bSStefano Zampini if (pcbddc->benign_saddle_point) { 14739f47a83aSStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 14749f47a83aSStefano Zampini 147505b28244SStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->use_change_of_basis || !computesubschurs) pcbddc->benign_change_explicit = PETSC_TRUE; 1476669cc0f4SStefano Zampini /* detect local saddle point and change the basis in pcbddc->local_mat (TODO: reuse case) */ 1477339f8db1SStefano Zampini ierr = PCBDDCBenignDetectSaddlePoint(pc,&zerodiag);CHKERRQ(ierr); 1478a3df083aSStefano Zampini /* pop B0 mat from local mat */ 1479c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 14801dd7afcfSStefano Zampini /* give pcis a hint to not reuse submatrices during PCISCreate */ 14811dd7afcfSStefano Zampini if (pc->flag == SAME_NONZERO_PATTERN && pcis->reusesubmatrices == PETSC_TRUE) { 14821dd7afcfSStefano Zampini if (pcbddc->benign_n && (pcbddc->benign_change_explicit || pcbddc->dbg_flag)) { 14831dd7afcfSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 14841dd7afcfSStefano Zampini } else { 1485a3df083aSStefano Zampini pcis->reusesubmatrices = PETSC_TRUE; 14861dd7afcfSStefano Zampini } 1487a3df083aSStefano Zampini } else { 14889f47a83aSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 1489674ae819SStefano Zampini } 1490a3df083aSStefano Zampini } 149127b6a85dSStefano Zampini 1492f1a72664SStefano Zampini /* propagate relevant information */ 14934f1b2e48SStefano Zampini #if !defined(PETSC_USE_COMPLEX) /* workaround for reals */ 14943301b35fSStefano Zampini if (matis->A->symmetric_set) { 14953301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 14963301b35fSStefano Zampini } 1497e496cd5dSStefano Zampini #endif 149806a4e24aSStefano Zampini if (matis->A->symmetric_set) { 149906a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 150006a4e24aSStefano Zampini } 150106a4e24aSStefano Zampini if (matis->A->spd_set) { 150206a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SPD,matis->A->spd);CHKERRQ(ierr); 150306a4e24aSStefano Zampini } 1504e496cd5dSStefano Zampini 15055e8657edSStefano Zampini /* Set up all the "iterative substructuring" common block without computing solvers */ 15065e8657edSStefano Zampini { 15075e8657edSStefano Zampini Mat temp_mat; 15085e8657edSStefano Zampini 15095e8657edSStefano Zampini temp_mat = matis->A; 15105e8657edSStefano Zampini matis->A = pcbddc->local_mat; 15115e8657edSStefano Zampini ierr = PCISSetUp(pc,PETSC_FALSE);CHKERRQ(ierr); 15125e8657edSStefano Zampini pcbddc->local_mat = matis->A; 15135e8657edSStefano Zampini matis->A = temp_mat; 15145e8657edSStefano Zampini } 1515684f6988SStefano Zampini 151681d14e9dSStefano Zampini /* Analyze interface */ 1517674ae819SStefano Zampini if (computetopography) { 1518674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 15198de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1520345ecf6cSStefano Zampini if (pcbddc->adaptive_selection && !pcbddc->use_deluxe_scaling && !pcbddc->mat_graph->twodim) { 1521345ecf6cSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute the adaptive primal space for a problem with 3D edges without deluxe scaling"); 1522345ecf6cSStefano Zampini } 15235ca1260dSStefano Zampini if (pcbddc->benign_compute_nonetflux) { 1524669cc0f4SStefano Zampini MatNullSpace nnfnnsp; 1525669cc0f4SStefano Zampini 1526669cc0f4SStefano Zampini ierr = PCBDDCComputeNoNetFlux(pc->pmat,pcbddc->divudotp,pcbddc->mat_graph,&nnfnnsp);CHKERRQ(ierr); 1527669cc0f4SStefano Zampini ierr = MatSetNearNullSpace(pc->pmat,nnfnnsp);CHKERRQ(ierr); 1528669cc0f4SStefano Zampini ierr = MatNullSpaceDestroy(&nnfnnsp);CHKERRQ(ierr); 1529669cc0f4SStefano Zampini } 1530674ae819SStefano Zampini } 1531fb8d54d4SStefano Zampini 15325408967cSStefano Zampini /* check existence of a divergence free extension, i.e. 15335408967cSStefano Zampini b(v_I,p_0) = 0 for all v_I (raise error if not). 15345408967cSStefano Zampini Also, check that PCBDDCBenignGetOrSetP0 works */ 15355408967cSStefano Zampini #if defined(PETSC_USE_DEBUG) 153609f581a4SStefano Zampini if (pcbddc->benign_saddle_point) { 15375408967cSStefano Zampini ierr = PCBDDCBenignCheck(pc,zerodiag);CHKERRQ(ierr); 153809f581a4SStefano Zampini } 15395408967cSStefano Zampini #endif 15404f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 154106f24817SStefano Zampini 1542b96c3477SStefano Zampini /* Setup local dirichlet solver ksp_D and sub_schurs solvers */ 1543684f6988SStefano Zampini if (computesolvers) { 1544b334f244SStefano Zampini PCBDDCSubSchurs sub_schurs; 1545d5574798SStefano Zampini 1546d5574798SStefano Zampini if (computesubschurs && computetopography) { 154708122e43SStefano Zampini ierr = PCBDDCInitSubSchurs(pc);CHKERRQ(ierr); 1548b1b3d7a2SStefano Zampini } 15499d54b7f4SStefano Zampini /* SetUp Scaling operator (scaling matrices could be needed in SubSchursSetUp)*/ 15509d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) { 15519d54b7f4SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 15529d54b7f4SStefano Zampini } 1553b334f244SStefano Zampini sub_schurs = pcbddc->sub_schurs; 1554b334f244SStefano Zampini if (sub_schurs && sub_schurs->schur_explicit) { 15552070dbb6SStefano Zampini if (computesubschurs) { 155608122e43SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 15572070dbb6SStefano Zampini } 1558d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 1559d5574798SStefano Zampini } else { 1560d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 15612070dbb6SStefano Zampini if (computesubschurs) { 1562d5574798SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 1563d5574798SStefano Zampini } 15642070dbb6SStefano Zampini } 156508122e43SStefano Zampini if (pcbddc->adaptive_selection) { 156608122e43SStefano Zampini ierr = PCBDDCAdaptiveSelection(pc);CHKERRQ(ierr); 15678de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1568b7eb3628SStefano Zampini } 1569b1b3d7a2SStefano Zampini } 1570684f6988SStefano Zampini 1571f4ddd8eeSStefano Zampini /* infer if NullSpace object attached to Mat via MatSetNearNullSpace has changed */ 1572fb8d54d4SStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1573f4ddd8eeSStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullspace);CHKERRQ(ierr); 1574f4ddd8eeSStefano Zampini if (pcbddc->onearnullspace) { /* already used nearnullspace */ 1575f4ddd8eeSStefano Zampini if (!nearnullspace) { /* near null space attached to mat has been destroyed */ 1576f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1577f4ddd8eeSStefano Zampini } else { 1578f4ddd8eeSStefano Zampini /* determine if the two nullspaces are different (should be lightweight) */ 1579f4ddd8eeSStefano Zampini if (nearnullspace != pcbddc->onearnullspace) { 1580f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1581165b64e2SStefano Zampini } else { /* maybe the user has changed the content of the nearnullspace so check vectors ObjectStateId */ 1582f4ddd8eeSStefano Zampini PetscInt i; 1583165b64e2SStefano Zampini const Vec *nearnullvecs; 1584165b64e2SStefano Zampini PetscObjectState state; 1585165b64e2SStefano Zampini PetscInt nnsp_size; 1586165b64e2SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullspace,NULL,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1587f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1588f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&state);CHKERRQ(ierr); 1589165b64e2SStefano Zampini if (pcbddc->onearnullvecs_state[i] != state) { 1590f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1591f4ddd8eeSStefano Zampini break; 1592f4ddd8eeSStefano Zampini } 1593f4ddd8eeSStefano Zampini } 1594f4ddd8eeSStefano Zampini } 1595f4ddd8eeSStefano Zampini } 1596f4ddd8eeSStefano Zampini } else { 1597f4ddd8eeSStefano Zampini if (!nearnullspace) { /* both nearnullspaces are null */ 1598f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1599f4ddd8eeSStefano Zampini } else { /* nearnullspace attached later */ 1600f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1601f4ddd8eeSStefano Zampini } 1602f4ddd8eeSStefano Zampini } 1603f4ddd8eeSStefano Zampini 1604f4ddd8eeSStefano Zampini /* Setup constraints and related work vectors */ 1605727cdba6SStefano Zampini /* reset primal space flags */ 1606f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 1607727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 16088de1fae6SStefano Zampini if (computeconstraintsmatrix || new_nearnullspace_provided) { 1609727cdba6SStefano Zampini /* It also sets the primal space flags */ 1610674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 1611e7b262bdSStefano Zampini /* Allocate needed local vectors (which depends on quantities defined during ConstraintsSetUp) */ 1612f4ddd8eeSStefano Zampini ierr = PCBDDCSetUpLocalWorkVectors(pc);CHKERRQ(ierr); 16133975b054SStefano Zampini } 16145e8657edSStefano Zampini 16153975b054SStefano Zampini if (computesolvers || pcbddc->new_primal_space) { 16165e8657edSStefano Zampini if (pcbddc->use_change_of_basis) { 16175e8657edSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 16185e8657edSStefano Zampini 16195e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 16204f1b2e48SStefano Zampini if (pcbddc->benign_change) { 16211dd7afcfSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 1622c263805aSStefano Zampini /* pop B0 from pcbddc->local_mat */ 1623c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 1624c263805aSStefano Zampini } 16255e8657edSStefano Zampini /* get submatrices */ 16265e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 16275e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 16285e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 16295e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 16305e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 16315e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 16323975b054SStefano Zampini /* set flag in pcis to not reuse submatrices during PCISCreate */ 16333975b054SStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 16349c6a02ceSStefano Zampini } else if (!pcbddc->user_ChangeOfBasisMatrix && !pcbddc->benign_change) { 1635b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 16365e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 16375e8657edSStefano Zampini pcbddc->local_mat = matis->A; 16385e8657edSStefano Zampini } 1639b96c3477SStefano Zampini /* SetUp coarse and local Neumann solvers */ 164099cc7994SStefano Zampini ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr); 1641b96c3477SStefano Zampini /* SetUp Scaling operator */ 16429d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1643674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 16440c7d97c5SJed Brown } 16459d54b7f4SStefano Zampini } 16461dd7afcfSStefano Zampini /* mark topography as done */ 164756282151SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 16480369aaf7SStefano Zampini 16491dd7afcfSStefano Zampini /* wrap pcis->A_IB and pcis->A_BI if we did not change explicitly the variables on the pressures */ 16501dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_FALSE);CHKERRQ(ierr); 16511dd7afcfSStefano Zampini 165258a03d70SStefano Zampini if (pcbddc->dbg_flag) { 165358a03d70SStefano Zampini ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 16542b510759SStefano Zampini } 16550c7d97c5SJed Brown PetscFunctionReturn(0); 16560c7d97c5SJed Brown } 16570c7d97c5SJed Brown 16580c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 16590c7d97c5SJed Brown /* 166050efa1b5SStefano Zampini PCApply_BDDC - Applies the BDDC operator to a vector. 16610c7d97c5SJed Brown 16620c7d97c5SJed Brown Input Parameters: 16630f202f7eSStefano Zampini + pc - the preconditioner context 16640f202f7eSStefano Zampini - r - input vector (global) 16650c7d97c5SJed Brown 16660c7d97c5SJed Brown Output Parameter: 16670c7d97c5SJed Brown . z - output vector (global) 16680c7d97c5SJed Brown 16690c7d97c5SJed Brown Application Interface Routine: PCApply() 16700c7d97c5SJed Brown */ 16710c7d97c5SJed Brown #undef __FUNCT__ 16720c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 167353cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 16740c7d97c5SJed Brown { 16750c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 16760c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1677b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 16780c7d97c5SJed Brown PetscErrorCode ierr; 16793b03a366Sstefano_zampini const PetscScalar one = 1.0; 16803b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 16812617d88aSStefano Zampini const PetscScalar zero = 0.0; 16820c7d97c5SJed Brown 16830c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 16840c7d97c5SJed Brown NN interface preconditioner changed to BDDC 1685b097fa66SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static == PETSC_TRUE) */ 16860c7d97c5SJed Brown 16870c7d97c5SJed Brown PetscFunctionBegin; 16881dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 16891dd7afcfSStefano Zampini Vec swap; 169027b6a85dSStefano Zampini 169127b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 16921dd7afcfSStefano Zampini swap = pcbddc->work_change; 16931dd7afcfSStefano Zampini pcbddc->work_change = r; 16941dd7afcfSStefano Zampini r = swap; 16951dd7afcfSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 16961dd7afcfSStefano Zampini if (pcbddc->benign_apply_coarse_only && pcbddc->use_exact_dirichlet_trick && pcbddc->change_interior) { 16971dd7afcfSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 16981dd7afcfSStefano Zampini ierr = VecLockPush(pcis->vec1_global);CHKERRQ(ierr); 16991dd7afcfSStefano Zampini } 17001dd7afcfSStefano Zampini } 170127b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 1702015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1703efc2fbd9SStefano Zampini } 170427b6a85dSStefano Zampini if (!pcbddc->use_exact_dirichlet_trick && !pcbddc->benign_apply_coarse_only) { 1705b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 17060c7d97c5SJed Brown /* First Dirichlet solve */ 17070c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17080c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17090c7d97c5SJed Brown /* 17100c7d97c5SJed Brown Assembling right hand side for BDDC operator 1711b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 1712674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 17130c7d97c5SJed Brown */ 1714b097fa66SStefano Zampini if (n_D) { 1715b097fa66SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 17160c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 171716909a7fSStefano Zampini if (pcbddc->switch_static) { 171816909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 171916909a7fSStefano Zampini 172016909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 172116909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 172216909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 172316909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 172416909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 172516909a7fSStefano Zampini } else { 172616909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 172716909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 172816909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 172916909a7fSStefano Zampini } 173016909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 173116909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 173216909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 173316909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 173416909a7fSStefano Zampini } else { 1735b097fa66SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 173616909a7fSStefano Zampini } 1737b097fa66SStefano Zampini } else { 1738b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1739b097fa66SStefano Zampini } 17400c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 17410c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1742674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 1743b76ba322SStefano Zampini } else { 17444fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 1745674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 1746b76ba322SStefano Zampini } 17474fee134fSStefano Zampini } 1748b76ba322SStefano Zampini 17492617d88aSStefano Zampini /* Apply interface preconditioner 17502617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1751dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 17522617d88aSStefano Zampini 1753674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 1754674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 17550c7d97c5SJed Brown 17563b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 17570c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17580c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1759b097fa66SStefano Zampini if (n_B) { 176016909a7fSStefano Zampini if (pcbddc->switch_static) { 176116909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 176216909a7fSStefano Zampini 176316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 176416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 176516909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 176616909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 176716909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 176816909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 176916909a7fSStefano Zampini } else { 177016909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 177116909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 177216909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 177316909a7fSStefano Zampini } 177416909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 177516909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 177616909a7fSStefano Zampini } else { 17770c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 177816909a7fSStefano Zampini } 177916909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 178016909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 178116909a7fSStefano Zampini 178216909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 178316909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 178416909a7fSStefano Zampini } else { 178516909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 178616909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 178716909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 178816909a7fSStefano Zampini } 1789b097fa66SStefano Zampini } 1790df187020SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 1791efc2fbd9SStefano Zampini 179227b6a85dSStefano Zampini if (!pcbddc->use_exact_dirichlet_trick && !pcbddc->benign_apply_coarse_only) { 1793b097fa66SStefano Zampini if (pcbddc->switch_static) { 1794b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 1795b097fa66SStefano Zampini } else { 1796b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 1797b097fa66SStefano Zampini } 17980c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 17990c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1800b097fa66SStefano Zampini } else { 1801b097fa66SStefano Zampini if (pcbddc->switch_static) { 1802b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 1803b097fa66SStefano Zampini } else { 1804b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 1805b097fa66SStefano Zampini } 1806b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1807b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1808b097fa66SStefano Zampini } 180927b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 18101dd7afcfSStefano Zampini if (pcbddc->benign_apply_coarse_only) { 18111dd7afcfSStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 18121dd7afcfSStefano Zampini } 1813015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 1814efc2fbd9SStefano Zampini } 18151f4df5f7SStefano Zampini 18161dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 18171dd7afcfSStefano Zampini Vec swap; 18181dd7afcfSStefano Zampini 18191dd7afcfSStefano Zampini swap = r; 18201dd7afcfSStefano Zampini r = pcbddc->work_change; 18211dd7afcfSStefano Zampini pcbddc->work_change = swap; 18221dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 18231dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 18241dd7afcfSStefano Zampini } 18250c7d97c5SJed Brown PetscFunctionReturn(0); 18260c7d97c5SJed Brown } 182750efa1b5SStefano Zampini 182850efa1b5SStefano Zampini /* -------------------------------------------------------------------------- */ 182950efa1b5SStefano Zampini /* 183050efa1b5SStefano Zampini PCApplyTranspose_BDDC - Applies the transpose of the BDDC operator to a vector. 183150efa1b5SStefano Zampini 183250efa1b5SStefano Zampini Input Parameters: 18330f202f7eSStefano Zampini + pc - the preconditioner context 18340f202f7eSStefano Zampini - r - input vector (global) 183550efa1b5SStefano Zampini 183650efa1b5SStefano Zampini Output Parameter: 183750efa1b5SStefano Zampini . z - output vector (global) 183850efa1b5SStefano Zampini 183950efa1b5SStefano Zampini Application Interface Routine: PCApplyTranspose() 184050efa1b5SStefano Zampini */ 184150efa1b5SStefano Zampini #undef __FUNCT__ 184250efa1b5SStefano Zampini #define __FUNCT__ "PCApplyTranspose_BDDC" 184350efa1b5SStefano Zampini PetscErrorCode PCApplyTranspose_BDDC(PC pc,Vec r,Vec z) 184450efa1b5SStefano Zampini { 184550efa1b5SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 184650efa1b5SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1847b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 184850efa1b5SStefano Zampini PetscErrorCode ierr; 184950efa1b5SStefano Zampini const PetscScalar one = 1.0; 185050efa1b5SStefano Zampini const PetscScalar m_one = -1.0; 185150efa1b5SStefano Zampini const PetscScalar zero = 0.0; 185250efa1b5SStefano Zampini 185350efa1b5SStefano Zampini PetscFunctionBegin; 18541dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 18551dd7afcfSStefano Zampini Vec swap; 185627b6a85dSStefano Zampini 185727b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 18581dd7afcfSStefano Zampini swap = pcbddc->work_change; 18591dd7afcfSStefano Zampini pcbddc->work_change = r; 18601dd7afcfSStefano Zampini r = swap; 186127b6a85dSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 186227b6a85dSStefano Zampini if (pcbddc->benign_apply_coarse_only && pcbddc->use_exact_dirichlet_trick && pcbddc->change_interior) { 186327b6a85dSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 186427b6a85dSStefano Zampini ierr = VecLockPush(pcis->vec1_global);CHKERRQ(ierr); 18651dd7afcfSStefano Zampini } 186627b6a85dSStefano Zampini } 186727b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 1868537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1869537c1cdfSStefano Zampini } 187027b6a85dSStefano Zampini if (!pcbddc->use_exact_dirichlet_trick && !pcbddc->benign_apply_coarse_only) { 1871b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 187250efa1b5SStefano Zampini /* First Dirichlet solve */ 187350efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 187450efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 187550efa1b5SStefano Zampini /* 187650efa1b5SStefano Zampini Assembling right hand side for BDDC operator 1877b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 187850efa1b5SStefano Zampini - pcis->vec1_B the interface part of the global vector z 187950efa1b5SStefano Zampini */ 1880b097fa66SStefano Zampini if (n_D) { 1881b097fa66SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 188250efa1b5SStefano Zampini ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 188316909a7fSStefano Zampini if (pcbddc->switch_static) { 188416909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 188516909a7fSStefano Zampini 188616909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 188716909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 188816909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 188916909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 189016909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 189116909a7fSStefano Zampini } else { 189216909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 189316909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 189416909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 189516909a7fSStefano Zampini } 189616909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 189716909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 189816909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 189916909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 190016909a7fSStefano Zampini } else { 1901b097fa66SStefano Zampini ierr = MatMultTranspose(pcis->A_IB,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 190216909a7fSStefano Zampini } 1903b097fa66SStefano Zampini } else { 1904b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1905b097fa66SStefano Zampini } 190650efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 190750efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 190850efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 190950efa1b5SStefano Zampini } else { 191050efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 191150efa1b5SStefano Zampini } 191250efa1b5SStefano Zampini 191350efa1b5SStefano Zampini /* Apply interface preconditioner 191450efa1b5SStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1915dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_TRUE);CHKERRQ(ierr); 191650efa1b5SStefano Zampini 191750efa1b5SStefano Zampini /* Apply transpose of partition of unity operator */ 191850efa1b5SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 191950efa1b5SStefano Zampini 192050efa1b5SStefano Zampini /* Second Dirichlet solve and assembling of output */ 192150efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 192250efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1923b097fa66SStefano Zampini if (n_B) { 192416909a7fSStefano Zampini if (pcbddc->switch_static) { 192516909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 192616909a7fSStefano Zampini 192716909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 192816909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 192916909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 193016909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 193116909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 193216909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 193316909a7fSStefano Zampini } else { 193416909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 193516909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 193616909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 193716909a7fSStefano Zampini } 193816909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 193916909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 194016909a7fSStefano Zampini } else { 194150efa1b5SStefano Zampini ierr = MatMultTranspose(pcis->A_BI,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 194216909a7fSStefano Zampini } 194316909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 194416909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 194516909a7fSStefano Zampini 194616909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 194716909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 194816909a7fSStefano Zampini } else { 194916909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 195016909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 195116909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 195216909a7fSStefano Zampini } 1953b097fa66SStefano Zampini } 1954b0147a47SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 195527b6a85dSStefano Zampini if (!pcbddc->use_exact_dirichlet_trick && !pcbddc->benign_apply_coarse_only) { 1956b097fa66SStefano Zampini if (pcbddc->switch_static) { 1957b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 1958b097fa66SStefano Zampini } else { 1959b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 1960b097fa66SStefano Zampini } 196150efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 196250efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1963b097fa66SStefano Zampini } else { 1964b097fa66SStefano Zampini if (pcbddc->switch_static) { 1965b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 1966b097fa66SStefano Zampini } else { 1967b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 1968b097fa66SStefano Zampini } 1969b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1970b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1971b097fa66SStefano Zampini } 197227b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 1973537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 1974537c1cdfSStefano Zampini } 19751dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 19761dd7afcfSStefano Zampini Vec swap; 19771dd7afcfSStefano Zampini 19781dd7afcfSStefano Zampini swap = r; 19791dd7afcfSStefano Zampini r = pcbddc->work_change; 19801dd7afcfSStefano Zampini pcbddc->work_change = swap; 19811dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 19821dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 19831dd7afcfSStefano Zampini } 198450efa1b5SStefano Zampini PetscFunctionReturn(0); 198550efa1b5SStefano Zampini } 1986da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 1987674ae819SStefano Zampini 1988da1bb401SStefano Zampini #undef __FUNCT__ 1989da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC" 1990da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 1991da1bb401SStefano Zampini { 1992da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1993da1bb401SStefano Zampini PetscErrorCode ierr; 1994da1bb401SStefano Zampini 1995da1bb401SStefano Zampini PetscFunctionBegin; 1996674ae819SStefano Zampini /* free BDDC custom data */ 1997674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 1998674ae819SStefano Zampini /* destroy objects related to topography */ 1999674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 2000674ae819SStefano Zampini /* free allocated graph structure */ 2001da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr); 2002b96c3477SStefano Zampini /* free allocated sub schurs structure */ 2003b96c3477SStefano Zampini ierr = PetscFree(pcbddc->sub_schurs);CHKERRQ(ierr); 200434a97f8cSStefano Zampini /* destroy objects for scaling operator */ 2005674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 200634a97f8cSStefano Zampini ierr = PetscFree(pcbddc->deluxe_ctx);CHKERRQ(ierr); 2007674ae819SStefano Zampini /* free solvers stuff */ 2008674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 200962a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 201062a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 201162a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 20121dd7afcfSStefano Zampini /* free data created by PCIS */ 20131dd7afcfSStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 20143425bc38SStefano Zampini /* remove functions */ 2015906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",NULL);CHKERRQ(ierr); 2016674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 201730368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",NULL);CHKERRQ(ierr); 2018bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 20192b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr); 2020b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr); 20212b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr); 2022bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 202382ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2024bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 202582ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2026bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 202782ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2028bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 2029785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2030bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 203163602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",NULL);CHKERRQ(ierr); 2032bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 2033bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 2034bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 2035bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 2036a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",NULL);CHKERRQ(ierr); 2037674ae819SStefano Zampini /* Free the private data structure */ 2038674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 2039da1bb401SStefano Zampini PetscFunctionReturn(0); 2040da1bb401SStefano Zampini } 20413425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 20421e6b0712SBarry Smith 20433425bc38SStefano Zampini #undef __FUNCT__ 2044a06fd7f2SStefano Zampini #define __FUNCT__ "PCPreSolveChangeRHS_BDDC" 2045a06fd7f2SStefano Zampini static PetscErrorCode PCPreSolveChangeRHS_BDDC(PC pc, PetscBool* change) 2046a06fd7f2SStefano Zampini { 2047a06fd7f2SStefano Zampini PetscFunctionBegin; 2048a06fd7f2SStefano Zampini *change = PETSC_TRUE; 2049a06fd7f2SStefano Zampini PetscFunctionReturn(0); 2050a06fd7f2SStefano Zampini } 2051a06fd7f2SStefano Zampini 2052a06fd7f2SStefano Zampini #undef __FUNCT__ 20533425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC" 20543425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 20553425bc38SStefano Zampini { 2056674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 2057266e20e9SStefano Zampini Vec work; 20583425bc38SStefano Zampini PC_IS* pcis; 20593425bc38SStefano Zampini PC_BDDC* pcbddc; 20603425bc38SStefano Zampini PetscErrorCode ierr; 20610c7d97c5SJed Brown 20623425bc38SStefano Zampini PetscFunctionBegin; 20633425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 20643425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 20653425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 20663425bc38SStefano Zampini 2067c08af4c6SStefano Zampini /* 2068c08af4c6SStefano Zampini change of basis for physical rhs if needed 2069c08af4c6SStefano Zampini It also changes the rhs in case of dirichlet boundaries 2070c08af4c6SStefano Zampini */ 20713738a8e6SStefano Zampini if (!pcbddc->original_rhs) { 20723738a8e6SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 20733738a8e6SStefano Zampini } 20743738a8e6SStefano Zampini ierr = VecCopy(standard_rhs,pcbddc->original_rhs);CHKERRQ(ierr); 20753738a8e6SStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,pcbddc->original_rhs,NULL);CHKERRQ(ierr); 2076fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 20773738a8e6SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcbddc->original_rhs,pcbddc->work_change);CHKERRQ(ierr); 20783738a8e6SStefano Zampini work = pcbddc->work_change; 2079fc17d649SStefano Zampini } else { 20803738a8e6SStefano Zampini work = pcbddc->original_rhs; 2081fc17d649SStefano Zampini } 20823425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 2083266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2084266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,work,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2085fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 2086fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 2087266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2088266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2089674ae819SStefano Zampini /* Apply partition of unity */ 20903425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 2091266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 20928eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 20933425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 20943425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 20953425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 20963425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 2097266e20e9SStefano Zampini ierr = VecSet(work,0.0);CHKERRQ(ierr); 2098266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2099266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,work,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2100266e20e9SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,work,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 2101266e20e9SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2102266e20e9SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,work,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 21033425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 21043425bc38SStefano Zampini } 21053425bc38SStefano Zampini /* BDDC rhs */ 21063425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 21078eeda7d8SStefano Zampini if (pcbddc->switch_static) { 21083425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 21093425bc38SStefano Zampini } 2110fc17d649SStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 21113425bc38SStefano Zampini /* apply BDDC */ 2112dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 2113266e20e9SStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 21143425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 21153425bc38SStefano Zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 21163425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 21173425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 21183425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 21193425bc38SStefano Zampini PetscFunctionReturn(0); 21203425bc38SStefano Zampini } 21211e6b0712SBarry Smith 21223425bc38SStefano Zampini #undef __FUNCT__ 21233425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS" 21243425bc38SStefano Zampini /*@ 21250f202f7eSStefano Zampini PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETI-DP linear system using the physical right-hand side 21263425bc38SStefano Zampini 21273425bc38SStefano Zampini Collective 21283425bc38SStefano Zampini 21293425bc38SStefano Zampini Input Parameters: 21300f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix object obtained by a call to PCBDDCCreateFETIDPOperators 21310f202f7eSStefano Zampini - standard_rhs - the right-hand side of the original linear system 21323425bc38SStefano Zampini 21333425bc38SStefano Zampini Output Parameters: 21340f202f7eSStefano Zampini . fetidp_flux_rhs - the right-hand side for the FETI-DP linear system 21353425bc38SStefano Zampini 21363425bc38SStefano Zampini Level: developer 21373425bc38SStefano Zampini 21383425bc38SStefano Zampini Notes: 21393425bc38SStefano Zampini 21400f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetSolution 21413425bc38SStefano Zampini @*/ 21423425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 21433425bc38SStefano Zampini { 2144674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 21453425bc38SStefano Zampini PetscErrorCode ierr; 21463425bc38SStefano Zampini 21473425bc38SStefano Zampini PetscFunctionBegin; 2148266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2149266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_rhs,VEC_CLASSID,2); 2150266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_rhs,VEC_CLASSID,3); 21513425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2152163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 21533425bc38SStefano Zampini PetscFunctionReturn(0); 21543425bc38SStefano Zampini } 21553425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 21561e6b0712SBarry Smith 21573425bc38SStefano Zampini #undef __FUNCT__ 21583425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC" 21593425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 21603425bc38SStefano Zampini { 2161674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 21623425bc38SStefano Zampini PC_IS* pcis; 21633425bc38SStefano Zampini PC_BDDC* pcbddc; 21643425bc38SStefano Zampini PetscErrorCode ierr; 21653425bc38SStefano Zampini 21663425bc38SStefano Zampini PetscFunctionBegin; 21673425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 21683425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 21693425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 21703425bc38SStefano Zampini 21713425bc38SStefano Zampini /* apply B_delta^T */ 21723425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21733425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21743425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 21753425bc38SStefano Zampini /* compute rhs for BDDC application */ 21763425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 21778eeda7d8SStefano Zampini if (pcbddc->switch_static) { 21783425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 21793425bc38SStefano Zampini } 2180fc17d649SStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 21813425bc38SStefano Zampini /* apply BDDC */ 2182dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 21833425bc38SStefano Zampini /* put values into standard global vector */ 21843425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21853425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21868eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 21873425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 21883425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 21893425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_D,-1.0,pcis->vec1_D);CHKERRQ(ierr); 21903425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 21913425bc38SStefano Zampini } 21923425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21933425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2194266e20e9SStefano Zampini /* add p0 solution to final solution */ 2195266e20e9SStefano Zampini ierr = PCBDDCBenignGetOrSetP0(mat_ctx->pc,standard_sol,PETSC_FALSE);CHKERRQ(ierr); 2196fc17d649SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2197fc17d649SStefano Zampini Vec v2; 2198fc17d649SStefano Zampini ierr = VecDuplicate(standard_sol,&v2);CHKERRQ(ierr); 2199fc17d649SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,standard_sol,v2);CHKERRQ(ierr); 2200fc17d649SStefano Zampini ierr = VecCopy(v2,standard_sol);CHKERRQ(ierr); 2201fc17d649SStefano Zampini ierr = VecDestroy(&v2);CHKERRQ(ierr); 2202fc17d649SStefano Zampini } 22033308cffdSStefano Zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 22043425bc38SStefano Zampini PetscFunctionReturn(0); 22053425bc38SStefano Zampini } 22061e6b0712SBarry Smith 22073425bc38SStefano Zampini #undef __FUNCT__ 22083425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution" 22093425bc38SStefano Zampini /*@ 22100f202f7eSStefano Zampini PCBDDCMatFETIDPGetSolution - Compute the physical solution using the solution of the FETI-DP linear system 22113425bc38SStefano Zampini 22123425bc38SStefano Zampini Collective 22133425bc38SStefano Zampini 22143425bc38SStefano Zampini Input Parameters: 22150f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix obtained by a call to PCBDDCCreateFETIDPOperators 22160f202f7eSStefano Zampini - fetidp_flux_sol - the solution of the FETI-DP linear system 22173425bc38SStefano Zampini 22183425bc38SStefano Zampini Output Parameters: 22190f202f7eSStefano Zampini . standard_sol - the solution defined on the physical domain 22203425bc38SStefano Zampini 22213425bc38SStefano Zampini Level: developer 22223425bc38SStefano Zampini 22233425bc38SStefano Zampini Notes: 22243425bc38SStefano Zampini 22250f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetRHS 22263425bc38SStefano Zampini @*/ 22273425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 22283425bc38SStefano Zampini { 2229674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 22303425bc38SStefano Zampini PetscErrorCode ierr; 22313425bc38SStefano Zampini 22323425bc38SStefano Zampini PetscFunctionBegin; 2233266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_mat,MAT_CLASSID,1); 2234266e20e9SStefano Zampini PetscValidHeaderSpecific(fetidp_flux_sol,VEC_CLASSID,2); 2235266e20e9SStefano Zampini PetscValidHeaderSpecific(standard_sol,VEC_CLASSID,3); 22363425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 2237163d334eSBarry Smith ierr = PetscUseMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 22383425bc38SStefano Zampini PetscFunctionReturn(0); 22393425bc38SStefano Zampini } 22403425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 22411e6b0712SBarry Smith 2242f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec); 2243edf7251bSStefano Zampini extern PetscErrorCode FETIDPMatMultTranspose(Mat,Vec,Vec); 2244f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat); 2245f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec); 2246edf7251bSStefano Zampini extern PetscErrorCode FETIDPPCApplyTranspose(PC,Vec,Vec); 2247f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC); 2248674ae819SStefano Zampini 22493425bc38SStefano Zampini #undef __FUNCT__ 22503425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC" 22513425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 22523425bc38SStefano Zampini { 2253674ae819SStefano Zampini 2254674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 22553425bc38SStefano Zampini Mat newmat; 2256674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 22573425bc38SStefano Zampini PC newpc; 2258ce94432eSBarry Smith MPI_Comm comm; 22593425bc38SStefano Zampini PetscErrorCode ierr; 22603425bc38SStefano Zampini 22613425bc38SStefano Zampini PetscFunctionBegin; 2262ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 22633425bc38SStefano Zampini /* FETIDP linear matrix */ 22643425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 22653425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 22663425bc38SStefano Zampini ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 22673425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 2268edf7251bSStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT_TRANSPOSE,(void (*)(void))FETIDPMatMultTranspose);CHKERRQ(ierr); 22693425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 22703425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 22713425bc38SStefano Zampini /* FETIDP preconditioner */ 22723425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 22733425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 22743425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 22753425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 22763425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 22773425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 2278edf7251bSStefano Zampini ierr = PCShellSetApplyTranspose(newpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 22793425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 228023ee1639SBarry Smith ierr = PCSetOperators(newpc,newmat,newmat);CHKERRQ(ierr); 22813425bc38SStefano Zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 22823425bc38SStefano Zampini /* return pointers for objects created */ 22833425bc38SStefano Zampini *fetidp_mat=newmat; 22843425bc38SStefano Zampini *fetidp_pc=newpc; 22853425bc38SStefano Zampini PetscFunctionReturn(0); 22863425bc38SStefano Zampini } 22871e6b0712SBarry Smith 22883425bc38SStefano Zampini #undef __FUNCT__ 22893425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators" 22903425bc38SStefano Zampini /*@ 22910f202f7eSStefano Zampini PCBDDCCreateFETIDPOperators - Create FETI-DP operators 22923425bc38SStefano Zampini 22933425bc38SStefano Zampini Collective 22943425bc38SStefano Zampini 22953425bc38SStefano Zampini Input Parameters: 22960f202f7eSStefano Zampini . pc - the BDDC preconditioning context (setup should have been called before) 229728509bceSStefano Zampini 229828509bceSStefano Zampini Output Parameters: 22990f202f7eSStefano Zampini + fetidp_mat - shell FETI-DP matrix object 23000f202f7eSStefano Zampini - fetidp_pc - shell Dirichlet preconditioner for FETI-DP matrix 230128509bceSStefano Zampini 230228509bceSStefano Zampini Options Database Keys: 23030f202f7eSStefano Zampini . -fetidp_fullyredundant <false> - use or not a fully redundant set of Lagrange multipliers 23043425bc38SStefano Zampini 23053425bc38SStefano Zampini Level: developer 23063425bc38SStefano Zampini 23073425bc38SStefano Zampini Notes: 23080f202f7eSStefano Zampini Currently the only operations provided for FETI-DP matrix are MatMult and MatMultTranspose 23093425bc38SStefano Zampini 23100f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCMatFETIDPGetRHS, PCBDDCMatFETIDPGetSolution 23113425bc38SStefano Zampini @*/ 23123425bc38SStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 23133425bc38SStefano Zampini { 23143425bc38SStefano Zampini PetscErrorCode ierr; 23153425bc38SStefano Zampini 23163425bc38SStefano Zampini PetscFunctionBegin; 23173425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 23183425bc38SStefano Zampini if (pc->setupcalled) { 2319516d51a7SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,Mat*,PC*),(pc,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 2320f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n"); 23213425bc38SStefano Zampini PetscFunctionReturn(0); 23223425bc38SStefano Zampini } 23230c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2324da1bb401SStefano Zampini /*MC 2325da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 23260c7d97c5SJed Brown 232728509bceSStefano Zampini An implementation of the BDDC preconditioner based on 232828509bceSStefano Zampini 232928509bceSStefano Zampini .vb 233028509bceSStefano Zampini [1] C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 233128509bceSStefano 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 233228509bceSStefano Zampini [3] J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", http://arxiv.org/abs/0712.3977 23330f202f7eSStefano 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 233428509bceSStefano Zampini .ve 233528509bceSStefano Zampini 233628509bceSStefano Zampini The matrix to be preconditioned (Pmat) must be of type MATIS. 233728509bceSStefano Zampini 23380f202f7eSStefano Zampini Currently works with MATIS matrices with local matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers. 233928509bceSStefano Zampini 234028509bceSStefano Zampini It also works with unsymmetric and indefinite problems. 234128509bceSStefano Zampini 2342b6fdb6dfSStefano 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. 2343b6fdb6dfSStefano Zampini 2344c7017625SStefano 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). 234528509bceSStefano Zampini 23460f202f7eSStefano 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() 234730368db7SStefano Zampini Additional information on dofs can be provided by using PCBDDCSetDofsSplitting(), PCBDDCSetDirichletBoundaries(), PCBDDCSetNeumannBoundaries(), and PCBDDCSetPrimalVerticesIS() and their local counterparts. 234828509bceSStefano Zampini 23490f202f7eSStefano Zampini Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace(). Non-singular modes are retained via SVD. 235028509bceSStefano Zampini 23510f202f7eSStefano 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. 23520f202f7eSStefano Zampini User defined change of basis can be passed to PCBDDC by using PCBDDCSetChangeOfBasisMat() 235328509bceSStefano Zampini 23540f202f7eSStefano Zampini The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using a MatPartitioning object. 235528509bceSStefano Zampini 2356df4d28bfSStefano 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. 235728509bceSStefano Zampini 23580f202f7eSStefano 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. 23590f202f7eSStefano Zampini Deluxe scaling is not supported yet for FETI-DP. 23600f202f7eSStefano Zampini 23610f202f7eSStefano Zampini Options Database Keys (some of them, run with -h for a complete list): 23620f202f7eSStefano Zampini 23630f202f7eSStefano Zampini . -pc_bddc_use_vertices <true> - use or not vertices in primal space 23640f202f7eSStefano Zampini . -pc_bddc_use_edges <true> - use or not edges in primal space 23650f202f7eSStefano Zampini . -pc_bddc_use_faces <false> - use or not faces in primal space 23660f202f7eSStefano Zampini . -pc_bddc_symmetric <true> - symmetric computation of primal basis functions. Specify false for unsymmetric problems 23670f202f7eSStefano Zampini . -pc_bddc_use_change_of_basis <false> - use change of basis approach (on edges only) 23680f202f7eSStefano Zampini . -pc_bddc_use_change_on_faces <false> - use change of basis approach on faces if change of basis has been requested 23690f202f7eSStefano Zampini . -pc_bddc_switch_static <false> - switches from M_2 (default) to M_3 operator (see reference article [1]) 237028509bceSStefano Zampini . -pc_bddc_levels <0> - maximum number of levels for multilevel 23710f202f7eSStefano 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) 23720f202f7eSStefano 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) 23730f202f7eSStefano Zampini . -pc_bddc_use_deluxe_scaling <false> - use deluxe scaling 23740f202f7eSStefano 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) 2375df4d28bfSStefano 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) 237628509bceSStefano Zampini - -pc_bddc_check_level <0> - set verbosity level of debugging output 237728509bceSStefano Zampini 237828509bceSStefano Zampini Options for Dirichlet, Neumann or coarse solver can be set with 237928509bceSStefano Zampini .vb 238028509bceSStefano Zampini -pc_bddc_dirichlet_ 238128509bceSStefano Zampini -pc_bddc_neumann_ 238228509bceSStefano Zampini -pc_bddc_coarse_ 238328509bceSStefano Zampini .ve 23840f202f7eSStefano Zampini e.g -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg. PCBDDC uses by default KPSPREONLY and PCLU. 238528509bceSStefano Zampini 23860f202f7eSStefano Zampini When using a multilevel approach, solvers' options at the N-th level (N > 1) can be specified as 238728509bceSStefano Zampini .vb 2388312be037SStefano Zampini -pc_bddc_dirichlet_lN_ 2389312be037SStefano Zampini -pc_bddc_neumann_lN_ 2390312be037SStefano Zampini -pc_bddc_coarse_lN_ 239128509bceSStefano Zampini .ve 23920f202f7eSStefano Zampini Note that level number ranges from the finest (0) to the coarsest (N). 23930f202f7eSStefano 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. 23940f202f7eSStefano Zampini .vb 23950f202f7eSStefano Zampini -pc_bddc_coarse_pc_bddc_adaptive_threshold 5 -pc_bddc_coarse_l1_pc_bddc_redistribute 3 23960f202f7eSStefano Zampini .ve 23970f202f7eSStefano 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 2398da1bb401SStefano Zampini 2399da1bb401SStefano Zampini Level: intermediate 2400da1bb401SStefano Zampini 2401b6fdb6dfSStefano Zampini Developer notes: 2402da1bb401SStefano Zampini 2403da1bb401SStefano Zampini Contributed by Stefano Zampini 2404da1bb401SStefano Zampini 2405da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 2406da1bb401SStefano Zampini M*/ 2407b2573a8aSBarry Smith 2408da1bb401SStefano Zampini #undef __FUNCT__ 2409da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC" 24108cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 2411da1bb401SStefano Zampini { 2412da1bb401SStefano Zampini PetscErrorCode ierr; 2413da1bb401SStefano Zampini PC_BDDC *pcbddc; 2414da1bb401SStefano Zampini 2415da1bb401SStefano Zampini PetscFunctionBegin; 2416da1bb401SStefano Zampini /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 2417b00a9115SJed Brown ierr = PetscNewLog(pc,&pcbddc);CHKERRQ(ierr); 2418da1bb401SStefano Zampini pc->data = (void*)pcbddc; 2419da1bb401SStefano Zampini 2420da1bb401SStefano Zampini /* create PCIS data structure */ 2421da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 2422da1bb401SStefano Zampini 242347d04d0dSStefano Zampini /* BDDC customization */ 242408a5cf49SStefano Zampini pcbddc->use_local_adj = PETSC_TRUE; 242547d04d0dSStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 242647d04d0dSStefano Zampini pcbddc->use_edges = PETSC_TRUE; 242747d04d0dSStefano Zampini pcbddc->use_faces = PETSC_FALSE; 242847d04d0dSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 242947d04d0dSStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 243047d04d0dSStefano Zampini pcbddc->switch_static = PETSC_FALSE; 2431fa434743SStefano Zampini pcbddc->use_nnsp_true = PETSC_FALSE; 2432fa434743SStefano Zampini pcbddc->use_qr_single = PETSC_FALSE; 24333301b35fSStefano Zampini pcbddc->symmetric_primal = PETSC_TRUE; 243406a4e24aSStefano Zampini pcbddc->benign_saddle_point = PETSC_FALSE; 243527b6a85dSStefano Zampini pcbddc->benign_have_null = PETSC_FALSE; 243614f95afaSStefano Zampini pcbddc->vertex_size = 1; 243747d04d0dSStefano Zampini pcbddc->dbg_flag = 0; 2438b9d89cd5SStefano Zampini /* private */ 2439727cdba6SStefano Zampini pcbddc->local_primal_size = 0; 24400e6343abSStefano Zampini pcbddc->local_primal_size_cc = 0; 24410e6343abSStefano Zampini pcbddc->local_primal_ref_node = 0; 24420e6343abSStefano Zampini pcbddc->local_primal_ref_mult = 0; 2443e9189074SStefano Zampini pcbddc->n_vertices = 0; 2444727cdba6SStefano Zampini pcbddc->primal_indices_local_idxs = 0; 2445fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 244668457ee5SStefano Zampini pcbddc->coarse_size = -1; 2447f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 2448727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 2449f4ddd8eeSStefano Zampini pcbddc->global_primal_indices = 0; 2450f4ddd8eeSStefano Zampini pcbddc->onearnullspace = 0; 2451f4ddd8eeSStefano Zampini pcbddc->onearnullvecs_state = 0; 2452674ae819SStefano Zampini pcbddc->user_primal_vertices = 0; 245330368db7SStefano Zampini pcbddc->user_primal_vertices_local = 0; 24543972b0daSStefano Zampini pcbddc->temp_solution = 0; 2455534831adSStefano Zampini pcbddc->original_rhs = 0; 2456534831adSStefano Zampini pcbddc->local_mat = 0; 2457534831adSStefano Zampini pcbddc->ChangeOfBasisMatrix = 0; 2458b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = 0; 2459da1bb401SStefano Zampini pcbddc->coarse_vec = 0; 2460da1bb401SStefano Zampini pcbddc->coarse_ksp = 0; 2461da1bb401SStefano Zampini pcbddc->coarse_phi_B = 0; 2462da1bb401SStefano Zampini pcbddc->coarse_phi_D = 0; 246315aaf578SStefano Zampini pcbddc->coarse_psi_B = 0; 246415aaf578SStefano Zampini pcbddc->coarse_psi_D = 0; 2465da1bb401SStefano Zampini pcbddc->vec1_P = 0; 2466da1bb401SStefano Zampini pcbddc->vec1_R = 0; 2467da1bb401SStefano Zampini pcbddc->vec2_R = 0; 2468da1bb401SStefano Zampini pcbddc->local_auxmat1 = 0; 2469da1bb401SStefano Zampini pcbddc->local_auxmat2 = 0; 2470da1bb401SStefano Zampini pcbddc->R_to_B = 0; 2471da1bb401SStefano Zampini pcbddc->R_to_D = 0; 2472da1bb401SStefano Zampini pcbddc->ksp_D = 0; 2473da1bb401SStefano Zampini pcbddc->ksp_R = 0; 2474da1bb401SStefano Zampini pcbddc->NeumannBoundaries = 0; 2475785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = 0; 2476785d1243SStefano Zampini pcbddc->DirichletBoundaries = 0; 2477785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = 0; 247860d44989SStefano Zampini pcbddc->user_provided_isfordofs = PETSC_FALSE; 247960d44989SStefano Zampini pcbddc->n_ISForDofs = 0; 248063602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 2481da1bb401SStefano Zampini pcbddc->ISForDofs = 0; 248263602bcaSStefano Zampini pcbddc->ISForDofsLocal = 0; 2483da1bb401SStefano Zampini pcbddc->ConstraintMatrix = 0; 248485c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 248547d04d0dSStefano Zampini pcbddc->coarse_loc_to_glob = 0; 248647d04d0dSStefano Zampini pcbddc->coarsening_ratio = 8; 2487b0c7d250SStefano Zampini pcbddc->coarse_adj_red = 0; 24884fad6a16SStefano Zampini pcbddc->current_level = 0; 24892b510759SStefano Zampini pcbddc->max_levels = 0; 2490323d395dSStefano Zampini pcbddc->use_coarse_estimates = PETSC_FALSE; 249157de7509SStefano Zampini pcbddc->coarse_eqs_per_proc = 1; 2492f3bde8b3SStefano Zampini pcbddc->coarse_subassembling = 0; 24934f1b2e48SStefano Zampini pcbddc->detect_disconnected = PETSC_FALSE; 24944f1b2e48SStefano Zampini pcbddc->n_local_subs = 0; 24954f1b2e48SStefano Zampini pcbddc->local_subs = NULL; 249681d14e9dSStefano Zampini 249781d14e9dSStefano Zampini /* benign subspace trick */ 249881d14e9dSStefano Zampini pcbddc->benign_change = 0; 249927b6a85dSStefano Zampini pcbddc->benign_compute_correction = PETSC_TRUE; 25000369aaf7SStefano Zampini pcbddc->benign_vec = 0; 25010369aaf7SStefano Zampini pcbddc->benign_original_mat = 0; 25020369aaf7SStefano Zampini pcbddc->benign_sf = 0; 25034f1b2e48SStefano Zampini pcbddc->benign_B0 = 0; 25044f1b2e48SStefano Zampini pcbddc->benign_n = 0; 25054f1b2e48SStefano Zampini pcbddc->benign_p0 = NULL; 25064f1b2e48SStefano Zampini pcbddc->benign_p0_lidx = NULL; 25074f1b2e48SStefano Zampini pcbddc->benign_p0_gidx = NULL; 2508b0f5fe93SStefano Zampini pcbddc->benign_null = PETSC_FALSE; 250981d14e9dSStefano Zampini 2510674ae819SStefano Zampini /* create local graph structure */ 2511674ae819SStefano Zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 2512674ae819SStefano Zampini 2513674ae819SStefano Zampini /* scaling */ 2514674ae819SStefano Zampini pcbddc->work_scaling = 0; 251534a97f8cSStefano Zampini pcbddc->use_deluxe_scaling = PETSC_FALSE; 2516b96c3477SStefano Zampini 2517b334f244SStefano Zampini /* sub schurs options */ 2518b96c3477SStefano Zampini pcbddc->sub_schurs_rebuild = PETSC_FALSE; 2519b96c3477SStefano Zampini pcbddc->sub_schurs_layers = -1; 2520b96c3477SStefano Zampini pcbddc->sub_schurs_use_useradj = PETSC_FALSE; 2521b96c3477SStefano Zampini 2522b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_FALSE; 2523da1bb401SStefano Zampini 2524b7eb3628SStefano Zampini /* adaptivity */ 2525f6f667cfSStefano Zampini pcbddc->adaptive_threshold = 0.0; 252608122e43SStefano Zampini pcbddc->adaptive_nmax = 0; 2527f6f667cfSStefano Zampini pcbddc->adaptive_nmin = 0; 2528b7eb3628SStefano Zampini 2529da1bb401SStefano Zampini /* function pointers */ 2530da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 253193bd9ae7SStefano Zampini pc->ops->applytranspose = PCApplyTranspose_BDDC; 2532da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 2533da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 2534da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 25356b78500eSPatrick Sanan pc->ops->view = PCView_BDDC; 2536da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 2537da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 2538da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 2539534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 2540534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 2541da1bb401SStefano Zampini 2542da1bb401SStefano Zampini /* composing function */ 2543906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",PCBDDCSetChangeOfBasisMat_BDDC);CHKERRQ(ierr); 2544674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 254530368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",PCBDDCSetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 2546bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 25472b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr); 2548b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr); 25492b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr); 2550bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 255182ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2552bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 255382ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2554bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 255582ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2556bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 255782ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2558bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 255963602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",PCBDDCSetDofsSplittingLocal_BDDC);CHKERRQ(ierr); 2560bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 2561bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 2562bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 2563bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 2564a06fd7f2SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",PCPreSolveChangeRHS_BDDC);CHKERRQ(ierr); 2565da1bb401SStefano Zampini PetscFunctionReturn(0); 2566da1bb401SStefano Zampini } 25673425bc38SStefano Zampini 2568