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 */ 438eeda7d8SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_check_level","Verbose output for PCBDDC (intended for debug)","none",pcbddc->dbg_flag,&pcbddc->dbg_flag,NULL);CHKERRQ(ierr); 446b78500eSPatrick Sanan /* Primal space customization */ 4508a5cf49SStefano 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); 468eeda7d8SStefano 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); 478eeda7d8SStefano 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); 488eeda7d8SStefano 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); 4914f95afaSStefano 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); 506661aa1dSStefano 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); 5114f95afaSStefano 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); 528eeda7d8SStefano Zampini /* Change of basis */ 53b9b85e73SStefano 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); 54b9b85e73SStefano 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); 55674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 56674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 57674ae819SStefano Zampini } 588eeda7d8SStefano Zampini /* Switch between M_2 (default) and M_3 preconditioners (as defined by C. Dohrmann in the ref. article) */ 598eeda7d8SStefano 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); 6057de7509SStefano 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); 610298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr); 622b510759SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr); 63323d395dSStefano 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); 64674ae819SStefano 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); 65b96c3477SStefano 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); 66b96c3477SStefano 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); 67b96c3477SStefano 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); 68683d3df6SStefano 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); 69bf3a8328SStefano 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); 70bf3a8328SStefano 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); 714c6709b3SStefano 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); 7208122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmin","Minimum number of constraints per connected components","none",pcbddc->adaptive_nmin,&pcbddc->adaptive_nmin,NULL);CHKERRQ(ierr); 7308122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmax","Maximum number of constraints per connected components","none",pcbddc->adaptive_nmax,&pcbddc->adaptive_nmax,NULL);CHKERRQ(ierr); 743301b35fSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_symmetric","Symmetric computation of primal basis functions","none",pcbddc->symmetric_primal,&pcbddc->symmetric_primal,NULL);CHKERRQ(ierr); 75b0c7d250SStefano 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); 76b3afcdbeSStefano 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); 77b3afcdbeSStefano 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); 78e9627c49SStefano 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); 7927b6a85dSStefano 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); 804f1b2e48SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_detect_disconnected","Detects disconnected subdomains","none",pcbddc->detect_disconnected,&pcbddc->detect_disconnected,NULL);CHKERRQ(ierr); 8170c64980SStefano 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); 820c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 830c7d97c5SJed Brown PetscFunctionReturn(0); 840c7d97c5SJed Brown } 856b78500eSPatrick Sanan 866b78500eSPatrick Sanan /* -------------------------------------------------------------------------- */ 876b78500eSPatrick Sanan #undef __FUNCT__ 886b78500eSPatrick Sanan #define __FUNCT__ "PCView_BDDC" 896b78500eSPatrick Sanan static PetscErrorCode PCView_BDDC(PC pc,PetscViewer viewer) 906b78500eSPatrick Sanan { 916b78500eSPatrick Sanan PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 92e9627c49SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 936b78500eSPatrick Sanan PetscErrorCode ierr; 946b78500eSPatrick Sanan PetscBool isascii,isstring; 95e9627c49SStefano Zampini PetscSubcomm subcomm; 96e9627c49SStefano Zampini PetscViewer subviewer; 976b78500eSPatrick Sanan 986b78500eSPatrick Sanan PetscFunctionBegin; 996b78500eSPatrick Sanan ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1006b78500eSPatrick Sanan ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 1016b78500eSPatrick Sanan /* Nothing printed for the String viewer */ 1026b78500eSPatrick Sanan /* ASCII viewer */ 1036b78500eSPatrick Sanan if (isascii) { 104e9627c49SStefano Zampini PetscMPIInt color,rank; 105e9627c49SStefano Zampini Petsc64bitInt loc[4],gsum[4],gmax[4],gmin[4]; 106e9627c49SStefano Zampini PetscScalar interface_size; 107e9627c49SStefano Zampini PetscReal ratio1=0.,ratio2=0.; 108e9627c49SStefano Zampini Vec counter; 1096b78500eSPatrick Sanan 110e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use verbose output: %d\n",pcbddc->dbg_flag);CHKERRQ(ierr); 111e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use user-defined CSR: %d\n",!!pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 1126b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use local mat graph: %d\n",pcbddc->use_local_adj);CHKERRQ(ierr); 113e9627c49SStefano Zampini if (pcbddc->mat_graph->twodim) { 114e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Connectivity graph topological dimension: 2\n");CHKERRQ(ierr); 115e9627c49SStefano Zampini } else { 116e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Connectivity graph topological dimension: 3\n");CHKERRQ(ierr); 117e9627c49SStefano Zampini } 118e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use vertices: %d (vertext size %d)\n",pcbddc->use_vertices,pcbddc->vertex_size);CHKERRQ(ierr); 1196b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use edges: %d\n",pcbddc->use_edges);CHKERRQ(ierr); 1206b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use faces: %d\n",pcbddc->use_faces);CHKERRQ(ierr); 1216b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use true near null space: %d\n",pcbddc->use_nnsp_true);CHKERRQ(ierr); 1226b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use QR for single constraints on cc: %d\n",pcbddc->use_qr_single);CHKERRQ(ierr); 1236b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use change of basis on local edge nodes: %d\n",pcbddc->use_change_of_basis);CHKERRQ(ierr); 1246b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use change of basis on local face nodes: %d\n",pcbddc->use_change_on_faces);CHKERRQ(ierr); 12527b6a85dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: User defined change of basis matrix: %d\n",!!pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 12627b6a85dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Has change of basis matrix: %d\n",!!pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 12727b6a85dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Eliminate dirichlet boundary dofs: %d\n",pcbddc->eliminate_dirdofs);CHKERRQ(ierr); 1286b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Switch on static condensation ops around the interface preconditioner: %d\n",pcbddc->switch_static);CHKERRQ(ierr); 12927b6a85dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use exact dirichlet trick: %d\n",pcbddc->use_exact_dirichlet_trick);CHKERRQ(ierr); 1306b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Multilevel max levels: %d\n",pcbddc->max_levels);CHKERRQ(ierr); 131e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Multilevel coarsening ratio: %d\n",pcbddc->coarsening_ratio);CHKERRQ(ierr); 1326b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use estimated eigs for coarse problem: %d\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 1336b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use deluxe scaling: %d\n",pcbddc->use_deluxe_scaling);CHKERRQ(ierr); 134e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use deluxe zerorows: %d\n",pcbddc->deluxe_zerorows);CHKERRQ(ierr); 1356b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Rebuild interface graph for Schur principal minors: %d\n",pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 1366b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Number of dofs' layers for the computation of principal minors: %d\n",pcbddc->sub_schurs_layers);CHKERRQ(ierr); 1376b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use user CSR graph to compute successive layers: %d\n",pcbddc->sub_schurs_use_useradj);CHKERRQ(ierr); 138e9627c49SStefano 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); 1396b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Min constraints / connected component: %d\n",pcbddc->adaptive_nmin);CHKERRQ(ierr); 1406b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Max constraints / connected component: %d\n",pcbddc->adaptive_nmax);CHKERRQ(ierr); 141e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Invert exact Schur complement for adaptive selection: %d\n",pcbddc->sub_schurs_exact_schur);CHKERRQ(ierr); 1426b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Symmetric computation of primal basis functions: %d\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 1436b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Num. Procs. to map coarse adjacency list: %d\n",pcbddc->coarse_adj_red);CHKERRQ(ierr); 144e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Coarse eqs per proc (significant at the coarsest level): %d\n",pcbddc->coarse_eqs_per_proc);CHKERRQ(ierr); 145e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Detect disconnected: %d\n",pcbddc->detect_disconnected);CHKERRQ(ierr); 14627b6a85dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Benign subspace trick: %d\n",pcbddc->benign_saddle_point);CHKERRQ(ierr); 14727b6a85dSStefano 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); 1486b78500eSPatrick Sanan 149e9627c49SStefano Zampini /* compute some number on the domain decomposition */ 150e9627c49SStefano Zampini ierr = VecSet(pcis->vec1_B,1.0);CHKERRQ(ierr); 151e9627c49SStefano Zampini ierr = MatCreateVecs(pc->pmat,&counter,0);CHKERRQ(ierr); 152e9627c49SStefano Zampini ierr = VecSet(counter,0.0);CHKERRQ(ierr); 153e9627c49SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 154e9627c49SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 155e9627c49SStefano Zampini ierr = VecSum(counter,&interface_size);CHKERRQ(ierr); 156e9627c49SStefano Zampini ierr = VecDestroy(&counter);CHKERRQ(ierr); 157e9627c49SStefano Zampini gsum[0] = 1; 158e9627c49SStefano Zampini gsum[1] = gsum[2] = gsum[3] = 0; 159e9627c49SStefano Zampini loc[0] = !!pcis->n; 160e9627c49SStefano Zampini loc[1] = pcis->n - pcis->n_B; 161e9627c49SStefano Zampini loc[2] = pcis->n_B; 162e9627c49SStefano Zampini loc[3] = pcbddc->local_primal_size; 163e9627c49SStefano Zampini ierr = MPI_Reduce(loc,gsum,4,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 164e9627c49SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = -1; 165e9627c49SStefano Zampini ierr = MPI_Reduce(loc,gmax,4,MPIU_INT64,MPI_MAX,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 166e9627c49SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = PETSC_MAX_INT; 167e9627c49SStefano Zampini ierr = MPI_Reduce(loc,gmin,4,MPIU_INT64,MPI_MIN,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 168e9627c49SStefano Zampini if (pcbddc->coarse_size) { 169e9627c49SStefano Zampini ratio1 = pc->pmat->rmap->N/(1.*pcbddc->coarse_size); 170e9627c49SStefano Zampini ratio2 = PetscRealPart(interface_size)/pcbddc->coarse_size; 171e9627c49SStefano Zampini } 172e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: ********************************** STATISTICS AT LEVEL %d **********************************\n",pcbddc->current_level);CHKERRQ(ierr); 173e9627c49SStefano 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); 174e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Coarsening ratios: all/coarse %d interface/coarse %d\n",(PetscInt)ratio1,(PetscInt)ratio2);CHKERRQ(ierr); 175e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Active processes : %d\n",(PetscInt)gsum[0]);CHKERRQ(ierr); 176e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Dofs type :\tMIN\tMAX\tMEAN\n",(PetscInt)gmin[1],(PetscInt)gmax[1],(PetscInt)(gsum[1]/gsum[0]));CHKERRQ(ierr); 177e9627c49SStefano 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); 178e9627c49SStefano 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); 179e9627c49SStefano 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); 18027b6a85dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: ********************************** COARSE PROBLEM DETAILS *********************************\n",pcbddc->current_level);CHKERRQ(ierr); 18127b6a85dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 182e9627c49SStefano Zampini 183e9627c49SStefano Zampini /* the coarse problem can be handled with a different communicator */ 184e9627c49SStefano Zampini if (pcbddc->coarse_ksp) color = 1; 185e9627c49SStefano Zampini else color = 0; 186e9627c49SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 187e9627c49SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)pc),&subcomm);CHKERRQ(ierr); 188e9627c49SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 189e9627c49SStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 190e9627c49SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 191e9627c49SStefano Zampini if (color == 1) { 192e9627c49SStefano Zampini ierr = KSPView(pcbddc->coarse_ksp,subviewer);CHKERRQ(ierr); 193e9627c49SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 194e9627c49SStefano Zampini } 195e9627c49SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 196e9627c49SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 197e9627c49SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 198e9627c49SStefano Zampini } 1996b78500eSPatrick Sanan PetscFunctionReturn(0); 2006b78500eSPatrick Sanan } 2016b78500eSPatrick Sanan 2020c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 203674ae819SStefano Zampini #undef __FUNCT__ 204906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCSetChangeOfBasisMat_BDDC" 2051dd7afcfSStefano Zampini static PetscErrorCode PCBDDCSetChangeOfBasisMat_BDDC(PC pc, Mat change, PetscBool interior) 206b9b85e73SStefano Zampini { 207b9b85e73SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 208b9b85e73SStefano Zampini PetscErrorCode ierr; 209b9b85e73SStefano Zampini 210b9b85e73SStefano Zampini PetscFunctionBegin; 211b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)change);CHKERRQ(ierr); 21256282151SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 213b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = change; 2141dd7afcfSStefano Zampini pcbddc->change_interior = interior; 215b9b85e73SStefano Zampini PetscFunctionReturn(0); 216b9b85e73SStefano Zampini } 217b9b85e73SStefano Zampini #undef __FUNCT__ 218906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCSetChangeOfBasisMat" 219b9b85e73SStefano Zampini /*@ 220906d46d4SStefano Zampini PCBDDCSetChangeOfBasisMat - Set user defined change of basis for dofs 221b9b85e73SStefano Zampini 222b9b85e73SStefano Zampini Collective on PC 223b9b85e73SStefano Zampini 224b9b85e73SStefano Zampini Input Parameters: 225b9b85e73SStefano Zampini + pc - the preconditioning context 2261dd7afcfSStefano Zampini . change - the change of basis matrix 2271dd7afcfSStefano Zampini - interior - whether or not the change of basis modifies interior dofs 228b9b85e73SStefano Zampini 229b9b85e73SStefano Zampini Level: intermediate 230b9b85e73SStefano Zampini 231b9b85e73SStefano Zampini Notes: 232b9b85e73SStefano Zampini 233b9b85e73SStefano Zampini .seealso: PCBDDC 234b9b85e73SStefano Zampini @*/ 2351dd7afcfSStefano Zampini PetscErrorCode PCBDDCSetChangeOfBasisMat(PC pc, Mat change, PetscBool interior) 236b9b85e73SStefano Zampini { 237b9b85e73SStefano Zampini PetscErrorCode ierr; 238b9b85e73SStefano Zampini 239b9b85e73SStefano Zampini PetscFunctionBegin; 240b9b85e73SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 241b9b85e73SStefano Zampini PetscValidHeaderSpecific(change,MAT_CLASSID,2); 242906d46d4SStefano Zampini PetscCheckSameComm(pc,1,change,2); 243906d46d4SStefano Zampini if (pc->mat) { 244906d46d4SStefano Zampini PetscInt rows_c,cols_c,rows,cols; 245906d46d4SStefano Zampini ierr = MatGetSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 246906d46d4SStefano Zampini ierr = MatGetSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 2476c4ed002SBarry 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); 2486c4ed002SBarry 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); 249906d46d4SStefano Zampini ierr = MatGetLocalSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 250906d46d4SStefano Zampini ierr = MatGetLocalSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 2516c4ed002SBarry 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); 2526c4ed002SBarry 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); 253906d46d4SStefano Zampini } 2541dd7afcfSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetChangeOfBasisMat_C",(PC,Mat,PetscBool),(pc,change,interior));CHKERRQ(ierr); 255b9b85e73SStefano Zampini PetscFunctionReturn(0); 256b9b85e73SStefano Zampini } 257b9b85e73SStefano Zampini /* -------------------------------------------------------------------------- */ 258b9b85e73SStefano Zampini #undef __FUNCT__ 25930368db7SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesIS_BDDC" 26030368db7SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesIS_BDDC(PC pc, IS PrimalVertices) 26130368db7SStefano Zampini { 26230368db7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 26356282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 26430368db7SStefano Zampini PetscErrorCode ierr; 26530368db7SStefano Zampini 26630368db7SStefano Zampini PetscFunctionBegin; 26756282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 26856282151SStefano Zampini if (pcbddc->user_primal_vertices) { 26956282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices,&isequal);CHKERRQ(ierr); 27056282151SStefano Zampini } 27130368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 27230368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 27330368db7SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 27456282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 27530368db7SStefano Zampini PetscFunctionReturn(0); 27630368db7SStefano Zampini } 27730368db7SStefano Zampini #undef __FUNCT__ 27830368db7SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesIS" 27930368db7SStefano Zampini /*@ 28030368db7SStefano Zampini PCBDDCSetPrimalVerticesIS - Set additional user defined primal vertices in PCBDDC 28130368db7SStefano Zampini 28230368db7SStefano Zampini Collective 28330368db7SStefano Zampini 28430368db7SStefano Zampini Input Parameters: 28530368db7SStefano Zampini + pc - the preconditioning context 28630368db7SStefano Zampini - PrimalVertices - index set of primal vertices in global numbering (can be empty) 28730368db7SStefano Zampini 28830368db7SStefano Zampini Level: intermediate 28930368db7SStefano Zampini 29030368db7SStefano Zampini Notes: 29130368db7SStefano Zampini Any process can list any global node 29230368db7SStefano Zampini 29330368db7SStefano Zampini .seealso: PCBDDC 29430368db7SStefano Zampini @*/ 29530368db7SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesIS(PC pc, IS PrimalVertices) 29630368db7SStefano Zampini { 29730368db7SStefano Zampini PetscErrorCode ierr; 29830368db7SStefano Zampini 29930368db7SStefano Zampini PetscFunctionBegin; 30030368db7SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 30130368db7SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 30230368db7SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 30330368db7SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 30430368db7SStefano Zampini PetscFunctionReturn(0); 30530368db7SStefano Zampini } 30630368db7SStefano Zampini /* -------------------------------------------------------------------------- */ 30730368db7SStefano Zampini #undef __FUNCT__ 308674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS_BDDC" 309674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 310674ae819SStefano Zampini { 311674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 31256282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 313674ae819SStefano Zampini PetscErrorCode ierr; 3141e6b0712SBarry Smith 315674ae819SStefano Zampini PetscFunctionBegin; 31656282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 31756282151SStefano Zampini if (pcbddc->user_primal_vertices_local) { 31856282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices_local,&isequal);CHKERRQ(ierr); 31956282151SStefano Zampini } 320674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 32130368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 32230368db7SStefano Zampini pcbddc->user_primal_vertices_local = PrimalVertices; 32356282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 324674ae819SStefano Zampini PetscFunctionReturn(0); 325674ae819SStefano Zampini } 326674ae819SStefano Zampini #undef __FUNCT__ 327674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS" 328674ae819SStefano Zampini /*@ 32928509bceSStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC 330674ae819SStefano Zampini 33117eb1463SStefano Zampini Collective 332674ae819SStefano Zampini 333674ae819SStefano Zampini Input Parameters: 334674ae819SStefano Zampini + pc - the preconditioning context 33517eb1463SStefano Zampini - PrimalVertices - index set of primal vertices in local numbering (can be empty) 336674ae819SStefano Zampini 337674ae819SStefano Zampini Level: intermediate 338674ae819SStefano Zampini 339674ae819SStefano Zampini Notes: 340674ae819SStefano Zampini 341674ae819SStefano Zampini .seealso: PCBDDC 342674ae819SStefano Zampini @*/ 343674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 344674ae819SStefano Zampini { 345674ae819SStefano Zampini PetscErrorCode ierr; 346674ae819SStefano Zampini 347674ae819SStefano Zampini PetscFunctionBegin; 348674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 349674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 35017eb1463SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 351674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 352674ae819SStefano Zampini PetscFunctionReturn(0); 353674ae819SStefano Zampini } 354674ae819SStefano Zampini /* -------------------------------------------------------------------------- */ 3550c7d97c5SJed Brown #undef __FUNCT__ 3564fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio_BDDC" 3574fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 3584fad6a16SStefano Zampini { 3594fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3604fad6a16SStefano Zampini 3614fad6a16SStefano Zampini PetscFunctionBegin; 3624fad6a16SStefano Zampini pcbddc->coarsening_ratio = k; 3634fad6a16SStefano Zampini PetscFunctionReturn(0); 3644fad6a16SStefano Zampini } 3651e6b0712SBarry Smith 3664fad6a16SStefano Zampini #undef __FUNCT__ 3674fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio" 3684fad6a16SStefano Zampini /*@ 36928509bceSStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel 3704fad6a16SStefano Zampini 3714fad6a16SStefano Zampini Logically collective on PC 3724fad6a16SStefano Zampini 3734fad6a16SStefano Zampini Input Parameters: 3744fad6a16SStefano Zampini + pc - the preconditioning context 37528509bceSStefano Zampini - k - coarsening ratio (H/h at the coarser level) 3764fad6a16SStefano Zampini 3770f202f7eSStefano Zampini Options Database Keys: 3780f202f7eSStefano Zampini . -pc_bddc_coarsening_ratio 3794fad6a16SStefano Zampini 3804fad6a16SStefano Zampini Level: intermediate 3814fad6a16SStefano Zampini 3824fad6a16SStefano Zampini Notes: 3830f202f7eSStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level 3844fad6a16SStefano Zampini 3850f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetLevels() 3864fad6a16SStefano Zampini @*/ 3874fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 3884fad6a16SStefano Zampini { 3894fad6a16SStefano Zampini PetscErrorCode ierr; 3904fad6a16SStefano Zampini 3914fad6a16SStefano Zampini PetscFunctionBegin; 3924fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 3932b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,k,2); 3944fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 3954fad6a16SStefano Zampini PetscFunctionReturn(0); 3964fad6a16SStefano Zampini } 3972b510759SStefano Zampini 398b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */ 3992b510759SStefano Zampini #undef __FUNCT__ 400b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet_BDDC" 401b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg) 402b8ffe317SStefano Zampini { 403b8ffe317SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 404b8ffe317SStefano Zampini 405b8ffe317SStefano Zampini PetscFunctionBegin; 40685c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = flg; 407b8ffe317SStefano Zampini PetscFunctionReturn(0); 408b8ffe317SStefano Zampini } 409b8ffe317SStefano Zampini 410b8ffe317SStefano Zampini #undef __FUNCT__ 411b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet" 412b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg) 4132b510759SStefano Zampini { 4142b510759SStefano Zampini PetscErrorCode ierr; 4152b510759SStefano Zampini 4162b510759SStefano Zampini PetscFunctionBegin; 4172b510759SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 418b8ffe317SStefano Zampini PetscValidLogicalCollectiveBool(pc,flg,2); 419b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr); 4202b510759SStefano Zampini PetscFunctionReturn(0); 4212b510759SStefano Zampini } 4221e6b0712SBarry Smith 4234fad6a16SStefano Zampini #undef __FUNCT__ 4242b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel_BDDC" 4252b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level) 4264fad6a16SStefano Zampini { 4274fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4284fad6a16SStefano Zampini 4294fad6a16SStefano Zampini PetscFunctionBegin; 4302b510759SStefano Zampini pcbddc->current_level = level; 4314fad6a16SStefano Zampini PetscFunctionReturn(0); 4324fad6a16SStefano Zampini } 4331e6b0712SBarry Smith 4344fad6a16SStefano Zampini #undef __FUNCT__ 435b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel" 436b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 437b8ffe317SStefano Zampini { 438b8ffe317SStefano Zampini PetscErrorCode ierr; 439b8ffe317SStefano Zampini 440b8ffe317SStefano Zampini PetscFunctionBegin; 441b8ffe317SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 442b8ffe317SStefano Zampini PetscValidLogicalCollectiveInt(pc,level,2); 443b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr); 444b8ffe317SStefano Zampini PetscFunctionReturn(0); 445b8ffe317SStefano Zampini } 446b8ffe317SStefano Zampini 447b8ffe317SStefano Zampini #undef __FUNCT__ 4482b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels_BDDC" 4492b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels) 4502b510759SStefano Zampini { 4512b510759SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4522b510759SStefano Zampini 4532b510759SStefano Zampini PetscFunctionBegin; 4542b510759SStefano Zampini pcbddc->max_levels = levels; 4552b510759SStefano Zampini PetscFunctionReturn(0); 4562b510759SStefano Zampini } 4572b510759SStefano Zampini 4582b510759SStefano Zampini #undef __FUNCT__ 4592b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels" 4604fad6a16SStefano Zampini /*@ 46128509bceSStefano Zampini PCBDDCSetLevels - Sets the maximum number of levels for multilevel 4624fad6a16SStefano Zampini 4634fad6a16SStefano Zampini Logically collective on PC 4644fad6a16SStefano Zampini 4654fad6a16SStefano Zampini Input Parameters: 4664fad6a16SStefano Zampini + pc - the preconditioning context 46728509bceSStefano Zampini - levels - the maximum number of levels (max 9) 4684fad6a16SStefano Zampini 4690f202f7eSStefano Zampini Options Database Keys: 4700f202f7eSStefano Zampini . -pc_bddc_levels 4714fad6a16SStefano Zampini 4724fad6a16SStefano Zampini Level: intermediate 4734fad6a16SStefano Zampini 4744fad6a16SStefano Zampini Notes: 4750f202f7eSStefano Zampini Default value is 0, i.e. traditional one-level BDDC 4764fad6a16SStefano Zampini 4770f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetCoarseningRatio() 4784fad6a16SStefano Zampini @*/ 4792b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels) 4804fad6a16SStefano Zampini { 4814fad6a16SStefano Zampini PetscErrorCode ierr; 4824fad6a16SStefano Zampini 4834fad6a16SStefano Zampini PetscFunctionBegin; 4844fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 4852b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,levels,2); 486312be037SStefano Zampini if (levels > 99) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Maximum number of levels for bddc is 99\n"); 4872b510759SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr); 4884fad6a16SStefano Zampini PetscFunctionReturn(0); 4894fad6a16SStefano Zampini } 4904fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 4911e6b0712SBarry Smith 4924fad6a16SStefano Zampini #undef __FUNCT__ 4930bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace_BDDC" 4940bdf917eSStefano Zampini static PetscErrorCode PCBDDCSetNullSpace_BDDC(PC pc,MatNullSpace NullSpace) 4950bdf917eSStefano Zampini { 4960bdf917eSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4970bdf917eSStefano Zampini PetscErrorCode ierr; 4980bdf917eSStefano Zampini 4990bdf917eSStefano Zampini PetscFunctionBegin; 5000bdf917eSStefano Zampini ierr = PetscObjectReference((PetscObject)NullSpace);CHKERRQ(ierr); 5010bdf917eSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 5020bdf917eSStefano Zampini pcbddc->NullSpace = NullSpace; 5030bdf917eSStefano Zampini PetscFunctionReturn(0); 5040bdf917eSStefano Zampini } 5051e6b0712SBarry Smith 5060bdf917eSStefano Zampini #undef __FUNCT__ 5070bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace" 5080bdf917eSStefano Zampini /*@ 50928509bceSStefano Zampini PCBDDCSetNullSpace - Set nullspace for BDDC operator 5100bdf917eSStefano Zampini 5110bdf917eSStefano Zampini Logically collective on PC and MatNullSpace 5120bdf917eSStefano Zampini 5130bdf917eSStefano Zampini Input Parameters: 5140bdf917eSStefano Zampini + pc - the preconditioning context 51528509bceSStefano Zampini - NullSpace - Null space of the linear operator to be preconditioned (Pmat) 5160bdf917eSStefano Zampini 5170bdf917eSStefano Zampini Level: intermediate 5180bdf917eSStefano Zampini 5190bdf917eSStefano Zampini Notes: 5200bdf917eSStefano Zampini 5210bdf917eSStefano Zampini .seealso: PCBDDC 5220bdf917eSStefano Zampini @*/ 5230bdf917eSStefano Zampini PetscErrorCode PCBDDCSetNullSpace(PC pc,MatNullSpace NullSpace) 5240bdf917eSStefano Zampini { 5250bdf917eSStefano Zampini PetscErrorCode ierr; 5260bdf917eSStefano Zampini 5270bdf917eSStefano Zampini PetscFunctionBegin; 5280bdf917eSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 529674ae819SStefano Zampini PetscValidHeaderSpecific(NullSpace,MAT_NULLSPACE_CLASSID,2); 5302b510759SStefano Zampini PetscCheckSameComm(pc,1,NullSpace,2); 5310bdf917eSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNullSpace_C",(PC,MatNullSpace),(pc,NullSpace));CHKERRQ(ierr); 5320bdf917eSStefano Zampini PetscFunctionReturn(0); 5330bdf917eSStefano Zampini } 5340bdf917eSStefano Zampini /* -------------------------------------------------------------------------- */ 5351e6b0712SBarry Smith 5360bdf917eSStefano Zampini #undef __FUNCT__ 5373b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC" 5383b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 5393b03a366Sstefano_zampini { 5403b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 54156282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 5423b03a366Sstefano_zampini PetscErrorCode ierr; 5433b03a366Sstefano_zampini 5443b03a366Sstefano_zampini PetscFunctionBegin; 54556282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 54656282151SStefano Zampini if (pcbddc->DirichletBoundaries) { 54756282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundaries,&isequal);CHKERRQ(ierr); 54856282151SStefano Zampini } 549785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 550785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 5513b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 55236e030ebSStefano Zampini pcbddc->DirichletBoundaries = DirichletBoundaries; 55356282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 5543b03a366Sstefano_zampini PetscFunctionReturn(0); 5553b03a366Sstefano_zampini } 5561e6b0712SBarry Smith 5573b03a366Sstefano_zampini #undef __FUNCT__ 5583b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries" 5593b03a366Sstefano_zampini /*@ 56028509bceSStefano Zampini PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem. 5613b03a366Sstefano_zampini 562785d1243SStefano Zampini Collective 5633b03a366Sstefano_zampini 5643b03a366Sstefano_zampini Input Parameters: 5653b03a366Sstefano_zampini + pc - the preconditioning context 566785d1243SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries 5673b03a366Sstefano_zampini 5683b03a366Sstefano_zampini Level: intermediate 5693b03a366Sstefano_zampini 5700f202f7eSStefano Zampini Notes: 5710f202f7eSStefano Zampini Provide the information if you used MatZeroRows/Columns routines. Any process can list any global node 5723b03a366Sstefano_zampini 5730f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundariesLocal(), MatZeroRows(), MatZeroRowsColumns() 5743b03a366Sstefano_zampini @*/ 5753b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 5763b03a366Sstefano_zampini { 5773b03a366Sstefano_zampini PetscErrorCode ierr; 5783b03a366Sstefano_zampini 5793b03a366Sstefano_zampini PetscFunctionBegin; 5803b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 581674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 582785d1243SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 5833b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 5843b03a366Sstefano_zampini PetscFunctionReturn(0); 5853b03a366Sstefano_zampini } 5863b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 5871e6b0712SBarry Smith 5883b03a366Sstefano_zampini #undef __FUNCT__ 58982ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal_BDDC" 59082ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries) 5910c7d97c5SJed Brown { 5920c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 59356282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 5940c7d97c5SJed Brown PetscErrorCode ierr; 5950c7d97c5SJed Brown 5960c7d97c5SJed Brown PetscFunctionBegin; 59756282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 59856282151SStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 59956282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundariesLocal,&isequal);CHKERRQ(ierr); 60056282151SStefano Zampini } 601785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 602785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 6030c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 604785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = DirichletBoundaries; 60556282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 6060c7d97c5SJed Brown PetscFunctionReturn(0); 6070c7d97c5SJed Brown } 6080c7d97c5SJed Brown 6090c7d97c5SJed Brown #undef __FUNCT__ 61082ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal" 6119c0446d6SStefano Zampini /*@ 61282ba6b80SStefano Zampini PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering. 6139c0446d6SStefano Zampini 614785d1243SStefano Zampini Collective 61553cdbc3dSStefano Zampini 61653cdbc3dSStefano Zampini Input Parameters: 61753cdbc3dSStefano Zampini + pc - the preconditioning context 61882ba6b80SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering) 61953cdbc3dSStefano Zampini 62053cdbc3dSStefano Zampini Level: intermediate 62153cdbc3dSStefano Zampini 6229c0446d6SStefano Zampini Notes: 62353cdbc3dSStefano Zampini 6240f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundaries(), MatZeroRows(), MatZeroRowsColumns() 62553cdbc3dSStefano Zampini @*/ 62682ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries) 6270c7d97c5SJed Brown { 6280c7d97c5SJed Brown PetscErrorCode ierr; 6290c7d97c5SJed Brown 6300c7d97c5SJed Brown PetscFunctionBegin; 6310c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6320c7d97c5SJed Brown PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 63382ba6b80SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 63482ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 6350c7d97c5SJed Brown PetscFunctionReturn(0); 6360c7d97c5SJed Brown } 6370c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 6380c7d97c5SJed Brown 6390c7d97c5SJed Brown #undef __FUNCT__ 6400c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 64153cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 6420c7d97c5SJed Brown { 6430c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 64456282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 64553cdbc3dSStefano Zampini PetscErrorCode ierr; 6460c7d97c5SJed Brown 6470c7d97c5SJed Brown PetscFunctionBegin; 64856282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 64956282151SStefano Zampini if (pcbddc->NeumannBoundaries) { 65056282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundaries,&isequal);CHKERRQ(ierr); 65156282151SStefano Zampini } 652785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 653785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 65453cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 65536e030ebSStefano Zampini pcbddc->NeumannBoundaries = NeumannBoundaries; 65656282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 6570c7d97c5SJed Brown PetscFunctionReturn(0); 6580c7d97c5SJed Brown } 6591e6b0712SBarry Smith 6600c7d97c5SJed Brown #undef __FUNCT__ 6610c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 66257527edcSJed Brown /*@ 66328509bceSStefano Zampini PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem. 66457527edcSJed Brown 665785d1243SStefano Zampini Collective 66657527edcSJed Brown 66757527edcSJed Brown Input Parameters: 66857527edcSJed Brown + pc - the preconditioning context 669785d1243SStefano Zampini - NeumannBoundaries - parallel IS defining the Neumann boundaries 67057527edcSJed Brown 67157527edcSJed Brown Level: intermediate 67257527edcSJed Brown 6730f202f7eSStefano Zampini Notes: 6740f202f7eSStefano Zampini Any process can list any global node 67557527edcSJed Brown 6760f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundariesLocal() 67757527edcSJed Brown @*/ 67853cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 6790c7d97c5SJed Brown { 6800c7d97c5SJed Brown PetscErrorCode ierr; 6810c7d97c5SJed Brown 6820c7d97c5SJed Brown PetscFunctionBegin; 6830c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 684674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 685785d1243SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 68653cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 68753cdbc3dSStefano Zampini PetscFunctionReturn(0); 68853cdbc3dSStefano Zampini } 68953cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 6901e6b0712SBarry Smith 69153cdbc3dSStefano Zampini #undef __FUNCT__ 69282ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal_BDDC" 69382ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries) 6940c7d97c5SJed Brown { 6950c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 69656282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 6970c7d97c5SJed Brown PetscErrorCode ierr; 6980c7d97c5SJed Brown 6990c7d97c5SJed Brown PetscFunctionBegin; 70056282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 70156282151SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 70256282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundariesLocal,&isequal);CHKERRQ(ierr); 70356282151SStefano Zampini } 704785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 705785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 7060c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 707785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = NeumannBoundaries; 70856282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7090c7d97c5SJed Brown PetscFunctionReturn(0); 7100c7d97c5SJed Brown } 7110c7d97c5SJed Brown 7120c7d97c5SJed Brown #undef __FUNCT__ 71382ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal" 7140c7d97c5SJed Brown /*@ 71582ba6b80SStefano Zampini PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering. 7160c7d97c5SJed Brown 717785d1243SStefano Zampini Collective 7180c7d97c5SJed Brown 7190c7d97c5SJed Brown Input Parameters: 7200c7d97c5SJed Brown + pc - the preconditioning context 72182ba6b80SStefano Zampini - NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering) 7220c7d97c5SJed Brown 7230c7d97c5SJed Brown Level: intermediate 7240c7d97c5SJed Brown 7250c7d97c5SJed Brown Notes: 7260c7d97c5SJed Brown 7270f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundaries() 7280c7d97c5SJed Brown @*/ 72982ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries) 7300c7d97c5SJed Brown { 7310c7d97c5SJed Brown PetscErrorCode ierr; 7320c7d97c5SJed Brown 7330c7d97c5SJed Brown PetscFunctionBegin; 7340c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 7350c7d97c5SJed Brown PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 73682ba6b80SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 73782ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 73853cdbc3dSStefano Zampini PetscFunctionReturn(0); 73953cdbc3dSStefano Zampini } 74053cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 74153cdbc3dSStefano Zampini 74253cdbc3dSStefano Zampini #undef __FUNCT__ 743da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC" 744da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 745da1bb401SStefano Zampini { 746da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 747da1bb401SStefano Zampini 748da1bb401SStefano Zampini PetscFunctionBegin; 749da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 750da1bb401SStefano Zampini PetscFunctionReturn(0); 751da1bb401SStefano Zampini } 7521e6b0712SBarry Smith 753da1bb401SStefano Zampini #undef __FUNCT__ 754da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries" 755da1bb401SStefano Zampini /*@ 756785d1243SStefano Zampini PCBDDCGetDirichletBoundaries - Get parallel IS for Dirichlet boundaries 757da1bb401SStefano Zampini 758785d1243SStefano Zampini Collective 759785d1243SStefano Zampini 760785d1243SStefano Zampini Input Parameters: 761785d1243SStefano Zampini . pc - the preconditioning context 762785d1243SStefano Zampini 763785d1243SStefano Zampini Output Parameters: 764785d1243SStefano Zampini . DirichletBoundaries - index set defining the Dirichlet boundaries 765785d1243SStefano Zampini 766785d1243SStefano Zampini Level: intermediate 767785d1243SStefano Zampini 7680f202f7eSStefano Zampini Notes: 7690f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetDirichletBoundaries 770785d1243SStefano Zampini 771785d1243SStefano Zampini .seealso: PCBDDC 772785d1243SStefano Zampini @*/ 773785d1243SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 774785d1243SStefano Zampini { 775785d1243SStefano Zampini PetscErrorCode ierr; 776785d1243SStefano Zampini 777785d1243SStefano Zampini PetscFunctionBegin; 778785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 779785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 780785d1243SStefano Zampini PetscFunctionReturn(0); 781785d1243SStefano Zampini } 782785d1243SStefano Zampini /* -------------------------------------------------------------------------- */ 783785d1243SStefano Zampini 784785d1243SStefano Zampini #undef __FUNCT__ 785785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal_BDDC" 786785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries) 787785d1243SStefano Zampini { 788785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 789785d1243SStefano Zampini 790785d1243SStefano Zampini PetscFunctionBegin; 791785d1243SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundariesLocal; 792785d1243SStefano Zampini PetscFunctionReturn(0); 793785d1243SStefano Zampini } 794785d1243SStefano Zampini 795785d1243SStefano Zampini #undef __FUNCT__ 79682ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal" 797da1bb401SStefano Zampini /*@ 79882ba6b80SStefano Zampini PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering) 799da1bb401SStefano Zampini 800785d1243SStefano Zampini Collective 801da1bb401SStefano Zampini 802da1bb401SStefano Zampini Input Parameters: 80328509bceSStefano Zampini . pc - the preconditioning context 804da1bb401SStefano Zampini 805da1bb401SStefano Zampini Output Parameters: 80628509bceSStefano Zampini . DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 807da1bb401SStefano Zampini 808da1bb401SStefano Zampini Level: intermediate 809da1bb401SStefano Zampini 810da1bb401SStefano Zampini Notes: 8110f202f7eSStefano 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). 8120f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 813da1bb401SStefano Zampini 814da1bb401SStefano Zampini .seealso: PCBDDC 815da1bb401SStefano Zampini @*/ 81682ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries) 817da1bb401SStefano Zampini { 818da1bb401SStefano Zampini PetscErrorCode ierr; 819da1bb401SStefano Zampini 820da1bb401SStefano Zampini PetscFunctionBegin; 821da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 82282ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 823da1bb401SStefano Zampini PetscFunctionReturn(0); 824da1bb401SStefano Zampini } 825da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 8261e6b0712SBarry Smith 827da1bb401SStefano Zampini #undef __FUNCT__ 82853cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 82953cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 83053cdbc3dSStefano Zampini { 83153cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 83253cdbc3dSStefano Zampini 83353cdbc3dSStefano Zampini PetscFunctionBegin; 83453cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 83553cdbc3dSStefano Zampini PetscFunctionReturn(0); 83653cdbc3dSStefano Zampini } 8371e6b0712SBarry Smith 83853cdbc3dSStefano Zampini #undef __FUNCT__ 83953cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 84053cdbc3dSStefano Zampini /*@ 841785d1243SStefano Zampini PCBDDCGetNeumannBoundaries - Get parallel IS for Neumann boundaries 84253cdbc3dSStefano Zampini 843785d1243SStefano Zampini Collective 844785d1243SStefano Zampini 845785d1243SStefano Zampini Input Parameters: 846785d1243SStefano Zampini . pc - the preconditioning context 847785d1243SStefano Zampini 848785d1243SStefano Zampini Output Parameters: 849785d1243SStefano Zampini . NeumannBoundaries - index set defining the Neumann boundaries 850785d1243SStefano Zampini 851785d1243SStefano Zampini Level: intermediate 852785d1243SStefano Zampini 8530f202f7eSStefano Zampini Notes: 8540f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetNeumannBoundaries 855785d1243SStefano Zampini 856785d1243SStefano Zampini .seealso: PCBDDC 857785d1243SStefano Zampini @*/ 858785d1243SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 859785d1243SStefano Zampini { 860785d1243SStefano Zampini PetscErrorCode ierr; 861785d1243SStefano Zampini 862785d1243SStefano Zampini PetscFunctionBegin; 863785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 864785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 865785d1243SStefano Zampini PetscFunctionReturn(0); 866785d1243SStefano Zampini } 867785d1243SStefano Zampini /* -------------------------------------------------------------------------- */ 868785d1243SStefano Zampini 869785d1243SStefano Zampini #undef __FUNCT__ 870785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal_BDDC" 871785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries) 872785d1243SStefano Zampini { 873785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 874785d1243SStefano Zampini 875785d1243SStefano Zampini PetscFunctionBegin; 876785d1243SStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundariesLocal; 877785d1243SStefano Zampini PetscFunctionReturn(0); 878785d1243SStefano Zampini } 879785d1243SStefano Zampini 880785d1243SStefano Zampini #undef __FUNCT__ 88182ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal" 88253cdbc3dSStefano Zampini /*@ 88382ba6b80SStefano Zampini PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering) 88453cdbc3dSStefano Zampini 885785d1243SStefano Zampini Collective 88653cdbc3dSStefano Zampini 88753cdbc3dSStefano Zampini Input Parameters: 88828509bceSStefano Zampini . pc - the preconditioning context 88953cdbc3dSStefano Zampini 89053cdbc3dSStefano Zampini Output Parameters: 89128509bceSStefano Zampini . NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 89253cdbc3dSStefano Zampini 89353cdbc3dSStefano Zampini Level: intermediate 89453cdbc3dSStefano Zampini 89553cdbc3dSStefano Zampini Notes: 8960f202f7eSStefano 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). 8970f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 89853cdbc3dSStefano Zampini 89953cdbc3dSStefano Zampini .seealso: PCBDDC 90053cdbc3dSStefano Zampini @*/ 90182ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries) 90253cdbc3dSStefano Zampini { 90353cdbc3dSStefano Zampini PetscErrorCode ierr; 90453cdbc3dSStefano Zampini 90553cdbc3dSStefano Zampini PetscFunctionBegin; 90653cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 90782ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 9080c7d97c5SJed Brown PetscFunctionReturn(0); 9090c7d97c5SJed Brown } 91036e030ebSStefano Zampini /* -------------------------------------------------------------------------- */ 9111e6b0712SBarry Smith 91236e030ebSStefano Zampini #undef __FUNCT__ 913da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC" 9141a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 91536e030ebSStefano Zampini { 91636e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 917da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 91856282151SStefano Zampini PetscBool same_data = PETSC_FALSE; 919da1bb401SStefano Zampini PetscErrorCode ierr; 92036e030ebSStefano Zampini 92136e030ebSStefano Zampini PetscFunctionBegin; 9228687889aSStefano Zampini if (!nvtxs) { 9238687889aSStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 9248687889aSStefano Zampini PetscFunctionReturn(0); 9258687889aSStefano Zampini } 92656282151SStefano Zampini if (mat_graph->nvtxs_csr == nvtxs) { 92756282151SStefano Zampini if (mat_graph->xadj == xadj && mat_graph->adjncy == adjncy) same_data = PETSC_TRUE; 92856282151SStefano Zampini if (!same_data && mat_graph->xadj[nvtxs] == xadj[nvtxs]) { 92956282151SStefano Zampini ierr = PetscMemcmp(adjncy,mat_graph->adjncy,nvtxs*sizeof(PetscInt),&same_data);CHKERRQ(ierr); 93056282151SStefano Zampini } 93156282151SStefano Zampini } 93256282151SStefano Zampini if (!same_data) { 933674ae819SStefano Zampini /* free old CSR */ 934674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 935674ae819SStefano Zampini /* get CSR into graph structure */ 936da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 937854ce69bSBarry Smith ierr = PetscMalloc1(nvtxs+1,&mat_graph->xadj);CHKERRQ(ierr); 938785e854fSJed Brown ierr = PetscMalloc1(xadj[nvtxs],&mat_graph->adjncy);CHKERRQ(ierr); 939674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 940674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 941da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 9421a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 9431a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 944674ae819SStefano Zampini } 945575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 94656282151SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 94756282151SStefano Zampini } 94836e030ebSStefano Zampini PetscFunctionReturn(0); 94936e030ebSStefano Zampini } 9501e6b0712SBarry Smith 95136e030ebSStefano Zampini #undef __FUNCT__ 952da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph" 95336e030ebSStefano Zampini /*@ 9540f202f7eSStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local matrix 95536e030ebSStefano Zampini 95636e030ebSStefano Zampini Not collective 95736e030ebSStefano Zampini 95836e030ebSStefano Zampini Input Parameters: 95936e030ebSStefano Zampini + pc - the preconditioning context 9600f202f7eSStefano Zampini . nvtxs - number of local vertices of the graph (i.e., the size of the local problem) 96128509bceSStefano Zampini . xadj, adjncy - the CSR graph 96228509bceSStefano Zampini - copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER. 96336e030ebSStefano Zampini 96436e030ebSStefano Zampini Level: intermediate 96536e030ebSStefano Zampini 96636e030ebSStefano Zampini Notes: 96736e030ebSStefano Zampini 96828509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode 96936e030ebSStefano Zampini @*/ 9701a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 97136e030ebSStefano Zampini { 972575ad6abSStefano Zampini void (*f)(void) = 0; 97336e030ebSStefano Zampini PetscErrorCode ierr; 97436e030ebSStefano Zampini 97536e030ebSStefano Zampini PetscFunctionBegin; 97636e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 9778687889aSStefano Zampini if (nvtxs) { 978674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 979d7de1dd9SStefano Zampini PetscValidIntPointer(adjncy,4); 9808687889aSStefano Zampini } 9816c4ed002SBarry Smith if (copymode != PETSC_COPY_VALUES && copymode != PETSC_OWN_POINTER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d",copymode); 9821a83f524SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 983575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 984575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 985575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 986575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 987575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 988da1bb401SStefano Zampini } 98936e030ebSStefano Zampini PetscFunctionReturn(0); 99036e030ebSStefano Zampini } 9919c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 9921e6b0712SBarry Smith 9939c0446d6SStefano Zampini #undef __FUNCT__ 99463602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal_BDDC" 99563602bcaSStefano Zampini static PetscErrorCode PCBDDCSetDofsSplittingLocal_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 99663602bcaSStefano Zampini { 99763602bcaSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 99863602bcaSStefano Zampini PetscInt i; 99956282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 100063602bcaSStefano Zampini PetscErrorCode ierr; 100163602bcaSStefano Zampini 100263602bcaSStefano Zampini PetscFunctionBegin; 100356282151SStefano Zampini if (pcbddc->n_ISForDofsLocal == n_is) { 100456282151SStefano Zampini for (i=0;i<n_is;i++) { 100556282151SStefano Zampini PetscBool isequalt; 100656282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofsLocal[i],&isequalt);CHKERRQ(ierr); 100756282151SStefano Zampini if (!isequalt) break; 100856282151SStefano Zampini } 100956282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 101056282151SStefano Zampini } 101156282151SStefano Zampini for (i=0;i<n_is;i++) { 101256282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 101356282151SStefano Zampini } 101463602bcaSStefano Zampini /* Destroy ISes if they were already set */ 101563602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 101663602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 101763602bcaSStefano Zampini } 101863602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 101963602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 102063602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 102163602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 102263602bcaSStefano Zampini } 102363602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 102463602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 102563602bcaSStefano Zampini /* allocate space then set */ 1026d02579f5SStefano Zampini if (n_is) { 1027d02579f5SStefano Zampini ierr = PetscMalloc1(n_is,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1028d02579f5SStefano Zampini } 102963602bcaSStefano Zampini for (i=0;i<n_is;i++) { 103063602bcaSStefano Zampini pcbddc->ISForDofsLocal[i] = ISForDofs[i]; 103163602bcaSStefano Zampini } 103263602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = n_is; 103363602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 103456282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 103563602bcaSStefano Zampini PetscFunctionReturn(0); 103663602bcaSStefano Zampini } 103763602bcaSStefano Zampini 103863602bcaSStefano Zampini #undef __FUNCT__ 103963602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal" 104063602bcaSStefano Zampini /*@ 104163602bcaSStefano Zampini PCBDDCSetDofsSplittingLocal - Set index sets defining fields of the local subdomain matrix 104263602bcaSStefano Zampini 104363602bcaSStefano Zampini Collective 104463602bcaSStefano Zampini 104563602bcaSStefano Zampini Input Parameters: 104663602bcaSStefano Zampini + pc - the preconditioning context 10470f202f7eSStefano Zampini . n_is - number of index sets defining the fields 10480f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in local ordering 104963602bcaSStefano Zampini 105063602bcaSStefano Zampini Level: intermediate 105163602bcaSStefano Zampini 10520f202f7eSStefano Zampini Notes: 10530f202f7eSStefano Zampini n_is should be the same among processes. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 105463602bcaSStefano Zampini 105563602bcaSStefano Zampini .seealso: PCBDDC 105663602bcaSStefano Zampini @*/ 105763602bcaSStefano Zampini PetscErrorCode PCBDDCSetDofsSplittingLocal(PC pc,PetscInt n_is, IS ISForDofs[]) 105863602bcaSStefano Zampini { 105963602bcaSStefano Zampini PetscInt i; 106063602bcaSStefano Zampini PetscErrorCode ierr; 106163602bcaSStefano Zampini 106263602bcaSStefano Zampini PetscFunctionBegin; 106363602bcaSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 106463602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 106563602bcaSStefano Zampini for (i=0;i<n_is;i++) { 106663602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 106763602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 106863602bcaSStefano Zampini } 1069e71e7a71SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplittingLocal_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 107063602bcaSStefano Zampini PetscFunctionReturn(0); 107163602bcaSStefano Zampini } 107263602bcaSStefano Zampini /* -------------------------------------------------------------------------- */ 107363602bcaSStefano Zampini 107463602bcaSStefano Zampini #undef __FUNCT__ 10759c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 10769c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 10779c0446d6SStefano Zampini { 10789c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 10799c0446d6SStefano Zampini PetscInt i; 108056282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 10819c0446d6SStefano Zampini PetscErrorCode ierr; 10829c0446d6SStefano Zampini 10839c0446d6SStefano Zampini PetscFunctionBegin; 108456282151SStefano Zampini if (pcbddc->n_ISForDofs == n_is) { 108556282151SStefano Zampini for (i=0;i<n_is;i++) { 108656282151SStefano Zampini PetscBool isequalt; 108756282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofs[i],&isequalt);CHKERRQ(ierr); 108856282151SStefano Zampini if (!isequalt) break; 108956282151SStefano Zampini } 109056282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 109156282151SStefano Zampini } 109256282151SStefano Zampini for (i=0;i<n_is;i++) { 109356282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 109456282151SStefano Zampini } 1095da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 10969c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 10979c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 10989c0446d6SStefano Zampini } 1099d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 110063602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 110163602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 110263602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 110363602bcaSStefano Zampini } 110463602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 110563602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 1106da1bb401SStefano Zampini /* allocate space then set */ 1107d02579f5SStefano Zampini if (n_is) { 1108785e854fSJed Brown ierr = PetscMalloc1(n_is,&pcbddc->ISForDofs);CHKERRQ(ierr); 1109d02579f5SStefano Zampini } 11109c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 1111da1bb401SStefano Zampini pcbddc->ISForDofs[i] = ISForDofs[i]; 11129c0446d6SStefano Zampini } 11139c0446d6SStefano Zampini pcbddc->n_ISForDofs = n_is; 111463602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 111556282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 11169c0446d6SStefano Zampini PetscFunctionReturn(0); 11179c0446d6SStefano Zampini } 11181e6b0712SBarry Smith 11199c0446d6SStefano Zampini #undef __FUNCT__ 11209c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 11219c0446d6SStefano Zampini /*@ 112263602bcaSStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of the global matrix 11239c0446d6SStefano Zampini 112463602bcaSStefano Zampini Collective 11259c0446d6SStefano Zampini 11269c0446d6SStefano Zampini Input Parameters: 11279c0446d6SStefano Zampini + pc - the preconditioning context 11280f202f7eSStefano Zampini . n_is - number of index sets defining the fields 11290f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in global ordering 11309c0446d6SStefano Zampini 11319c0446d6SStefano Zampini Level: intermediate 11329c0446d6SStefano Zampini 11330f202f7eSStefano Zampini Notes: 11340f202f7eSStefano Zampini Any process can list any global node. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 11359c0446d6SStefano Zampini 11369c0446d6SStefano Zampini .seealso: PCBDDC 11379c0446d6SStefano Zampini @*/ 11389c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 11399c0446d6SStefano Zampini { 11402b510759SStefano Zampini PetscInt i; 11419c0446d6SStefano Zampini PetscErrorCode ierr; 11429c0446d6SStefano Zampini 11439c0446d6SStefano Zampini PetscFunctionBegin; 11449c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 114563602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 11462b510759SStefano Zampini for (i=0;i<n_is;i++) { 114763602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 114863602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 11492b510759SStefano Zampini } 11509c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 11519c0446d6SStefano Zampini PetscFunctionReturn(0); 11529c0446d6SStefano Zampini } 1153906d46d4SStefano Zampini 1154da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 1155534831adSStefano Zampini #undef __FUNCT__ 1156534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC" 1157534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 1158534831adSStefano Zampini /* 1159534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 1160534831adSStefano Zampini guess if a transformation of basis approach has been selected. 11619c0446d6SStefano Zampini 1162534831adSStefano Zampini Input Parameter: 1163534831adSStefano Zampini + pc - the preconditioner contex 1164534831adSStefano Zampini 1165534831adSStefano Zampini Application Interface Routine: PCPreSolve() 1166534831adSStefano Zampini 1167534831adSStefano Zampini Notes: 1168534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 1169534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1170534831adSStefano Zampini */ 1171534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1172534831adSStefano Zampini { 1173534831adSStefano Zampini PetscErrorCode ierr; 1174534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1175534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 11763972b0daSStefano Zampini Vec used_vec; 117727b6a85dSStefano Zampini PetscBool save_rhs = PETSC_TRUE, benign_correction_computed; 1178534831adSStefano Zampini 1179534831adSStefano Zampini PetscFunctionBegin; 118027b6a85dSStefano Zampini /* if we are working with CG or CHEBYSHEV, one dirichlet solve can be avoided during Krylov iterations */ 118185c4d303SStefano Zampini if (ksp) { 1182*f94e96cbSStefano Zampini PetscBool iscg, ischeby, isgroppcg, ispipecg, ispipecgrr; 118385c4d303SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr); 118427b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPGROPPCG,&isgroppcg);CHKERRQ(ierr); 118527b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECG,&ispipecg);CHKERRQ(ierr); 1186*f94e96cbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPIPECGRR,&ispipecgrr);CHKERRQ(ierr); 118727b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCHEBYSHEV,&ischeby);CHKERRQ(ierr); 1188*f94e96cbSStefano Zampini if (pcbddc->switch_static || (!iscg && !ischeby && !isgroppcg && !ispipecg && !ispipecgrr)) { 118985c4d303SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 119085c4d303SStefano Zampini } 119185c4d303SStefano Zampini } 119285c4d303SStefano Zampini /* Creates parallel work vectors used in presolve */ 119362a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 119462a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 119562a6ff1dSStefano Zampini } 119662a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 119762a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 119862a6ff1dSStefano Zampini } 11998d00608fSStefano Zampini 120027b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_FALSE; 12013972b0daSStefano Zampini if (x) { 12023972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 12033972b0daSStefano Zampini used_vec = x; 12048d00608fSStefano Zampini } else { /* it can only happen when calling PCBDDCMatFETIDPGetRHS */ 12053972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 12063972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 12073972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 120827b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 12093972b0daSStefano Zampini } 12108efcfb23SStefano Zampini 12118efcfb23SStefano Zampini /* hack into ksp data structure since PCPreSolve comes earlier than setting to zero the guess in src/ksp/ksp/interface/itfunc.c */ 12123972b0daSStefano Zampini if (ksp) { 1213a0cb1b98SStefano Zampini /* store the flag for the initial guess since it will be restored back during PCPostSolve_BDDC */ 12148efcfb23SStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 12158efcfb23SStefano Zampini if (!pcbddc->ksp_guess_nonzero) { 12163972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 12173972b0daSStefano Zampini } 12183972b0daSStefano Zampini } 12193308cffdSStefano Zampini 12208d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 12213972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 122270c64980SStefano Zampini if (rhs && pcbddc->eliminate_dirdofs) { 12233975b054SStefano Zampini IS dirIS = NULL; 12243975b054SStefano Zampini 1225a07ea27aSStefano Zampini /* DirichletBoundariesLocal may not be consistent among neighbours; gets a dirichlet dofs IS from graph (may be cached) */ 12263975b054SStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 12273975b054SStefano Zampini if (dirIS) { 1228906d46d4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1229785d1243SStefano Zampini PetscInt dirsize,i,*is_indices; 12302b095fd8SStefano Zampini PetscScalar *array_x; 12312b095fd8SStefano Zampini const PetscScalar *array_diagonal; 1232785d1243SStefano Zampini 12333972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 12343972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 1235e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1236e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1237e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1238e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 123982ba6b80SStefano Zampini ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr); 12403972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 12412b095fd8SStefano Zampini ierr = VecGetArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 12423972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 12432fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 12443972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 12452b095fd8SStefano Zampini ierr = VecRestoreArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 12463972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 1247e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1248e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 12498d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 12501b968477SStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 12518efcfb23SStefano Zampini } 1252a07ea27aSStefano Zampini } 1253b76ba322SStefano Zampini 12548efcfb23SStefano Zampini /* remove the computed solution or the initial guess from the rhs */ 12558d00608fSStefano Zampini if (pcbddc->rhs_change || (ksp && pcbddc->ksp_guess_nonzero) ) { 125627b6a85dSStefano Zampini /* save the original rhs */ 125727b6a85dSStefano Zampini if (save_rhs) { 125827b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 125927b6a85dSStefano Zampini save_rhs = PETSC_FALSE; 12608d00608fSStefano Zampini } 12618d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 12623972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 126327b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,used_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 12643972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 12658efcfb23SStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 126627b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_TRUE; 12677acc28cbSStefano Zampini if (ksp) { 12687acc28cbSStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_FALSE);CHKERRQ(ierr); 12697acc28cbSStefano Zampini } 12703308cffdSStefano Zampini } 12718efcfb23SStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 1272b76ba322SStefano Zampini 127327b6a85dSStefano Zampini /* compute initial vector in benign space if needed (TODO: FETI-DP is untested) 127427b6a85dSStefano Zampini and remove non-benign solution from the rhs */ 127527b6a85dSStefano Zampini benign_correction_computed = PETSC_FALSE; 127627b6a85dSStefano Zampini if (rhs && pcbddc->benign_compute_correction && pcbddc->benign_have_null) { 12770369aaf7SStefano Zampini /* compute u^*_h as in Xuemin Tu's thesis (see Section 4.8.1) */ 12780369aaf7SStefano Zampini if (!pcbddc->benign_vec) { 12790369aaf7SStefano Zampini ierr = VecDuplicate(rhs,&pcbddc->benign_vec);CHKERRQ(ierr); 12800369aaf7SStefano Zampini } 12814fee134fSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_TRUE; 128227b6a85dSStefano Zampini if (!pcbddc->benign_skip_correction) { 12831dd7afcfSStefano Zampini ierr = PCApply_BDDC(pc,rhs,pcbddc->benign_vec);CHKERRQ(ierr); 128427b6a85dSStefano Zampini /* store the original rhs if not done earlier */ 128527b6a85dSStefano Zampini if (save_rhs) { 128627b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 128727b6a85dSStefano Zampini save_rhs = PETSC_FALSE; 128892e3dcfbSStefano Zampini } 128927b6a85dSStefano Zampini benign_correction_computed = PETSC_TRUE; 129027b6a85dSStefano Zampini if (pcbddc->temp_solution_used) { 129127b6a85dSStefano Zampini ierr = VecAXPY(pcbddc->temp_solution,1.0,pcbddc->benign_vec);CHKERRQ(ierr); 12920369aaf7SStefano Zampini } 12930369aaf7SStefano Zampini ierr = VecScale(pcbddc->benign_vec,-1.0);CHKERRQ(ierr); 129427b6a85dSStefano Zampini if (pcbddc->rhs_change) { 12950369aaf7SStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,rhs,rhs);CHKERRQ(ierr); 129627b6a85dSStefano Zampini } else { 129727b6a85dSStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,pcbddc->original_rhs,rhs);CHKERRQ(ierr); 129827b6a85dSStefano Zampini } 12990369aaf7SStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 130027b6a85dSStefano Zampini } 130127b6a85dSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_FALSE; 13020369aaf7SStefano Zampini } 13030369aaf7SStefano Zampini 13040369aaf7SStefano Zampini /* set initial guess if using PCG */ 13050369aaf7SStefano Zampini if (x && pcbddc->use_exact_dirichlet_trick) { 13060369aaf7SStefano Zampini ierr = VecSet(x,0.0);CHKERRQ(ierr); 13071dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 130827b6a85dSStefano Zampini if (benign_correction_computed) { /* we have already saved the changed rhs */ 13091dd7afcfSStefano Zampini ierr = VecLockPop(pcis->vec1_global);CHKERRQ(ierr); 13101dd7afcfSStefano Zampini } else { 13111dd7afcfSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,pcis->vec1_global);CHKERRQ(ierr); 13121dd7afcfSStefano Zampini } 13131dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13141dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13151dd7afcfSStefano Zampini } else { 13160369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13170369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13181dd7afcfSStefano Zampini } 13190369aaf7SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 13201dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 13211dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.);CHKERRQ(ierr); 13221dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13231dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13241dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x);CHKERRQ(ierr); 13251dd7afcfSStefano Zampini } else { 13260369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13270369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13281dd7afcfSStefano Zampini } 13290369aaf7SStefano Zampini if (ksp) { 13300369aaf7SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 13310369aaf7SStefano Zampini } 13320369aaf7SStefano Zampini } 1333534831adSStefano Zampini PetscFunctionReturn(0); 1334534831adSStefano Zampini } 1335906d46d4SStefano Zampini 1336534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 1337534831adSStefano Zampini #undef __FUNCT__ 1338534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC" 1339534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 1340534831adSStefano Zampini /* 1341534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 1342534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 1343534831adSStefano Zampini 1344534831adSStefano Zampini Input Parameter: 1345534831adSStefano Zampini + pc - the preconditioner contex 1346534831adSStefano Zampini 1347534831adSStefano Zampini Application Interface Routine: PCPostSolve() 1348534831adSStefano Zampini 1349534831adSStefano Zampini Notes: 1350534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 1351534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1352534831adSStefano Zampini */ 1353534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1354534831adSStefano Zampini { 1355534831adSStefano Zampini PetscErrorCode ierr; 1356534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1357534831adSStefano Zampini 1358534831adSStefano Zampini PetscFunctionBegin; 13593972b0daSStefano Zampini /* add solution removed in presolve */ 13606bcfc461SStefano Zampini if (x && pcbddc->rhs_change) { 136127b6a85dSStefano Zampini if (pcbddc->temp_solution_used) { 13623425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 136327b6a85dSStefano Zampini } else if (pcbddc->benign_compute_correction) { 136427b6a85dSStefano Zampini ierr = VecAXPY(x,-1.0,pcbddc->benign_vec);CHKERRQ(ierr); 13653425bc38SStefano Zampini } 136627b6a85dSStefano Zampini } 136727b6a85dSStefano Zampini pcbddc->temp_solution_used = PETSC_FALSE; 136827b6a85dSStefano Zampini 1369fb223d50SStefano Zampini /* restore rhs to its original state */ 13708d00608fSStefano Zampini if (rhs && pcbddc->rhs_change) { 137127b6a85dSStefano Zampini ierr = VecSwap(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 1372fb223d50SStefano Zampini } 13738d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 13748efcfb23SStefano Zampini /* restore ksp guess state */ 13758efcfb23SStefano Zampini if (ksp) { 13768efcfb23SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 13778efcfb23SStefano Zampini } 1378534831adSStefano Zampini PetscFunctionReturn(0); 1379534831adSStefano Zampini } 1380534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 138153cdbc3dSStefano Zampini #undef __FUNCT__ 138253cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 13830c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 13840c7d97c5SJed Brown /* 13850c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 13860c7d97c5SJed Brown by setting data structures and options. 13870c7d97c5SJed Brown 13880c7d97c5SJed Brown Input Parameter: 138953cdbc3dSStefano Zampini + pc - the preconditioner context 13900c7d97c5SJed Brown 13910c7d97c5SJed Brown Application Interface Routine: PCSetUp() 13920c7d97c5SJed Brown 13930c7d97c5SJed Brown Notes: 13940c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 13950c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 13960c7d97c5SJed Brown */ 139753cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 13980c7d97c5SJed Brown { 13990c7d97c5SJed Brown PetscErrorCode ierr; 14000c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 14015e8657edSStefano Zampini Mat_IS* matis; 140208122e43SStefano Zampini MatNullSpace nearnullspace; 1403c9ed8603SStefano Zampini IS zerodiag = NULL; 140491e8d312SStefano Zampini PetscInt nrows,ncols; 140508122e43SStefano Zampini PetscBool computetopography,computesolvers,computesubschurs; 14068de1fae6SStefano Zampini PetscBool computeconstraintsmatrix; 14075e8657edSStefano Zampini PetscBool new_nearnullspace_provided,ismatis; 14080c7d97c5SJed Brown 14090c7d97c5SJed Brown PetscFunctionBegin; 14105e8657edSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATIS,&ismatis);CHKERRQ(ierr); 14116c4ed002SBarry Smith if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner requires matrix of type MATIS"); 141291e8d312SStefano Zampini ierr = MatGetSize(pc->pmat,&nrows,&ncols);CHKERRQ(ierr); 14136c4ed002SBarry Smith if (nrows != ncols) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PCBDDC preconditioner requires a square preconditioning matrix"); 14145e8657edSStefano Zampini matis = (Mat_IS*)pc->pmat->data; 1415f4ddd8eeSStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other future nonoverlapping preconditioners */ 14163b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 1417fcd409f5SStefano Zampini Also, BDDC directly build the Dirichlet problem */ 1418f4ddd8eeSStefano Zampini /* split work */ 1419674ae819SStefano Zampini if (pc->setupcalled) { 1420d1e9a80fSBarry Smith if (pc->flag == SAME_NONZERO_PATTERN) { 1421674ae819SStefano Zampini computetopography = PETSC_FALSE; 1422674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1423674ae819SStefano Zampini } else { /* DIFFERENT_NONZERO_PATTERN */ 1424674ae819SStefano Zampini computetopography = PETSC_TRUE; 1425674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1426674ae819SStefano Zampini } 1427674ae819SStefano Zampini } else { 1428674ae819SStefano Zampini computetopography = PETSC_TRUE; 1429674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1430674ae819SStefano Zampini } 1431fb180af4SStefano Zampini if (pcbddc->recompute_topography) { 1432fb180af4SStefano Zampini computetopography = PETSC_TRUE; 1433fb180af4SStefano Zampini } 143456282151SStefano Zampini pcbddc->recompute_topography = computetopography; 14358de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_FALSE; 1436b087196eSStefano Zampini 1437b087196eSStefano Zampini /* check parameters' compatibility */ 1438b7ab4a40SStefano Zampini if (!pcbddc->use_deluxe_scaling) pcbddc->deluxe_zerorows = PETSC_FALSE; 14399d54b7f4SStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_threshold > 0.0); 1440bf3a8328SStefano Zampini pcbddc->adaptive_userdefined = (PetscBool)(pcbddc->adaptive_selection && pcbddc->adaptive_userdefined); 1441862806e4SStefano Zampini if (pcbddc->adaptive_selection) pcbddc->use_faces = PETSC_TRUE; 1442862806e4SStefano Zampini 14435a95e1ceSStefano Zampini computesubschurs = (PetscBool)(pcbddc->adaptive_selection || pcbddc->use_deluxe_scaling); 144416909a7fSStefano Zampini if (pcbddc->switch_static) { 144516909a7fSStefano Zampini PetscBool ismatis; 144616909a7fSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->mat,MATIS,&ismatis);CHKERRQ(ierr); 144716909a7fSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"When the static switch is one, the iteration matrix should be of type MATIS"); 144816909a7fSStefano Zampini } 144916909a7fSStefano Zampini 1450f4ddd8eeSStefano Zampini /* Get stdout for dbg */ 145170cf5478SStefano Zampini if (pcbddc->dbg_flag) { 145270cf5478SStefano Zampini if (!pcbddc->dbg_viewer) { 145358a03d70SStefano Zampini pcbddc->dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pc)); 14541575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 1455f4ddd8eeSStefano Zampini } 145658a03d70SStefano Zampini ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1457f4ddd8eeSStefano Zampini } 1458f4ddd8eeSStefano Zampini 14595e8657edSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 14605e8657edSStefano Zampini /* use_change_of_basis flag is used to automatically compute a change of basis from constraints */ 14615e8657edSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 14625e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 14635e8657edSStefano Zampini } else { 1464b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 14655e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 14665e8657edSStefano Zampini pcbddc->local_mat = matis->A; 1467d16cbb6bSStefano Zampini } 1468d16cbb6bSStefano Zampini 14694f1b2e48SStefano Zampini /* detect local disconnected subdomains if requested and not done before */ 14704f1b2e48SStefano Zampini if (pcbddc->detect_disconnected && !pcbddc->n_local_subs) { 14714f1b2e48SStefano Zampini ierr = MatDetectDisconnectedComponents(pcbddc->local_mat,PETSC_FALSE,&pcbddc->n_local_subs,&pcbddc->local_subs);CHKERRQ(ierr); 14724f1b2e48SStefano Zampini } 14734f1b2e48SStefano Zampini 14744f1b2e48SStefano Zampini /* 14751dd7afcfSStefano Zampini Compute change of basis on local pressures (aka zerodiag dofs) 14764f1b2e48SStefano Zampini This should come earlier then PCISSetUp for extracting the correct subdomain matrices 14774f1b2e48SStefano Zampini */ 14781dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 1479d16cbb6bSStefano Zampini if (pcbddc->benign_saddle_point) { 14809f47a83aSStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 14819f47a83aSStefano Zampini 148205b28244SStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->use_change_of_basis || !computesubschurs) pcbddc->benign_change_explicit = PETSC_TRUE; 1483339f8db1SStefano Zampini /* detect local saddle point and change the basis in pcbddc->local_mat */ 1484339f8db1SStefano Zampini ierr = PCBDDCBenignDetectSaddlePoint(pc,&zerodiag);CHKERRQ(ierr); 1485a3df083aSStefano Zampini /* pop B0 mat from local mat */ 1486c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 14871dd7afcfSStefano Zampini /* give pcis a hint to not reuse submatrices during PCISCreate */ 14881dd7afcfSStefano Zampini if (pc->flag == SAME_NONZERO_PATTERN && pcis->reusesubmatrices == PETSC_TRUE) { 14891dd7afcfSStefano Zampini if (pcbddc->benign_n && (pcbddc->benign_change_explicit || pcbddc->dbg_flag)) { 14901dd7afcfSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 14911dd7afcfSStefano Zampini } else { 1492a3df083aSStefano Zampini pcis->reusesubmatrices = PETSC_TRUE; 14931dd7afcfSStefano Zampini } 1494a3df083aSStefano Zampini } else { 14959f47a83aSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 1496674ae819SStefano Zampini } 1497a3df083aSStefano Zampini } 149827b6a85dSStefano Zampini 1499f1a72664SStefano Zampini /* propagate relevant information */ 15004f1b2e48SStefano Zampini #if !defined(PETSC_USE_COMPLEX) /* workaround for reals */ 15013301b35fSStefano Zampini if (matis->A->symmetric_set) { 15023301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 15033301b35fSStefano Zampini } 1504e496cd5dSStefano Zampini #endif 150506a4e24aSStefano Zampini if (matis->A->symmetric_set) { 150606a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 150706a4e24aSStefano Zampini } 150806a4e24aSStefano Zampini if (matis->A->spd_set) { 150906a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SPD,matis->A->spd);CHKERRQ(ierr); 151006a4e24aSStefano Zampini } 1511e496cd5dSStefano Zampini 15125e8657edSStefano Zampini /* Set up all the "iterative substructuring" common block without computing solvers */ 15135e8657edSStefano Zampini { 15145e8657edSStefano Zampini Mat temp_mat; 15155e8657edSStefano Zampini 15165e8657edSStefano Zampini temp_mat = matis->A; 15175e8657edSStefano Zampini matis->A = pcbddc->local_mat; 15185e8657edSStefano Zampini ierr = PCISSetUp(pc,PETSC_FALSE);CHKERRQ(ierr); 15195e8657edSStefano Zampini pcbddc->local_mat = matis->A; 15205e8657edSStefano Zampini matis->A = temp_mat; 15215e8657edSStefano Zampini } 1522684f6988SStefano Zampini 152381d14e9dSStefano Zampini /* Analyze interface */ 1524674ae819SStefano Zampini if (computetopography) { 1525674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 15268de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1527674ae819SStefano Zampini } 1528fb8d54d4SStefano Zampini 15295408967cSStefano Zampini /* check existence of a divergence free extension, i.e. 15305408967cSStefano Zampini b(v_I,p_0) = 0 for all v_I (raise error if not). 15315408967cSStefano Zampini Also, check that PCBDDCBenignGetOrSetP0 works */ 15325408967cSStefano Zampini #if defined(PETSC_USE_DEBUG) 153309f581a4SStefano Zampini if (pcbddc->benign_saddle_point) { 15345408967cSStefano Zampini ierr = PCBDDCBenignCheck(pc,zerodiag);CHKERRQ(ierr); 153509f581a4SStefano Zampini } 15365408967cSStefano Zampini #endif 15374f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 153806f24817SStefano Zampini 1539b96c3477SStefano Zampini /* Setup local dirichlet solver ksp_D and sub_schurs solvers */ 1540684f6988SStefano Zampini if (computesolvers) { 1541d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 1542d5574798SStefano Zampini 1543d5574798SStefano Zampini if (computesubschurs && computetopography) { 154408122e43SStefano Zampini ierr = PCBDDCInitSubSchurs(pc);CHKERRQ(ierr); 1545b1b3d7a2SStefano Zampini } 15469d54b7f4SStefano Zampini /* SetUp Scaling operator (scaling matrices could be needed in SubSchursSetUp)*/ 15479d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) { 15489d54b7f4SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 15499d54b7f4SStefano Zampini } 1550df4d28bfSStefano Zampini if (sub_schurs->schur_explicit) { 15512070dbb6SStefano Zampini if (computesubschurs) { 155208122e43SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 15532070dbb6SStefano Zampini } 1554d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 1555d5574798SStefano Zampini } else { 1556d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 15572070dbb6SStefano Zampini if (computesubschurs) { 1558d5574798SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 1559d5574798SStefano Zampini } 15602070dbb6SStefano Zampini } 156108122e43SStefano Zampini if (pcbddc->adaptive_selection) { 156208122e43SStefano Zampini ierr = PCBDDCAdaptiveSelection(pc);CHKERRQ(ierr); 15638de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1564b7eb3628SStefano Zampini } 1565b1b3d7a2SStefano Zampini } 1566684f6988SStefano Zampini 1567f4ddd8eeSStefano Zampini /* infer if NullSpace object attached to Mat via MatSetNearNullSpace has changed */ 1568fb8d54d4SStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1569f4ddd8eeSStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullspace);CHKERRQ(ierr); 1570f4ddd8eeSStefano Zampini if (pcbddc->onearnullspace) { /* already used nearnullspace */ 1571f4ddd8eeSStefano Zampini if (!nearnullspace) { /* near null space attached to mat has been destroyed */ 1572f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1573f4ddd8eeSStefano Zampini } else { 1574f4ddd8eeSStefano Zampini /* determine if the two nullspaces are different (should be lightweight) */ 1575f4ddd8eeSStefano Zampini if (nearnullspace != pcbddc->onearnullspace) { 1576f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1577165b64e2SStefano Zampini } else { /* maybe the user has changed the content of the nearnullspace so check vectors ObjectStateId */ 1578f4ddd8eeSStefano Zampini PetscInt i; 1579165b64e2SStefano Zampini const Vec *nearnullvecs; 1580165b64e2SStefano Zampini PetscObjectState state; 1581165b64e2SStefano Zampini PetscInt nnsp_size; 1582165b64e2SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullspace,NULL,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1583f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1584f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&state);CHKERRQ(ierr); 1585165b64e2SStefano Zampini if (pcbddc->onearnullvecs_state[i] != state) { 1586f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1587f4ddd8eeSStefano Zampini break; 1588f4ddd8eeSStefano Zampini } 1589f4ddd8eeSStefano Zampini } 1590f4ddd8eeSStefano Zampini } 1591f4ddd8eeSStefano Zampini } 1592f4ddd8eeSStefano Zampini } else { 1593f4ddd8eeSStefano Zampini if (!nearnullspace) { /* both nearnullspaces are null */ 1594f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1595f4ddd8eeSStefano Zampini } else { /* nearnullspace attached later */ 1596f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1597f4ddd8eeSStefano Zampini } 1598f4ddd8eeSStefano Zampini } 1599f4ddd8eeSStefano Zampini 1600f4ddd8eeSStefano Zampini /* Setup constraints and related work vectors */ 1601727cdba6SStefano Zampini /* reset primal space flags */ 1602f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 1603727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 16048de1fae6SStefano Zampini if (computeconstraintsmatrix || new_nearnullspace_provided) { 1605727cdba6SStefano Zampini /* It also sets the primal space flags */ 1606674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 1607e7b262bdSStefano Zampini /* Allocate needed local vectors (which depends on quantities defined during ConstraintsSetUp) */ 1608f4ddd8eeSStefano Zampini ierr = PCBDDCSetUpLocalWorkVectors(pc);CHKERRQ(ierr); 16093975b054SStefano Zampini } 16105e8657edSStefano Zampini 16113975b054SStefano Zampini if (computesolvers || pcbddc->new_primal_space) { 16125e8657edSStefano Zampini if (pcbddc->use_change_of_basis) { 16135e8657edSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 16145e8657edSStefano Zampini 16155e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 16164f1b2e48SStefano Zampini if (pcbddc->benign_change) { 16171dd7afcfSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 1618c263805aSStefano Zampini /* pop B0 from pcbddc->local_mat */ 1619c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 1620c263805aSStefano Zampini } 16215e8657edSStefano Zampini /* get submatrices */ 16225e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 16235e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 16245e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 16255e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 16265e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 16275e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 16283975b054SStefano Zampini /* set flag in pcis to not reuse submatrices during PCISCreate */ 16293975b054SStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 16309c6a02ceSStefano Zampini } else if (!pcbddc->user_ChangeOfBasisMatrix && !pcbddc->benign_change) { 1631b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 16325e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 16335e8657edSStefano Zampini pcbddc->local_mat = matis->A; 16345e8657edSStefano Zampini } 1635b96c3477SStefano Zampini /* SetUp coarse and local Neumann solvers */ 163699cc7994SStefano Zampini ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr); 1637b96c3477SStefano Zampini /* SetUp Scaling operator */ 16389d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1639674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 16400c7d97c5SJed Brown } 16419d54b7f4SStefano Zampini } 16421dd7afcfSStefano Zampini /* mark topography as done */ 164356282151SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 16440369aaf7SStefano Zampini 16451dd7afcfSStefano Zampini /* wrap pcis->A_IB and pcis->A_BI if we did not change explicitly the variables on the pressures */ 16461dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_FALSE);CHKERRQ(ierr); 16471dd7afcfSStefano Zampini 164858a03d70SStefano Zampini if (pcbddc->dbg_flag) { 164958a03d70SStefano Zampini ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 16502b510759SStefano Zampini } 16510c7d97c5SJed Brown PetscFunctionReturn(0); 16520c7d97c5SJed Brown } 16530c7d97c5SJed Brown 16540c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 16550c7d97c5SJed Brown /* 165650efa1b5SStefano Zampini PCApply_BDDC - Applies the BDDC operator to a vector. 16570c7d97c5SJed Brown 16580c7d97c5SJed Brown Input Parameters: 16590f202f7eSStefano Zampini + pc - the preconditioner context 16600f202f7eSStefano Zampini - r - input vector (global) 16610c7d97c5SJed Brown 16620c7d97c5SJed Brown Output Parameter: 16630c7d97c5SJed Brown . z - output vector (global) 16640c7d97c5SJed Brown 16650c7d97c5SJed Brown Application Interface Routine: PCApply() 16660c7d97c5SJed Brown */ 16670c7d97c5SJed Brown #undef __FUNCT__ 16680c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 166953cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 16700c7d97c5SJed Brown { 16710c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 16720c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1673b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 16740c7d97c5SJed Brown PetscErrorCode ierr; 16753b03a366Sstefano_zampini const PetscScalar one = 1.0; 16763b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 16772617d88aSStefano Zampini const PetscScalar zero = 0.0; 16780c7d97c5SJed Brown 16790c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 16800c7d97c5SJed Brown NN interface preconditioner changed to BDDC 1681b097fa66SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static == PETSC_TRUE) */ 16820c7d97c5SJed Brown 16830c7d97c5SJed Brown PetscFunctionBegin; 16841dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 16851dd7afcfSStefano Zampini Vec swap; 168627b6a85dSStefano Zampini 168727b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 16881dd7afcfSStefano Zampini swap = pcbddc->work_change; 16891dd7afcfSStefano Zampini pcbddc->work_change = r; 16901dd7afcfSStefano Zampini r = swap; 16911dd7afcfSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 16921dd7afcfSStefano Zampini if (pcbddc->benign_apply_coarse_only && pcbddc->use_exact_dirichlet_trick && pcbddc->change_interior) { 16931dd7afcfSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 16941dd7afcfSStefano Zampini ierr = VecLockPush(pcis->vec1_global);CHKERRQ(ierr); 16951dd7afcfSStefano Zampini } 16961dd7afcfSStefano Zampini } 169727b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 1698015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1699efc2fbd9SStefano Zampini } 170027b6a85dSStefano Zampini if (!pcbddc->use_exact_dirichlet_trick && !pcbddc->benign_apply_coarse_only) { 1701b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 17020c7d97c5SJed Brown /* First Dirichlet solve */ 17030c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17040c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17050c7d97c5SJed Brown /* 17060c7d97c5SJed Brown Assembling right hand side for BDDC operator 1707b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 1708674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 17090c7d97c5SJed Brown */ 1710b097fa66SStefano Zampini if (n_D) { 1711b097fa66SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 17120c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 171316909a7fSStefano Zampini if (pcbddc->switch_static) { 171416909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 171516909a7fSStefano Zampini 171616909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 171716909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 171816909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 171916909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 172016909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 172116909a7fSStefano Zampini } else { 172216909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 172316909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 172416909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 172516909a7fSStefano Zampini } 172616909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 172716909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 172816909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 172916909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 173016909a7fSStefano Zampini } else { 1731b097fa66SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 173216909a7fSStefano Zampini } 1733b097fa66SStefano Zampini } else { 1734b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1735b097fa66SStefano Zampini } 17360c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 17370c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1738674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 1739b76ba322SStefano Zampini } else { 17404fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 1741674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 1742b76ba322SStefano Zampini } 17434fee134fSStefano Zampini } 1744b76ba322SStefano Zampini 17452617d88aSStefano Zampini /* Apply interface preconditioner 17462617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1747dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 17482617d88aSStefano Zampini 1749674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 1750674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 17510c7d97c5SJed Brown 17523b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 17530c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17540c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1755b097fa66SStefano Zampini if (n_B) { 175616909a7fSStefano Zampini if (pcbddc->switch_static) { 175716909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 175816909a7fSStefano Zampini 175916909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 176016909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 176116909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 176216909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 176316909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 176416909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 176516909a7fSStefano Zampini } else { 176616909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 176716909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 176816909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 176916909a7fSStefano Zampini } 177016909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 177116909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 177216909a7fSStefano Zampini } else { 17730c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 177416909a7fSStefano Zampini } 177516909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 177616909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 177716909a7fSStefano Zampini 177816909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 177916909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 178016909a7fSStefano Zampini } else { 178116909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 178216909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 178316909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 178416909a7fSStefano Zampini } 1785b097fa66SStefano Zampini } 1786df187020SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 1787efc2fbd9SStefano Zampini 178827b6a85dSStefano Zampini if (!pcbddc->use_exact_dirichlet_trick && !pcbddc->benign_apply_coarse_only) { 1789b097fa66SStefano Zampini if (pcbddc->switch_static) { 1790b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 1791b097fa66SStefano Zampini } else { 1792b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 1793b097fa66SStefano Zampini } 17940c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 17950c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1796b097fa66SStefano Zampini } else { 1797b097fa66SStefano Zampini if (pcbddc->switch_static) { 1798b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 1799b097fa66SStefano Zampini } else { 1800b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 1801b097fa66SStefano Zampini } 1802b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1803b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1804b097fa66SStefano Zampini } 1805efc2fbd9SStefano Zampini 180627b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 18071dd7afcfSStefano Zampini if (pcbddc->benign_apply_coarse_only) { 18081dd7afcfSStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 18091dd7afcfSStefano Zampini } 1810015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 1811efc2fbd9SStefano Zampini } 18121dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 18131dd7afcfSStefano Zampini Vec swap; 18141dd7afcfSStefano Zampini 18151dd7afcfSStefano Zampini swap = r; 18161dd7afcfSStefano Zampini r = pcbddc->work_change; 18171dd7afcfSStefano Zampini pcbddc->work_change = swap; 18181dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 18191dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 18201dd7afcfSStefano Zampini } 18210c7d97c5SJed Brown PetscFunctionReturn(0); 18220c7d97c5SJed Brown } 182350efa1b5SStefano Zampini 182450efa1b5SStefano Zampini /* -------------------------------------------------------------------------- */ 182550efa1b5SStefano Zampini /* 182650efa1b5SStefano Zampini PCApplyTranspose_BDDC - Applies the transpose of the BDDC operator to a vector. 182750efa1b5SStefano Zampini 182850efa1b5SStefano Zampini Input Parameters: 18290f202f7eSStefano Zampini + pc - the preconditioner context 18300f202f7eSStefano Zampini - r - input vector (global) 183150efa1b5SStefano Zampini 183250efa1b5SStefano Zampini Output Parameter: 183350efa1b5SStefano Zampini . z - output vector (global) 183450efa1b5SStefano Zampini 183550efa1b5SStefano Zampini Application Interface Routine: PCApplyTranspose() 183650efa1b5SStefano Zampini */ 183750efa1b5SStefano Zampini #undef __FUNCT__ 183850efa1b5SStefano Zampini #define __FUNCT__ "PCApplyTranspose_BDDC" 183950efa1b5SStefano Zampini PetscErrorCode PCApplyTranspose_BDDC(PC pc,Vec r,Vec z) 184050efa1b5SStefano Zampini { 184150efa1b5SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 184250efa1b5SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1843b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 184450efa1b5SStefano Zampini PetscErrorCode ierr; 184550efa1b5SStefano Zampini const PetscScalar one = 1.0; 184650efa1b5SStefano Zampini const PetscScalar m_one = -1.0; 184750efa1b5SStefano Zampini const PetscScalar zero = 0.0; 184850efa1b5SStefano Zampini 184950efa1b5SStefano Zampini PetscFunctionBegin; 18501dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 18511dd7afcfSStefano Zampini Vec swap; 185227b6a85dSStefano Zampini 185327b6a85dSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 18541dd7afcfSStefano Zampini swap = pcbddc->work_change; 18551dd7afcfSStefano Zampini pcbddc->work_change = r; 18561dd7afcfSStefano Zampini r = swap; 185727b6a85dSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 185827b6a85dSStefano Zampini if (pcbddc->benign_apply_coarse_only && pcbddc->use_exact_dirichlet_trick && pcbddc->change_interior) { 185927b6a85dSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 186027b6a85dSStefano Zampini ierr = VecLockPush(pcis->vec1_global);CHKERRQ(ierr); 18611dd7afcfSStefano Zampini } 186227b6a85dSStefano Zampini } 186327b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* get p0 from r */ 1864537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1865537c1cdfSStefano Zampini } 186627b6a85dSStefano Zampini if (!pcbddc->use_exact_dirichlet_trick && !pcbddc->benign_apply_coarse_only) { 1867b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 186850efa1b5SStefano Zampini /* First Dirichlet solve */ 186950efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 187050efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 187150efa1b5SStefano Zampini /* 187250efa1b5SStefano Zampini Assembling right hand side for BDDC operator 1873b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 187450efa1b5SStefano Zampini - pcis->vec1_B the interface part of the global vector z 187550efa1b5SStefano Zampini */ 1876b097fa66SStefano Zampini if (n_D) { 1877b097fa66SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 187850efa1b5SStefano Zampini ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 187916909a7fSStefano Zampini if (pcbddc->switch_static) { 188016909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 188116909a7fSStefano Zampini 188216909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 188316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 188416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 188516909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 188616909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 188716909a7fSStefano Zampini } else { 188816909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 188916909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 189016909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 189116909a7fSStefano Zampini } 189216909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 189316909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 189416909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 189516909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 189616909a7fSStefano Zampini } else { 1897b097fa66SStefano Zampini ierr = MatMultTranspose(pcis->A_IB,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 189816909a7fSStefano Zampini } 1899b097fa66SStefano Zampini } else { 1900b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1901b097fa66SStefano Zampini } 190250efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 190350efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 190450efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 190550efa1b5SStefano Zampini } else { 190650efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 190750efa1b5SStefano Zampini } 190850efa1b5SStefano Zampini 190950efa1b5SStefano Zampini /* Apply interface preconditioner 191050efa1b5SStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1911dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_TRUE);CHKERRQ(ierr); 191250efa1b5SStefano Zampini 191350efa1b5SStefano Zampini /* Apply transpose of partition of unity operator */ 191450efa1b5SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 191550efa1b5SStefano Zampini 191650efa1b5SStefano Zampini /* Second Dirichlet solve and assembling of output */ 191750efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 191850efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1919b097fa66SStefano Zampini if (n_B) { 192016909a7fSStefano Zampini if (pcbddc->switch_static) { 192116909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 192216909a7fSStefano Zampini 192316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 192416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 192516909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 192616909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 192716909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 192816909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 192916909a7fSStefano Zampini } else { 193016909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 193116909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 193216909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 193316909a7fSStefano Zampini } 193416909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 193516909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 193616909a7fSStefano Zampini } else { 193750efa1b5SStefano Zampini ierr = MatMultTranspose(pcis->A_BI,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 193816909a7fSStefano Zampini } 193916909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 194016909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 194116909a7fSStefano Zampini 194216909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 194316909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 194416909a7fSStefano Zampini } else { 194516909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 194616909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 194716909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 194816909a7fSStefano Zampini } 1949b097fa66SStefano Zampini } 1950b0147a47SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 195127b6a85dSStefano Zampini if (!pcbddc->use_exact_dirichlet_trick && !pcbddc->benign_apply_coarse_only) { 1952b097fa66SStefano Zampini if (pcbddc->switch_static) { 1953b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 1954b097fa66SStefano Zampini } else { 1955b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 1956b097fa66SStefano Zampini } 195750efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 195850efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1959b097fa66SStefano Zampini } else { 1960b097fa66SStefano Zampini if (pcbddc->switch_static) { 1961b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 1962b097fa66SStefano Zampini } else { 1963b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 1964b097fa66SStefano Zampini } 1965b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1966b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1967b097fa66SStefano Zampini } 196827b6a85dSStefano Zampini if (pcbddc->benign_have_null) { /* set p0 (computed in PCBDDCApplyInterface) */ 1969537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 1970537c1cdfSStefano Zampini } 19711dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 19721dd7afcfSStefano Zampini Vec swap; 19731dd7afcfSStefano Zampini 19741dd7afcfSStefano Zampini swap = r; 19751dd7afcfSStefano Zampini r = pcbddc->work_change; 19761dd7afcfSStefano Zampini pcbddc->work_change = swap; 19771dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 19781dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 19791dd7afcfSStefano Zampini } 198050efa1b5SStefano Zampini PetscFunctionReturn(0); 198150efa1b5SStefano Zampini } 1982da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 1983674ae819SStefano Zampini 1984da1bb401SStefano Zampini #undef __FUNCT__ 1985da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC" 1986da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 1987da1bb401SStefano Zampini { 1988da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1989da1bb401SStefano Zampini PetscErrorCode ierr; 1990da1bb401SStefano Zampini 1991da1bb401SStefano Zampini PetscFunctionBegin; 1992674ae819SStefano Zampini /* free BDDC custom data */ 1993674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 1994674ae819SStefano Zampini /* destroy objects related to topography */ 1995674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 1996674ae819SStefano Zampini /* free allocated graph structure */ 1997da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr); 1998b96c3477SStefano Zampini /* free allocated sub schurs structure */ 1999b96c3477SStefano Zampini ierr = PetscFree(pcbddc->sub_schurs);CHKERRQ(ierr); 200034a97f8cSStefano Zampini /* destroy objects for scaling operator */ 2001674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 200234a97f8cSStefano Zampini ierr = PetscFree(pcbddc->deluxe_ctx);CHKERRQ(ierr); 2003674ae819SStefano Zampini /* free solvers stuff */ 2004674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 200562a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 200662a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 200762a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 20081dd7afcfSStefano Zampini /* free data created by PCIS */ 20091dd7afcfSStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 20103425bc38SStefano Zampini /* remove functions */ 2011906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",NULL);CHKERRQ(ierr); 2012674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 201330368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",NULL);CHKERRQ(ierr); 2014bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 20152b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr); 2016b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr); 20172b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr); 2018bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",NULL);CHKERRQ(ierr); 2019bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 202082ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2021bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 202282ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2023bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 202482ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2025bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 2026785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2027bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 202863602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",NULL);CHKERRQ(ierr); 2029bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 2030bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 2031bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 2032bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 2033674ae819SStefano Zampini /* Free the private data structure */ 2034674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 2035da1bb401SStefano Zampini PetscFunctionReturn(0); 2036da1bb401SStefano Zampini } 20373425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 20381e6b0712SBarry Smith 20393425bc38SStefano Zampini #undef __FUNCT__ 20403425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC" 20413425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 20423425bc38SStefano Zampini { 2043674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 2044c08af4c6SStefano Zampini Vec copy_standard_rhs; 20453425bc38SStefano Zampini PC_IS* pcis; 20463425bc38SStefano Zampini PC_BDDC* pcbddc; 20473425bc38SStefano Zampini PetscErrorCode ierr; 20480c7d97c5SJed Brown 20493425bc38SStefano Zampini PetscFunctionBegin; 20503425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 20513425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 20523425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 20533425bc38SStefano Zampini 2054c08af4c6SStefano Zampini /* 2055c08af4c6SStefano Zampini change of basis for physical rhs if needed 2056c08af4c6SStefano Zampini It also changes the rhs in case of dirichlet boundaries 2057c08af4c6SStefano Zampini TODO: better management when FETIDP will have its own class 2058c08af4c6SStefano Zampini */ 2059c08af4c6SStefano Zampini ierr = VecDuplicate(standard_rhs,©_standard_rhs);CHKERRQ(ierr); 2060c08af4c6SStefano Zampini ierr = VecCopy(standard_rhs,copy_standard_rhs);CHKERRQ(ierr); 2061c08af4c6SStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,copy_standard_rhs,NULL);CHKERRQ(ierr); 20623425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 2063c08af4c6SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,copy_standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2064c08af4c6SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,copy_standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2065fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 2066fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 2067c08af4c6SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2068c08af4c6SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2069674ae819SStefano Zampini /* Apply partition of unity */ 20703425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 2071c08af4c6SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,copy_standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 20728eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 20733425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 20743425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 20753425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 20763425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 2077c08af4c6SStefano Zampini ierr = VecSet(copy_standard_rhs,0.0);CHKERRQ(ierr); 2078c08af4c6SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,copy_standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2079c08af4c6SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,copy_standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2080c08af4c6SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,copy_standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 2081c08af4c6SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2082c08af4c6SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20833425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 20843425bc38SStefano Zampini } 2085c08af4c6SStefano Zampini ierr = VecDestroy(©_standard_rhs);CHKERRQ(ierr); 20863425bc38SStefano Zampini /* BDDC rhs */ 20873425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 20888eeda7d8SStefano Zampini if (pcbddc->switch_static) { 20893425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 20903425bc38SStefano Zampini } 20913425bc38SStefano Zampini /* apply BDDC */ 2092dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 20933425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 20943425bc38SStefano Zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 20953425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 20963425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20973425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20983425bc38SStefano Zampini PetscFunctionReturn(0); 20993425bc38SStefano Zampini } 21001e6b0712SBarry Smith 21013425bc38SStefano Zampini #undef __FUNCT__ 21023425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS" 21033425bc38SStefano Zampini /*@ 21040f202f7eSStefano Zampini PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETI-DP linear system using the physical right-hand side 21053425bc38SStefano Zampini 21063425bc38SStefano Zampini Collective 21073425bc38SStefano Zampini 21083425bc38SStefano Zampini Input Parameters: 21090f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix object obtained by a call to PCBDDCCreateFETIDPOperators 21100f202f7eSStefano Zampini - standard_rhs - the right-hand side of the original linear system 21113425bc38SStefano Zampini 21123425bc38SStefano Zampini Output Parameters: 21130f202f7eSStefano Zampini . fetidp_flux_rhs - the right-hand side for the FETI-DP linear system 21143425bc38SStefano Zampini 21153425bc38SStefano Zampini Level: developer 21163425bc38SStefano Zampini 21173425bc38SStefano Zampini Notes: 21183425bc38SStefano Zampini 21190f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetSolution 21203425bc38SStefano Zampini @*/ 21213425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 21223425bc38SStefano Zampini { 2123674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 21243425bc38SStefano Zampini PetscErrorCode ierr; 21253425bc38SStefano Zampini 21263425bc38SStefano Zampini PetscFunctionBegin; 21273425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 21283425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 21293425bc38SStefano Zampini PetscFunctionReturn(0); 21303425bc38SStefano Zampini } 21313425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 21321e6b0712SBarry Smith 21333425bc38SStefano Zampini #undef __FUNCT__ 21343425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC" 21353425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 21363425bc38SStefano Zampini { 2137674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 21383425bc38SStefano Zampini PC_IS* pcis; 21393425bc38SStefano Zampini PC_BDDC* pcbddc; 21403425bc38SStefano Zampini PetscErrorCode ierr; 21413425bc38SStefano Zampini 21423425bc38SStefano Zampini PetscFunctionBegin; 21433425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 21443425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 21453425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 21463425bc38SStefano Zampini 21473425bc38SStefano Zampini /* apply B_delta^T */ 21483425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21493425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21503425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 21513425bc38SStefano Zampini /* compute rhs for BDDC application */ 21523425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 21538eeda7d8SStefano Zampini if (pcbddc->switch_static) { 21543425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 21553425bc38SStefano Zampini } 21563425bc38SStefano Zampini /* apply BDDC */ 2157dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 21583425bc38SStefano Zampini /* put values into standard global vector */ 21593425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21603425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21618eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 21623425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 21633425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 21643425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_D,-1.0,pcis->vec1_D);CHKERRQ(ierr); 21653425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 21663425bc38SStefano Zampini } 21673425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21683425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21693425bc38SStefano Zampini /* final change of basis if needed 21703425bc38SStefano Zampini Is also sums the dirichlet part removed during RHS assembling */ 21713308cffdSStefano Zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 21723425bc38SStefano Zampini PetscFunctionReturn(0); 21733425bc38SStefano Zampini } 21741e6b0712SBarry Smith 21753425bc38SStefano Zampini #undef __FUNCT__ 21763425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution" 21773425bc38SStefano Zampini /*@ 21780f202f7eSStefano Zampini PCBDDCMatFETIDPGetSolution - Compute the physical solution using the solution of the FETI-DP linear system 21793425bc38SStefano Zampini 21803425bc38SStefano Zampini Collective 21813425bc38SStefano Zampini 21823425bc38SStefano Zampini Input Parameters: 21830f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix obtained by a call to PCBDDCCreateFETIDPOperators 21840f202f7eSStefano Zampini - fetidp_flux_sol - the solution of the FETI-DP linear system 21853425bc38SStefano Zampini 21863425bc38SStefano Zampini Output Parameters: 21870f202f7eSStefano Zampini . standard_sol - the solution defined on the physical domain 21883425bc38SStefano Zampini 21893425bc38SStefano Zampini Level: developer 21903425bc38SStefano Zampini 21913425bc38SStefano Zampini Notes: 21923425bc38SStefano Zampini 21930f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetRHS 21943425bc38SStefano Zampini @*/ 21953425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 21963425bc38SStefano Zampini { 2197674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 21983425bc38SStefano Zampini PetscErrorCode ierr; 21993425bc38SStefano Zampini 22003425bc38SStefano Zampini PetscFunctionBegin; 22013425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 22023425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 22033425bc38SStefano Zampini PetscFunctionReturn(0); 22043425bc38SStefano Zampini } 22053425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 22061e6b0712SBarry Smith 2207f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec); 2208edf7251bSStefano Zampini extern PetscErrorCode FETIDPMatMultTranspose(Mat,Vec,Vec); 2209f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat); 2210f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec); 2211edf7251bSStefano Zampini extern PetscErrorCode FETIDPPCApplyTranspose(PC,Vec,Vec); 2212f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC); 2213674ae819SStefano Zampini 22143425bc38SStefano Zampini #undef __FUNCT__ 22153425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC" 22163425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 22173425bc38SStefano Zampini { 2218674ae819SStefano Zampini 2219674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 22203425bc38SStefano Zampini Mat newmat; 2221674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 22223425bc38SStefano Zampini PC newpc; 2223ce94432eSBarry Smith MPI_Comm comm; 22243425bc38SStefano Zampini PetscErrorCode ierr; 22253425bc38SStefano Zampini 22263425bc38SStefano Zampini PetscFunctionBegin; 2227ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 22283425bc38SStefano Zampini /* FETIDP linear matrix */ 22293425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 22303425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 22313425bc38SStefano Zampini ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 22323425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 2233edf7251bSStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT_TRANSPOSE,(void (*)(void))FETIDPMatMultTranspose);CHKERRQ(ierr); 22343425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 22353425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 22363425bc38SStefano Zampini /* FETIDP preconditioner */ 22373425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 22383425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 22393425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 22403425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 22413425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 22423425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 2243edf7251bSStefano Zampini ierr = PCShellSetApplyTranspose(newpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 22443425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 224523ee1639SBarry Smith ierr = PCSetOperators(newpc,newmat,newmat);CHKERRQ(ierr); 22463425bc38SStefano Zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 22473425bc38SStefano Zampini /* return pointers for objects created */ 22483425bc38SStefano Zampini *fetidp_mat=newmat; 22493425bc38SStefano Zampini *fetidp_pc=newpc; 22503425bc38SStefano Zampini PetscFunctionReturn(0); 22513425bc38SStefano Zampini } 22521e6b0712SBarry Smith 22533425bc38SStefano Zampini #undef __FUNCT__ 22543425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators" 22553425bc38SStefano Zampini /*@ 22560f202f7eSStefano Zampini PCBDDCCreateFETIDPOperators - Create FETI-DP operators 22573425bc38SStefano Zampini 22583425bc38SStefano Zampini Collective 22593425bc38SStefano Zampini 22603425bc38SStefano Zampini Input Parameters: 22610f202f7eSStefano Zampini . pc - the BDDC preconditioning context (setup should have been called before) 226228509bceSStefano Zampini 226328509bceSStefano Zampini Output Parameters: 22640f202f7eSStefano Zampini + fetidp_mat - shell FETI-DP matrix object 22650f202f7eSStefano Zampini - fetidp_pc - shell Dirichlet preconditioner for FETI-DP matrix 226628509bceSStefano Zampini 226728509bceSStefano Zampini Options Database Keys: 22680f202f7eSStefano Zampini . -fetidp_fullyredundant <false> - use or not a fully redundant set of Lagrange multipliers 22693425bc38SStefano Zampini 22703425bc38SStefano Zampini Level: developer 22713425bc38SStefano Zampini 22723425bc38SStefano Zampini Notes: 22730f202f7eSStefano Zampini Currently the only operations provided for FETI-DP matrix are MatMult and MatMultTranspose 22743425bc38SStefano Zampini 22750f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCMatFETIDPGetRHS, PCBDDCMatFETIDPGetSolution 22763425bc38SStefano Zampini @*/ 22773425bc38SStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 22783425bc38SStefano Zampini { 22793425bc38SStefano Zampini PetscErrorCode ierr; 22803425bc38SStefano Zampini 22813425bc38SStefano Zampini PetscFunctionBegin; 22823425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 22833425bc38SStefano Zampini if (pc->setupcalled) { 2284516d51a7SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,Mat*,PC*),(pc,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 2285f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n"); 22863425bc38SStefano Zampini PetscFunctionReturn(0); 22873425bc38SStefano Zampini } 22880c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2289da1bb401SStefano Zampini /*MC 2290da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 22910c7d97c5SJed Brown 229228509bceSStefano Zampini An implementation of the BDDC preconditioner based on 229328509bceSStefano Zampini 229428509bceSStefano Zampini .vb 229528509bceSStefano Zampini [1] C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 229628509bceSStefano 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 229728509bceSStefano Zampini [3] J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", http://arxiv.org/abs/0712.3977 22980f202f7eSStefano 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 229928509bceSStefano Zampini .ve 230028509bceSStefano Zampini 230128509bceSStefano Zampini The matrix to be preconditioned (Pmat) must be of type MATIS. 230228509bceSStefano Zampini 23030f202f7eSStefano Zampini Currently works with MATIS matrices with local matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers. 230428509bceSStefano Zampini 230528509bceSStefano Zampini It also works with unsymmetric and indefinite problems. 230628509bceSStefano Zampini 2307b6fdb6dfSStefano 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. 2308b6fdb6dfSStefano Zampini 23090f202f7eSStefano Zampini Approximate local solvers are automatically adapted for singular linear problems (see [1]) if the user has provided the nullspace using PCBDDCSetNullSpace() 231028509bceSStefano Zampini 23110f202f7eSStefano 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() 231230368db7SStefano Zampini Additional information on dofs can be provided by using PCBDDCSetDofsSplitting(), PCBDDCSetDirichletBoundaries(), PCBDDCSetNeumannBoundaries(), and PCBDDCSetPrimalVerticesIS() and their local counterparts. 231328509bceSStefano Zampini 23140f202f7eSStefano Zampini Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace(). Non-singular modes are retained via SVD. 231528509bceSStefano Zampini 23160f202f7eSStefano 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. 23170f202f7eSStefano Zampini User defined change of basis can be passed to PCBDDC by using PCBDDCSetChangeOfBasisMat() 231828509bceSStefano Zampini 23190f202f7eSStefano Zampini The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using a MatPartitioning object. 232028509bceSStefano Zampini 2321df4d28bfSStefano 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. 232228509bceSStefano Zampini 23230f202f7eSStefano 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. 23240f202f7eSStefano Zampini Deluxe scaling is not supported yet for FETI-DP. 23250f202f7eSStefano Zampini 23260f202f7eSStefano Zampini Options Database Keys (some of them, run with -h for a complete list): 23270f202f7eSStefano Zampini 23280f202f7eSStefano Zampini . -pc_bddc_use_vertices <true> - use or not vertices in primal space 23290f202f7eSStefano Zampini . -pc_bddc_use_edges <true> - use or not edges in primal space 23300f202f7eSStefano Zampini . -pc_bddc_use_faces <false> - use or not faces in primal space 23310f202f7eSStefano Zampini . -pc_bddc_symmetric <true> - symmetric computation of primal basis functions. Specify false for unsymmetric problems 23320f202f7eSStefano Zampini . -pc_bddc_use_change_of_basis <false> - use change of basis approach (on edges only) 23330f202f7eSStefano Zampini . -pc_bddc_use_change_on_faces <false> - use change of basis approach on faces if change of basis has been requested 23340f202f7eSStefano Zampini . -pc_bddc_switch_static <false> - switches from M_2 (default) to M_3 operator (see reference article [1]) 233528509bceSStefano Zampini . -pc_bddc_levels <0> - maximum number of levels for multilevel 23360f202f7eSStefano 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) 23370f202f7eSStefano 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) 23380f202f7eSStefano Zampini . -pc_bddc_use_deluxe_scaling <false> - use deluxe scaling 23390f202f7eSStefano 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) 2340df4d28bfSStefano 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) 234128509bceSStefano Zampini - -pc_bddc_check_level <0> - set verbosity level of debugging output 234228509bceSStefano Zampini 234328509bceSStefano Zampini Options for Dirichlet, Neumann or coarse solver can be set with 234428509bceSStefano Zampini .vb 234528509bceSStefano Zampini -pc_bddc_dirichlet_ 234628509bceSStefano Zampini -pc_bddc_neumann_ 234728509bceSStefano Zampini -pc_bddc_coarse_ 234828509bceSStefano Zampini .ve 23490f202f7eSStefano Zampini e.g -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg. PCBDDC uses by default KPSPREONLY and PCLU. 235028509bceSStefano Zampini 23510f202f7eSStefano Zampini When using a multilevel approach, solvers' options at the N-th level (N > 1) can be specified as 235228509bceSStefano Zampini .vb 2353312be037SStefano Zampini -pc_bddc_dirichlet_lN_ 2354312be037SStefano Zampini -pc_bddc_neumann_lN_ 2355312be037SStefano Zampini -pc_bddc_coarse_lN_ 235628509bceSStefano Zampini .ve 23570f202f7eSStefano Zampini Note that level number ranges from the finest (0) to the coarsest (N). 23580f202f7eSStefano 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. 23590f202f7eSStefano Zampini .vb 23600f202f7eSStefano Zampini -pc_bddc_coarse_pc_bddc_adaptive_threshold 5 -pc_bddc_coarse_l1_pc_bddc_redistribute 3 23610f202f7eSStefano Zampini .ve 23620f202f7eSStefano 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 2363da1bb401SStefano Zampini 2364da1bb401SStefano Zampini Level: intermediate 2365da1bb401SStefano Zampini 2366b6fdb6dfSStefano Zampini Developer notes: 2367da1bb401SStefano Zampini 2368da1bb401SStefano Zampini Contributed by Stefano Zampini 2369da1bb401SStefano Zampini 2370da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 2371da1bb401SStefano Zampini M*/ 2372b2573a8aSBarry Smith 2373da1bb401SStefano Zampini #undef __FUNCT__ 2374da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC" 23758cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 2376da1bb401SStefano Zampini { 2377da1bb401SStefano Zampini PetscErrorCode ierr; 2378da1bb401SStefano Zampini PC_BDDC *pcbddc; 2379da1bb401SStefano Zampini 2380da1bb401SStefano Zampini PetscFunctionBegin; 2381da1bb401SStefano Zampini /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 2382b00a9115SJed Brown ierr = PetscNewLog(pc,&pcbddc);CHKERRQ(ierr); 2383da1bb401SStefano Zampini pc->data = (void*)pcbddc; 2384da1bb401SStefano Zampini 2385da1bb401SStefano Zampini /* create PCIS data structure */ 2386da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 2387da1bb401SStefano Zampini 238847d04d0dSStefano Zampini /* BDDC customization */ 238908a5cf49SStefano Zampini pcbddc->use_local_adj = PETSC_TRUE; 239047d04d0dSStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 239147d04d0dSStefano Zampini pcbddc->use_edges = PETSC_TRUE; 239247d04d0dSStefano Zampini pcbddc->use_faces = PETSC_FALSE; 239347d04d0dSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 239447d04d0dSStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 239547d04d0dSStefano Zampini pcbddc->switch_static = PETSC_FALSE; 2396fa434743SStefano Zampini pcbddc->use_nnsp_true = PETSC_FALSE; 2397fa434743SStefano Zampini pcbddc->use_qr_single = PETSC_FALSE; 23983301b35fSStefano Zampini pcbddc->symmetric_primal = PETSC_TRUE; 239906a4e24aSStefano Zampini pcbddc->benign_saddle_point = PETSC_FALSE; 240027b6a85dSStefano Zampini pcbddc->benign_have_null = PETSC_FALSE; 240114f95afaSStefano Zampini pcbddc->vertex_size = 1; 240247d04d0dSStefano Zampini pcbddc->dbg_flag = 0; 2403b9d89cd5SStefano Zampini /* private */ 2404727cdba6SStefano Zampini pcbddc->local_primal_size = 0; 24050e6343abSStefano Zampini pcbddc->local_primal_size_cc = 0; 24060e6343abSStefano Zampini pcbddc->local_primal_ref_node = 0; 24070e6343abSStefano Zampini pcbddc->local_primal_ref_mult = 0; 2408e9189074SStefano Zampini pcbddc->n_vertices = 0; 2409727cdba6SStefano Zampini pcbddc->primal_indices_local_idxs = 0; 2410fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 241168457ee5SStefano Zampini pcbddc->coarse_size = -1; 2412f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 2413727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 2414f4ddd8eeSStefano Zampini pcbddc->global_primal_indices = 0; 2415f4ddd8eeSStefano Zampini pcbddc->onearnullspace = 0; 2416f4ddd8eeSStefano Zampini pcbddc->onearnullvecs_state = 0; 2417674ae819SStefano Zampini pcbddc->user_primal_vertices = 0; 241830368db7SStefano Zampini pcbddc->user_primal_vertices_local = 0; 24190bdf917eSStefano Zampini pcbddc->NullSpace = 0; 24203972b0daSStefano Zampini pcbddc->temp_solution = 0; 2421534831adSStefano Zampini pcbddc->original_rhs = 0; 2422534831adSStefano Zampini pcbddc->local_mat = 0; 2423534831adSStefano Zampini pcbddc->ChangeOfBasisMatrix = 0; 2424b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = 0; 2425da1bb401SStefano Zampini pcbddc->coarse_vec = 0; 2426da1bb401SStefano Zampini pcbddc->coarse_ksp = 0; 2427da1bb401SStefano Zampini pcbddc->coarse_phi_B = 0; 2428da1bb401SStefano Zampini pcbddc->coarse_phi_D = 0; 242915aaf578SStefano Zampini pcbddc->coarse_psi_B = 0; 243015aaf578SStefano Zampini pcbddc->coarse_psi_D = 0; 2431da1bb401SStefano Zampini pcbddc->vec1_P = 0; 2432da1bb401SStefano Zampini pcbddc->vec1_R = 0; 2433da1bb401SStefano Zampini pcbddc->vec2_R = 0; 2434da1bb401SStefano Zampini pcbddc->local_auxmat1 = 0; 2435da1bb401SStefano Zampini pcbddc->local_auxmat2 = 0; 2436da1bb401SStefano Zampini pcbddc->R_to_B = 0; 2437da1bb401SStefano Zampini pcbddc->R_to_D = 0; 2438da1bb401SStefano Zampini pcbddc->ksp_D = 0; 2439da1bb401SStefano Zampini pcbddc->ksp_R = 0; 2440da1bb401SStefano Zampini pcbddc->NeumannBoundaries = 0; 2441785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = 0; 2442785d1243SStefano Zampini pcbddc->DirichletBoundaries = 0; 2443785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = 0; 244460d44989SStefano Zampini pcbddc->user_provided_isfordofs = PETSC_FALSE; 244560d44989SStefano Zampini pcbddc->n_ISForDofs = 0; 244663602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 2447da1bb401SStefano Zampini pcbddc->ISForDofs = 0; 244863602bcaSStefano Zampini pcbddc->ISForDofsLocal = 0; 2449da1bb401SStefano Zampini pcbddc->ConstraintMatrix = 0; 245085c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 245147d04d0dSStefano Zampini pcbddc->coarse_loc_to_glob = 0; 245247d04d0dSStefano Zampini pcbddc->coarsening_ratio = 8; 2453b0c7d250SStefano Zampini pcbddc->coarse_adj_red = 0; 24544fad6a16SStefano Zampini pcbddc->current_level = 0; 24552b510759SStefano Zampini pcbddc->max_levels = 0; 2456323d395dSStefano Zampini pcbddc->use_coarse_estimates = PETSC_FALSE; 245757de7509SStefano Zampini pcbddc->coarse_eqs_per_proc = 1; 2458f3bde8b3SStefano Zampini pcbddc->coarse_subassembling = 0; 24594f1b2e48SStefano Zampini pcbddc->detect_disconnected = PETSC_FALSE; 24604f1b2e48SStefano Zampini pcbddc->n_local_subs = 0; 24614f1b2e48SStefano Zampini pcbddc->local_subs = NULL; 246281d14e9dSStefano Zampini 246381d14e9dSStefano Zampini /* benign subspace trick */ 246481d14e9dSStefano Zampini pcbddc->benign_change = 0; 246527b6a85dSStefano Zampini pcbddc->benign_compute_correction = PETSC_TRUE; 24660369aaf7SStefano Zampini pcbddc->benign_vec = 0; 24670369aaf7SStefano Zampini pcbddc->benign_original_mat = 0; 24680369aaf7SStefano Zampini pcbddc->benign_sf = 0; 24694f1b2e48SStefano Zampini pcbddc->benign_B0 = 0; 24704f1b2e48SStefano Zampini pcbddc->benign_n = 0; 24714f1b2e48SStefano Zampini pcbddc->benign_p0 = NULL; 24724f1b2e48SStefano Zampini pcbddc->benign_p0_lidx = NULL; 24734f1b2e48SStefano Zampini pcbddc->benign_p0_gidx = NULL; 2474b0f5fe93SStefano Zampini pcbddc->benign_null = PETSC_FALSE; 247581d14e9dSStefano Zampini 2476674ae819SStefano Zampini /* create local graph structure */ 2477674ae819SStefano Zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 2478674ae819SStefano Zampini 2479674ae819SStefano Zampini /* scaling */ 2480674ae819SStefano Zampini pcbddc->work_scaling = 0; 248134a97f8cSStefano Zampini pcbddc->use_deluxe_scaling = PETSC_FALSE; 2482b96c3477SStefano Zampini 2483b96c3477SStefano Zampini /* create sub schurs structure */ 2484b96c3477SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 2485b96c3477SStefano Zampini pcbddc->sub_schurs_rebuild = PETSC_FALSE; 2486b96c3477SStefano Zampini pcbddc->sub_schurs_layers = -1; 2487b96c3477SStefano Zampini pcbddc->sub_schurs_use_useradj = PETSC_FALSE; 2488b96c3477SStefano Zampini 2489b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_FALSE; 2490da1bb401SStefano Zampini 2491b7eb3628SStefano Zampini /* adaptivity */ 2492f6f667cfSStefano Zampini pcbddc->adaptive_threshold = 0.0; 249308122e43SStefano Zampini pcbddc->adaptive_nmax = 0; 2494f6f667cfSStefano Zampini pcbddc->adaptive_nmin = 0; 2495b7eb3628SStefano Zampini 2496da1bb401SStefano Zampini /* function pointers */ 2497da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 249893bd9ae7SStefano Zampini pc->ops->applytranspose = PCApplyTranspose_BDDC; 2499da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 2500da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 2501da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 25026b78500eSPatrick Sanan pc->ops->view = PCView_BDDC; 2503da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 2504da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 2505da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 2506534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 2507534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 2508da1bb401SStefano Zampini 2509da1bb401SStefano Zampini /* composing function */ 2510906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",PCBDDCSetChangeOfBasisMat_BDDC);CHKERRQ(ierr); 2511674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 251230368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",PCBDDCSetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 2513bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 25142b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr); 2515b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr); 25162b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr); 2517bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",PCBDDCSetNullSpace_BDDC);CHKERRQ(ierr); 2518bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 251982ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2520bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 252182ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2522bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 252382ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2524bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 252582ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2526bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 252763602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",PCBDDCSetDofsSplittingLocal_BDDC);CHKERRQ(ierr); 2528bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 2529bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 2530bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 2531bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 2532da1bb401SStefano Zampini PetscFunctionReturn(0); 2533da1bb401SStefano Zampini } 25343425bc38SStefano Zampini 2535