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); 78*e9627c49SStefano 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); 794f1b2e48SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_detect_disconnected","Detects disconnected subdomains","none",pcbddc->detect_disconnected,&pcbddc->detect_disconnected,NULL);CHKERRQ(ierr); 8070c64980SStefano 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); 810c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 820c7d97c5SJed Brown PetscFunctionReturn(0); 830c7d97c5SJed Brown } 846b78500eSPatrick Sanan 856b78500eSPatrick Sanan /* -------------------------------------------------------------------------- */ 866b78500eSPatrick Sanan #undef __FUNCT__ 876b78500eSPatrick Sanan #define __FUNCT__ "PCView_BDDC" 886b78500eSPatrick Sanan static PetscErrorCode PCView_BDDC(PC pc,PetscViewer viewer) 896b78500eSPatrick Sanan { 906b78500eSPatrick Sanan PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 91*e9627c49SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 926b78500eSPatrick Sanan PetscErrorCode ierr; 936b78500eSPatrick Sanan PetscBool isascii,isstring; 94*e9627c49SStefano Zampini PetscSubcomm subcomm; 95*e9627c49SStefano Zampini PetscViewer subviewer; 966b78500eSPatrick Sanan 976b78500eSPatrick Sanan PetscFunctionBegin; 986b78500eSPatrick Sanan ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 996b78500eSPatrick Sanan ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 1006b78500eSPatrick Sanan /* Nothing printed for the String viewer */ 1016b78500eSPatrick Sanan /* ASCII viewer */ 1026b78500eSPatrick Sanan if (isascii) { 103*e9627c49SStefano Zampini PetscMPIInt color,rank; 104*e9627c49SStefano Zampini Petsc64bitInt loc[4],gsum[4],gmax[4],gmin[4]; 105*e9627c49SStefano Zampini PetscScalar interface_size; 106*e9627c49SStefano Zampini PetscReal ratio1=0.,ratio2=0.; 107*e9627c49SStefano Zampini Vec counter; 1086b78500eSPatrick Sanan 109*e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use verbose output: %d\n",pcbddc->dbg_flag);CHKERRQ(ierr); 110*e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use user-defined CSR: %d\n",!!pcbddc->mat_graph->nvtxs_csr);CHKERRQ(ierr); 1116b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use local mat graph: %d\n",pcbddc->use_local_adj);CHKERRQ(ierr); 112*e9627c49SStefano Zampini if (pcbddc->mat_graph->twodim) { 113*e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Connectivity graph topological dimension: 2\n");CHKERRQ(ierr); 114*e9627c49SStefano Zampini } else { 115*e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Connectivity graph topological dimension: 3\n");CHKERRQ(ierr); 116*e9627c49SStefano Zampini } 117*e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use vertices: %d (vertext size %d)\n",pcbddc->use_vertices,pcbddc->vertex_size);CHKERRQ(ierr); 1186b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use edges: %d\n",pcbddc->use_edges);CHKERRQ(ierr); 1196b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use faces: %d\n",pcbddc->use_faces);CHKERRQ(ierr); 1206b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use true near null space: %d\n",pcbddc->use_nnsp_true);CHKERRQ(ierr); 1216b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use QR for single constraints on cc: %d\n",pcbddc->use_qr_single);CHKERRQ(ierr); 1226b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use change of basis on local edge nodes: %d\n",pcbddc->use_change_of_basis);CHKERRQ(ierr); 1236b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use change of basis on local face nodes: %d\n",pcbddc->use_change_on_faces);CHKERRQ(ierr); 12470c64980SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Eliminate dirichlet dofs: %d\n",pcbddc->eliminate_dirdofs);CHKERRQ(ierr); 1256b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Switch on static condensation ops around the interface preconditioner: %d\n",pcbddc->switch_static);CHKERRQ(ierr); 1266b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Multilevel max levels: %d\n",pcbddc->max_levels);CHKERRQ(ierr); 127*e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Multilevel coarsening ratio: %d\n",pcbddc->coarsening_ratio);CHKERRQ(ierr); 1286b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use estimated eigs for coarse problem: %d\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 1296b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use deluxe scaling: %d\n",pcbddc->use_deluxe_scaling);CHKERRQ(ierr); 130*e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use deluxe zerorows: %d\n",pcbddc->deluxe_zerorows);CHKERRQ(ierr); 1316b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Rebuild interface graph for Schur principal minors: %d\n",pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 1326b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Number of dofs' layers for the computation of principal minors: %d\n",pcbddc->sub_schurs_layers);CHKERRQ(ierr); 1336b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Use user CSR graph to compute successive layers: %d\n",pcbddc->sub_schurs_use_useradj);CHKERRQ(ierr); 134*e9627c49SStefano 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); 1356b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Min constraints / connected component: %d\n",pcbddc->adaptive_nmin);CHKERRQ(ierr); 1366b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Max constraints / connected component: %d\n",pcbddc->adaptive_nmax);CHKERRQ(ierr); 137*e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Invert exact Schur complement for adaptive selection: %d\n",pcbddc->sub_schurs_exact_schur);CHKERRQ(ierr); 1386b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Symmetric computation of primal basis functions: %d\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 1396b78500eSPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer," BDDC: Num. Procs. to map coarse adjacency list: %d\n",pcbddc->coarse_adj_red);CHKERRQ(ierr); 140*e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Coarse eqs per proc (significant at the coarsest level): %d\n",pcbddc->coarse_eqs_per_proc);CHKERRQ(ierr); 141*e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Detect disconnected: %d\n",pcbddc->detect_disconnected);CHKERRQ(ierr); 142*e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Benign subspace trick: %d (algebraic computation of no-net-flux %d)\n",pcbddc->benign_saddle_point,pcbddc->benign_compute_nonetflux);CHKERRQ(ierr); 143*e9627c49SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1446b78500eSPatrick Sanan 145*e9627c49SStefano Zampini /* compute some number on the domain decomposition */ 146*e9627c49SStefano Zampini ierr = VecSet(pcis->vec1_B,1.0);CHKERRQ(ierr); 147*e9627c49SStefano Zampini ierr = MatCreateVecs(pc->pmat,&counter,0);CHKERRQ(ierr); 148*e9627c49SStefano Zampini ierr = VecSet(counter,0.0);CHKERRQ(ierr); 149*e9627c49SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 150*e9627c49SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,counter,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 151*e9627c49SStefano Zampini ierr = VecSum(counter,&interface_size);CHKERRQ(ierr); 152*e9627c49SStefano Zampini ierr = VecDestroy(&counter);CHKERRQ(ierr); 153*e9627c49SStefano Zampini gsum[0] = 1; 154*e9627c49SStefano Zampini gsum[1] = gsum[2] = gsum[3] = 0; 155*e9627c49SStefano Zampini loc[0] = !!pcis->n; 156*e9627c49SStefano Zampini loc[1] = pcis->n - pcis->n_B; 157*e9627c49SStefano Zampini loc[2] = pcis->n_B; 158*e9627c49SStefano Zampini loc[3] = pcbddc->local_primal_size; 159*e9627c49SStefano Zampini ierr = MPI_Reduce(loc,gsum,4,MPIU_INT64,MPI_SUM,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 160*e9627c49SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = -1; 161*e9627c49SStefano Zampini ierr = MPI_Reduce(loc,gmax,4,MPIU_INT64,MPI_MAX,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 162*e9627c49SStefano Zampini if (!loc[0]) loc[1] = loc[2] = loc[3] = PETSC_MAX_INT; 163*e9627c49SStefano Zampini ierr = MPI_Reduce(loc,gmin,4,MPIU_INT64,MPI_MIN,0,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 164*e9627c49SStefano Zampini if (pcbddc->coarse_size) { 165*e9627c49SStefano Zampini ratio1 = pc->pmat->rmap->N/(1.*pcbddc->coarse_size); 166*e9627c49SStefano Zampini ratio2 = PetscRealPart(interface_size)/pcbddc->coarse_size; 167*e9627c49SStefano Zampini } 168*e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: ********************************** STATISTICS AT LEVEL %d **********************************\n",pcbddc->current_level);CHKERRQ(ierr); 169*e9627c49SStefano 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); 170*e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Coarsening ratios: all/coarse %d interface/coarse %d\n",(PetscInt)ratio1,(PetscInt)ratio2);CHKERRQ(ierr); 171*e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Active processes : %d\n",(PetscInt)gsum[0]);CHKERRQ(ierr); 172*e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: Dofs type :\tMIN\tMAX\tMEAN\n",(PetscInt)gmin[1],(PetscInt)gmax[1],(PetscInt)(gsum[1]/gsum[0]));CHKERRQ(ierr); 173*e9627c49SStefano 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); 174*e9627c49SStefano 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); 175*e9627c49SStefano 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); 176*e9627c49SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," BDDC: *******************************************************************************************\n");CHKERRQ(ierr); 177*e9627c49SStefano Zampini 178*e9627c49SStefano Zampini /* the coarse problem can be handled with a different communicator */ 179*e9627c49SStefano Zampini if (pcbddc->coarse_ksp) color = 1; 180*e9627c49SStefano Zampini else color = 0; 181*e9627c49SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 182*e9627c49SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)pc),&subcomm);CHKERRQ(ierr); 183*e9627c49SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 184*e9627c49SStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 185*e9627c49SStefano Zampini ierr = PetscViewerGetSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 186*e9627c49SStefano Zampini if (color == 1) { 187*e9627c49SStefano Zampini ierr = KSPView(pcbddc->coarse_ksp,subviewer);CHKERRQ(ierr); 188*e9627c49SStefano Zampini ierr = PetscViewerFlush(subviewer);CHKERRQ(ierr); 189*e9627c49SStefano Zampini } 190*e9627c49SStefano Zampini ierr = PetscViewerRestoreSubViewer(viewer,PetscSubcommChild(subcomm),&subviewer);CHKERRQ(ierr); 191*e9627c49SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 192*e9627c49SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 193*e9627c49SStefano Zampini } 1946b78500eSPatrick Sanan PetscFunctionReturn(0); 1956b78500eSPatrick Sanan } 1966b78500eSPatrick Sanan 1970c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 198674ae819SStefano Zampini #undef __FUNCT__ 199906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCSetChangeOfBasisMat_BDDC" 2001dd7afcfSStefano Zampini static PetscErrorCode PCBDDCSetChangeOfBasisMat_BDDC(PC pc, Mat change, PetscBool interior) 201b9b85e73SStefano Zampini { 202b9b85e73SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 203b9b85e73SStefano Zampini PetscErrorCode ierr; 204b9b85e73SStefano Zampini 205b9b85e73SStefano Zampini PetscFunctionBegin; 206b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)change);CHKERRQ(ierr); 20756282151SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 208b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = change; 2091dd7afcfSStefano Zampini pcbddc->change_interior = interior; 210b9b85e73SStefano Zampini PetscFunctionReturn(0); 211b9b85e73SStefano Zampini } 212b9b85e73SStefano Zampini #undef __FUNCT__ 213906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCSetChangeOfBasisMat" 214b9b85e73SStefano Zampini /*@ 215906d46d4SStefano Zampini PCBDDCSetChangeOfBasisMat - Set user defined change of basis for dofs 216b9b85e73SStefano Zampini 217b9b85e73SStefano Zampini Collective on PC 218b9b85e73SStefano Zampini 219b9b85e73SStefano Zampini Input Parameters: 220b9b85e73SStefano Zampini + pc - the preconditioning context 2211dd7afcfSStefano Zampini . change - the change of basis matrix 2221dd7afcfSStefano Zampini - interior - whether or not the change of basis modifies interior dofs 223b9b85e73SStefano Zampini 224b9b85e73SStefano Zampini Level: intermediate 225b9b85e73SStefano Zampini 226b9b85e73SStefano Zampini Notes: 227b9b85e73SStefano Zampini 228b9b85e73SStefano Zampini .seealso: PCBDDC 229b9b85e73SStefano Zampini @*/ 2301dd7afcfSStefano Zampini PetscErrorCode PCBDDCSetChangeOfBasisMat(PC pc, Mat change, PetscBool interior) 231b9b85e73SStefano Zampini { 232b9b85e73SStefano Zampini PetscErrorCode ierr; 233b9b85e73SStefano Zampini 234b9b85e73SStefano Zampini PetscFunctionBegin; 235b9b85e73SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 236b9b85e73SStefano Zampini PetscValidHeaderSpecific(change,MAT_CLASSID,2); 237906d46d4SStefano Zampini PetscCheckSameComm(pc,1,change,2); 238906d46d4SStefano Zampini if (pc->mat) { 239906d46d4SStefano Zampini PetscInt rows_c,cols_c,rows,cols; 240906d46d4SStefano Zampini ierr = MatGetSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 241906d46d4SStefano Zampini ierr = MatGetSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 2426c4ed002SBarry 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); 2436c4ed002SBarry 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); 244906d46d4SStefano Zampini ierr = MatGetLocalSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 245906d46d4SStefano Zampini ierr = MatGetLocalSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 2466c4ed002SBarry 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); 2476c4ed002SBarry 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); 248906d46d4SStefano Zampini } 2491dd7afcfSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetChangeOfBasisMat_C",(PC,Mat,PetscBool),(pc,change,interior));CHKERRQ(ierr); 250b9b85e73SStefano Zampini PetscFunctionReturn(0); 251b9b85e73SStefano Zampini } 252b9b85e73SStefano Zampini /* -------------------------------------------------------------------------- */ 253b9b85e73SStefano Zampini #undef __FUNCT__ 25430368db7SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesIS_BDDC" 25530368db7SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesIS_BDDC(PC pc, IS PrimalVertices) 25630368db7SStefano Zampini { 25730368db7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 25856282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 25930368db7SStefano Zampini PetscErrorCode ierr; 26030368db7SStefano Zampini 26130368db7SStefano Zampini PetscFunctionBegin; 26256282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 26356282151SStefano Zampini if (pcbddc->user_primal_vertices) { 26456282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices,&isequal);CHKERRQ(ierr); 26556282151SStefano Zampini } 26630368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 26730368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 26830368db7SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 26956282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 27030368db7SStefano Zampini PetscFunctionReturn(0); 27130368db7SStefano Zampini } 27230368db7SStefano Zampini #undef __FUNCT__ 27330368db7SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesIS" 27430368db7SStefano Zampini /*@ 27530368db7SStefano Zampini PCBDDCSetPrimalVerticesIS - Set additional user defined primal vertices in PCBDDC 27630368db7SStefano Zampini 27730368db7SStefano Zampini Collective 27830368db7SStefano Zampini 27930368db7SStefano Zampini Input Parameters: 28030368db7SStefano Zampini + pc - the preconditioning context 28130368db7SStefano Zampini - PrimalVertices - index set of primal vertices in global numbering (can be empty) 28230368db7SStefano Zampini 28330368db7SStefano Zampini Level: intermediate 28430368db7SStefano Zampini 28530368db7SStefano Zampini Notes: 28630368db7SStefano Zampini Any process can list any global node 28730368db7SStefano Zampini 28830368db7SStefano Zampini .seealso: PCBDDC 28930368db7SStefano Zampini @*/ 29030368db7SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesIS(PC pc, IS PrimalVertices) 29130368db7SStefano Zampini { 29230368db7SStefano Zampini PetscErrorCode ierr; 29330368db7SStefano Zampini 29430368db7SStefano Zampini PetscFunctionBegin; 29530368db7SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 29630368db7SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 29730368db7SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 29830368db7SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 29930368db7SStefano Zampini PetscFunctionReturn(0); 30030368db7SStefano Zampini } 30130368db7SStefano Zampini /* -------------------------------------------------------------------------- */ 30230368db7SStefano Zampini #undef __FUNCT__ 303674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS_BDDC" 304674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 305674ae819SStefano Zampini { 306674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 30756282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 308674ae819SStefano Zampini PetscErrorCode ierr; 3091e6b0712SBarry Smith 310674ae819SStefano Zampini PetscFunctionBegin; 31156282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 31256282151SStefano Zampini if (pcbddc->user_primal_vertices_local) { 31356282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices_local,&isequal);CHKERRQ(ierr); 31456282151SStefano Zampini } 315674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 31630368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 31730368db7SStefano Zampini pcbddc->user_primal_vertices_local = PrimalVertices; 31856282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 319674ae819SStefano Zampini PetscFunctionReturn(0); 320674ae819SStefano Zampini } 321674ae819SStefano Zampini #undef __FUNCT__ 322674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS" 323674ae819SStefano Zampini /*@ 32428509bceSStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC 325674ae819SStefano Zampini 32617eb1463SStefano Zampini Collective 327674ae819SStefano Zampini 328674ae819SStefano Zampini Input Parameters: 329674ae819SStefano Zampini + pc - the preconditioning context 33017eb1463SStefano Zampini - PrimalVertices - index set of primal vertices in local numbering (can be empty) 331674ae819SStefano Zampini 332674ae819SStefano Zampini Level: intermediate 333674ae819SStefano Zampini 334674ae819SStefano Zampini Notes: 335674ae819SStefano Zampini 336674ae819SStefano Zampini .seealso: PCBDDC 337674ae819SStefano Zampini @*/ 338674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 339674ae819SStefano Zampini { 340674ae819SStefano Zampini PetscErrorCode ierr; 341674ae819SStefano Zampini 342674ae819SStefano Zampini PetscFunctionBegin; 343674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 344674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 34517eb1463SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 346674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 347674ae819SStefano Zampini PetscFunctionReturn(0); 348674ae819SStefano Zampini } 349674ae819SStefano Zampini /* -------------------------------------------------------------------------- */ 3500c7d97c5SJed Brown #undef __FUNCT__ 3514fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio_BDDC" 3524fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 3534fad6a16SStefano Zampini { 3544fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3554fad6a16SStefano Zampini 3564fad6a16SStefano Zampini PetscFunctionBegin; 3574fad6a16SStefano Zampini pcbddc->coarsening_ratio = k; 3584fad6a16SStefano Zampini PetscFunctionReturn(0); 3594fad6a16SStefano Zampini } 3601e6b0712SBarry Smith 3614fad6a16SStefano Zampini #undef __FUNCT__ 3624fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio" 3634fad6a16SStefano Zampini /*@ 36428509bceSStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel 3654fad6a16SStefano Zampini 3664fad6a16SStefano Zampini Logically collective on PC 3674fad6a16SStefano Zampini 3684fad6a16SStefano Zampini Input Parameters: 3694fad6a16SStefano Zampini + pc - the preconditioning context 37028509bceSStefano Zampini - k - coarsening ratio (H/h at the coarser level) 3714fad6a16SStefano Zampini 3720f202f7eSStefano Zampini Options Database Keys: 3730f202f7eSStefano Zampini . -pc_bddc_coarsening_ratio 3744fad6a16SStefano Zampini 3754fad6a16SStefano Zampini Level: intermediate 3764fad6a16SStefano Zampini 3774fad6a16SStefano Zampini Notes: 3780f202f7eSStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level 3794fad6a16SStefano Zampini 3800f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetLevels() 3814fad6a16SStefano Zampini @*/ 3824fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 3834fad6a16SStefano Zampini { 3844fad6a16SStefano Zampini PetscErrorCode ierr; 3854fad6a16SStefano Zampini 3864fad6a16SStefano Zampini PetscFunctionBegin; 3874fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 3882b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,k,2); 3894fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 3904fad6a16SStefano Zampini PetscFunctionReturn(0); 3914fad6a16SStefano Zampini } 3922b510759SStefano Zampini 393b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */ 3942b510759SStefano Zampini #undef __FUNCT__ 395b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet_BDDC" 396b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg) 397b8ffe317SStefano Zampini { 398b8ffe317SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 399b8ffe317SStefano Zampini 400b8ffe317SStefano Zampini PetscFunctionBegin; 40185c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = flg; 402b8ffe317SStefano Zampini PetscFunctionReturn(0); 403b8ffe317SStefano Zampini } 404b8ffe317SStefano Zampini 405b8ffe317SStefano Zampini #undef __FUNCT__ 406b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet" 407b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg) 4082b510759SStefano Zampini { 4092b510759SStefano Zampini PetscErrorCode ierr; 4102b510759SStefano Zampini 4112b510759SStefano Zampini PetscFunctionBegin; 4122b510759SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 413b8ffe317SStefano Zampini PetscValidLogicalCollectiveBool(pc,flg,2); 414b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr); 4152b510759SStefano Zampini PetscFunctionReturn(0); 4162b510759SStefano Zampini } 4171e6b0712SBarry Smith 4184fad6a16SStefano Zampini #undef __FUNCT__ 4192b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel_BDDC" 4202b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level) 4214fad6a16SStefano Zampini { 4224fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4234fad6a16SStefano Zampini 4244fad6a16SStefano Zampini PetscFunctionBegin; 4252b510759SStefano Zampini pcbddc->current_level = level; 4264fad6a16SStefano Zampini PetscFunctionReturn(0); 4274fad6a16SStefano Zampini } 4281e6b0712SBarry Smith 4294fad6a16SStefano Zampini #undef __FUNCT__ 430b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel" 431b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 432b8ffe317SStefano Zampini { 433b8ffe317SStefano Zampini PetscErrorCode ierr; 434b8ffe317SStefano Zampini 435b8ffe317SStefano Zampini PetscFunctionBegin; 436b8ffe317SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 437b8ffe317SStefano Zampini PetscValidLogicalCollectiveInt(pc,level,2); 438b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr); 439b8ffe317SStefano Zampini PetscFunctionReturn(0); 440b8ffe317SStefano Zampini } 441b8ffe317SStefano Zampini 442b8ffe317SStefano Zampini #undef __FUNCT__ 4432b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels_BDDC" 4442b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels) 4452b510759SStefano Zampini { 4462b510759SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4472b510759SStefano Zampini 4482b510759SStefano Zampini PetscFunctionBegin; 4492b510759SStefano Zampini pcbddc->max_levels = levels; 4502b510759SStefano Zampini PetscFunctionReturn(0); 4512b510759SStefano Zampini } 4522b510759SStefano Zampini 4532b510759SStefano Zampini #undef __FUNCT__ 4542b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels" 4554fad6a16SStefano Zampini /*@ 45628509bceSStefano Zampini PCBDDCSetLevels - Sets the maximum number of levels for multilevel 4574fad6a16SStefano Zampini 4584fad6a16SStefano Zampini Logically collective on PC 4594fad6a16SStefano Zampini 4604fad6a16SStefano Zampini Input Parameters: 4614fad6a16SStefano Zampini + pc - the preconditioning context 46228509bceSStefano Zampini - levels - the maximum number of levels (max 9) 4634fad6a16SStefano Zampini 4640f202f7eSStefano Zampini Options Database Keys: 4650f202f7eSStefano Zampini . -pc_bddc_levels 4664fad6a16SStefano Zampini 4674fad6a16SStefano Zampini Level: intermediate 4684fad6a16SStefano Zampini 4694fad6a16SStefano Zampini Notes: 4700f202f7eSStefano Zampini Default value is 0, i.e. traditional one-level BDDC 4714fad6a16SStefano Zampini 4720f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetCoarseningRatio() 4734fad6a16SStefano Zampini @*/ 4742b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels) 4754fad6a16SStefano Zampini { 4764fad6a16SStefano Zampini PetscErrorCode ierr; 4774fad6a16SStefano Zampini 4784fad6a16SStefano Zampini PetscFunctionBegin; 4794fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 4802b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,levels,2); 481312be037SStefano Zampini if (levels > 99) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Maximum number of levels for bddc is 99\n"); 4822b510759SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr); 4834fad6a16SStefano Zampini PetscFunctionReturn(0); 4844fad6a16SStefano Zampini } 4854fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 4861e6b0712SBarry Smith 4874fad6a16SStefano Zampini #undef __FUNCT__ 4880bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace_BDDC" 4890bdf917eSStefano Zampini static PetscErrorCode PCBDDCSetNullSpace_BDDC(PC pc,MatNullSpace NullSpace) 4900bdf917eSStefano Zampini { 4910bdf917eSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4920bdf917eSStefano Zampini PetscErrorCode ierr; 4930bdf917eSStefano Zampini 4940bdf917eSStefano Zampini PetscFunctionBegin; 4950bdf917eSStefano Zampini ierr = PetscObjectReference((PetscObject)NullSpace);CHKERRQ(ierr); 4960bdf917eSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 4970bdf917eSStefano Zampini pcbddc->NullSpace = NullSpace; 4980bdf917eSStefano Zampini PetscFunctionReturn(0); 4990bdf917eSStefano Zampini } 5001e6b0712SBarry Smith 5010bdf917eSStefano Zampini #undef __FUNCT__ 5020bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace" 5030bdf917eSStefano Zampini /*@ 50428509bceSStefano Zampini PCBDDCSetNullSpace - Set nullspace for BDDC operator 5050bdf917eSStefano Zampini 5060bdf917eSStefano Zampini Logically collective on PC and MatNullSpace 5070bdf917eSStefano Zampini 5080bdf917eSStefano Zampini Input Parameters: 5090bdf917eSStefano Zampini + pc - the preconditioning context 51028509bceSStefano Zampini - NullSpace - Null space of the linear operator to be preconditioned (Pmat) 5110bdf917eSStefano Zampini 5120bdf917eSStefano Zampini Level: intermediate 5130bdf917eSStefano Zampini 5140bdf917eSStefano Zampini Notes: 5150bdf917eSStefano Zampini 5160bdf917eSStefano Zampini .seealso: PCBDDC 5170bdf917eSStefano Zampini @*/ 5180bdf917eSStefano Zampini PetscErrorCode PCBDDCSetNullSpace(PC pc,MatNullSpace NullSpace) 5190bdf917eSStefano Zampini { 5200bdf917eSStefano Zampini PetscErrorCode ierr; 5210bdf917eSStefano Zampini 5220bdf917eSStefano Zampini PetscFunctionBegin; 5230bdf917eSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 524674ae819SStefano Zampini PetscValidHeaderSpecific(NullSpace,MAT_NULLSPACE_CLASSID,2); 5252b510759SStefano Zampini PetscCheckSameComm(pc,1,NullSpace,2); 5260bdf917eSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNullSpace_C",(PC,MatNullSpace),(pc,NullSpace));CHKERRQ(ierr); 5270bdf917eSStefano Zampini PetscFunctionReturn(0); 5280bdf917eSStefano Zampini } 5290bdf917eSStefano Zampini /* -------------------------------------------------------------------------- */ 5301e6b0712SBarry Smith 5310bdf917eSStefano Zampini #undef __FUNCT__ 5323b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC" 5333b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 5343b03a366Sstefano_zampini { 5353b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 53656282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 5373b03a366Sstefano_zampini PetscErrorCode ierr; 5383b03a366Sstefano_zampini 5393b03a366Sstefano_zampini PetscFunctionBegin; 54056282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 54156282151SStefano Zampini if (pcbddc->DirichletBoundaries) { 54256282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundaries,&isequal);CHKERRQ(ierr); 54356282151SStefano Zampini } 544785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 545785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 5463b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 54736e030ebSStefano Zampini pcbddc->DirichletBoundaries = DirichletBoundaries; 54856282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 5493b03a366Sstefano_zampini PetscFunctionReturn(0); 5503b03a366Sstefano_zampini } 5511e6b0712SBarry Smith 5523b03a366Sstefano_zampini #undef __FUNCT__ 5533b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries" 5543b03a366Sstefano_zampini /*@ 55528509bceSStefano Zampini PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem. 5563b03a366Sstefano_zampini 557785d1243SStefano Zampini Collective 5583b03a366Sstefano_zampini 5593b03a366Sstefano_zampini Input Parameters: 5603b03a366Sstefano_zampini + pc - the preconditioning context 561785d1243SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries 5623b03a366Sstefano_zampini 5633b03a366Sstefano_zampini Level: intermediate 5643b03a366Sstefano_zampini 5650f202f7eSStefano Zampini Notes: 5660f202f7eSStefano Zampini Provide the information if you used MatZeroRows/Columns routines. Any process can list any global node 5673b03a366Sstefano_zampini 5680f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundariesLocal(), MatZeroRows(), MatZeroRowsColumns() 5693b03a366Sstefano_zampini @*/ 5703b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 5713b03a366Sstefano_zampini { 5723b03a366Sstefano_zampini PetscErrorCode ierr; 5733b03a366Sstefano_zampini 5743b03a366Sstefano_zampini PetscFunctionBegin; 5753b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 576674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 577785d1243SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 5783b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 5793b03a366Sstefano_zampini PetscFunctionReturn(0); 5803b03a366Sstefano_zampini } 5813b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 5821e6b0712SBarry Smith 5833b03a366Sstefano_zampini #undef __FUNCT__ 58482ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal_BDDC" 58582ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries) 5860c7d97c5SJed Brown { 5870c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 58856282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 5890c7d97c5SJed Brown PetscErrorCode ierr; 5900c7d97c5SJed Brown 5910c7d97c5SJed Brown PetscFunctionBegin; 59256282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 59356282151SStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 59456282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundariesLocal,&isequal);CHKERRQ(ierr); 59556282151SStefano Zampini } 596785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 597785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 5980c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 599785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = DirichletBoundaries; 60056282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 6010c7d97c5SJed Brown PetscFunctionReturn(0); 6020c7d97c5SJed Brown } 6030c7d97c5SJed Brown 6040c7d97c5SJed Brown #undef __FUNCT__ 60582ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal" 6069c0446d6SStefano Zampini /*@ 60782ba6b80SStefano Zampini PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering. 6089c0446d6SStefano Zampini 609785d1243SStefano Zampini Collective 61053cdbc3dSStefano Zampini 61153cdbc3dSStefano Zampini Input Parameters: 61253cdbc3dSStefano Zampini + pc - the preconditioning context 61382ba6b80SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering) 61453cdbc3dSStefano Zampini 61553cdbc3dSStefano Zampini Level: intermediate 61653cdbc3dSStefano Zampini 6179c0446d6SStefano Zampini Notes: 61853cdbc3dSStefano Zampini 6190f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundaries(), MatZeroRows(), MatZeroRowsColumns() 62053cdbc3dSStefano Zampini @*/ 62182ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries) 6220c7d97c5SJed Brown { 6230c7d97c5SJed Brown PetscErrorCode ierr; 6240c7d97c5SJed Brown 6250c7d97c5SJed Brown PetscFunctionBegin; 6260c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6270c7d97c5SJed Brown PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 62882ba6b80SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 62982ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 6300c7d97c5SJed Brown PetscFunctionReturn(0); 6310c7d97c5SJed Brown } 6320c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 6330c7d97c5SJed Brown 6340c7d97c5SJed Brown #undef __FUNCT__ 6350c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 63653cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 6370c7d97c5SJed Brown { 6380c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 63956282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 64053cdbc3dSStefano Zampini PetscErrorCode ierr; 6410c7d97c5SJed Brown 6420c7d97c5SJed Brown PetscFunctionBegin; 64356282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 64456282151SStefano Zampini if (pcbddc->NeumannBoundaries) { 64556282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundaries,&isequal);CHKERRQ(ierr); 64656282151SStefano Zampini } 647785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 648785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 64953cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 65036e030ebSStefano Zampini pcbddc->NeumannBoundaries = NeumannBoundaries; 65156282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 6520c7d97c5SJed Brown PetscFunctionReturn(0); 6530c7d97c5SJed Brown } 6541e6b0712SBarry Smith 6550c7d97c5SJed Brown #undef __FUNCT__ 6560c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 65757527edcSJed Brown /*@ 65828509bceSStefano Zampini PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem. 65957527edcSJed Brown 660785d1243SStefano Zampini Collective 66157527edcSJed Brown 66257527edcSJed Brown Input Parameters: 66357527edcSJed Brown + pc - the preconditioning context 664785d1243SStefano Zampini - NeumannBoundaries - parallel IS defining the Neumann boundaries 66557527edcSJed Brown 66657527edcSJed Brown Level: intermediate 66757527edcSJed Brown 6680f202f7eSStefano Zampini Notes: 6690f202f7eSStefano Zampini Any process can list any global node 67057527edcSJed Brown 6710f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundariesLocal() 67257527edcSJed Brown @*/ 67353cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 6740c7d97c5SJed Brown { 6750c7d97c5SJed Brown PetscErrorCode ierr; 6760c7d97c5SJed Brown 6770c7d97c5SJed Brown PetscFunctionBegin; 6780c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 679674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 680785d1243SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 68153cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 68253cdbc3dSStefano Zampini PetscFunctionReturn(0); 68353cdbc3dSStefano Zampini } 68453cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 6851e6b0712SBarry Smith 68653cdbc3dSStefano Zampini #undef __FUNCT__ 68782ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal_BDDC" 68882ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries) 6890c7d97c5SJed Brown { 6900c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 69156282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 6920c7d97c5SJed Brown PetscErrorCode ierr; 6930c7d97c5SJed Brown 6940c7d97c5SJed Brown PetscFunctionBegin; 69556282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 69656282151SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 69756282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundariesLocal,&isequal);CHKERRQ(ierr); 69856282151SStefano Zampini } 699785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 700785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 7010c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 702785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = NeumannBoundaries; 70356282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 7040c7d97c5SJed Brown PetscFunctionReturn(0); 7050c7d97c5SJed Brown } 7060c7d97c5SJed Brown 7070c7d97c5SJed Brown #undef __FUNCT__ 70882ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal" 7090c7d97c5SJed Brown /*@ 71082ba6b80SStefano Zampini PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering. 7110c7d97c5SJed Brown 712785d1243SStefano Zampini Collective 7130c7d97c5SJed Brown 7140c7d97c5SJed Brown Input Parameters: 7150c7d97c5SJed Brown + pc - the preconditioning context 71682ba6b80SStefano Zampini - NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering) 7170c7d97c5SJed Brown 7180c7d97c5SJed Brown Level: intermediate 7190c7d97c5SJed Brown 7200c7d97c5SJed Brown Notes: 7210c7d97c5SJed Brown 7220f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundaries() 7230c7d97c5SJed Brown @*/ 72482ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries) 7250c7d97c5SJed Brown { 7260c7d97c5SJed Brown PetscErrorCode ierr; 7270c7d97c5SJed Brown 7280c7d97c5SJed Brown PetscFunctionBegin; 7290c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 7300c7d97c5SJed Brown PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 73182ba6b80SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 73282ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 73353cdbc3dSStefano Zampini PetscFunctionReturn(0); 73453cdbc3dSStefano Zampini } 73553cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 73653cdbc3dSStefano Zampini 73753cdbc3dSStefano Zampini #undef __FUNCT__ 738da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC" 739da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 740da1bb401SStefano Zampini { 741da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 742da1bb401SStefano Zampini 743da1bb401SStefano Zampini PetscFunctionBegin; 744da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 745da1bb401SStefano Zampini PetscFunctionReturn(0); 746da1bb401SStefano Zampini } 7471e6b0712SBarry Smith 748da1bb401SStefano Zampini #undef __FUNCT__ 749da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries" 750da1bb401SStefano Zampini /*@ 751785d1243SStefano Zampini PCBDDCGetDirichletBoundaries - Get parallel IS for Dirichlet boundaries 752da1bb401SStefano Zampini 753785d1243SStefano Zampini Collective 754785d1243SStefano Zampini 755785d1243SStefano Zampini Input Parameters: 756785d1243SStefano Zampini . pc - the preconditioning context 757785d1243SStefano Zampini 758785d1243SStefano Zampini Output Parameters: 759785d1243SStefano Zampini . DirichletBoundaries - index set defining the Dirichlet boundaries 760785d1243SStefano Zampini 761785d1243SStefano Zampini Level: intermediate 762785d1243SStefano Zampini 7630f202f7eSStefano Zampini Notes: 7640f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetDirichletBoundaries 765785d1243SStefano Zampini 766785d1243SStefano Zampini .seealso: PCBDDC 767785d1243SStefano Zampini @*/ 768785d1243SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 769785d1243SStefano Zampini { 770785d1243SStefano Zampini PetscErrorCode ierr; 771785d1243SStefano Zampini 772785d1243SStefano Zampini PetscFunctionBegin; 773785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 774785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 775785d1243SStefano Zampini PetscFunctionReturn(0); 776785d1243SStefano Zampini } 777785d1243SStefano Zampini /* -------------------------------------------------------------------------- */ 778785d1243SStefano Zampini 779785d1243SStefano Zampini #undef __FUNCT__ 780785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal_BDDC" 781785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries) 782785d1243SStefano Zampini { 783785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 784785d1243SStefano Zampini 785785d1243SStefano Zampini PetscFunctionBegin; 786785d1243SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundariesLocal; 787785d1243SStefano Zampini PetscFunctionReturn(0); 788785d1243SStefano Zampini } 789785d1243SStefano Zampini 790785d1243SStefano Zampini #undef __FUNCT__ 79182ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal" 792da1bb401SStefano Zampini /*@ 79382ba6b80SStefano Zampini PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering) 794da1bb401SStefano Zampini 795785d1243SStefano Zampini Collective 796da1bb401SStefano Zampini 797da1bb401SStefano Zampini Input Parameters: 79828509bceSStefano Zampini . pc - the preconditioning context 799da1bb401SStefano Zampini 800da1bb401SStefano Zampini Output Parameters: 80128509bceSStefano Zampini . DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 802da1bb401SStefano Zampini 803da1bb401SStefano Zampini Level: intermediate 804da1bb401SStefano Zampini 805da1bb401SStefano Zampini Notes: 8060f202f7eSStefano 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). 8070f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 808da1bb401SStefano Zampini 809da1bb401SStefano Zampini .seealso: PCBDDC 810da1bb401SStefano Zampini @*/ 81182ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries) 812da1bb401SStefano Zampini { 813da1bb401SStefano Zampini PetscErrorCode ierr; 814da1bb401SStefano Zampini 815da1bb401SStefano Zampini PetscFunctionBegin; 816da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 81782ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 818da1bb401SStefano Zampini PetscFunctionReturn(0); 819da1bb401SStefano Zampini } 820da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 8211e6b0712SBarry Smith 822da1bb401SStefano Zampini #undef __FUNCT__ 82353cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 82453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 82553cdbc3dSStefano Zampini { 82653cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 82753cdbc3dSStefano Zampini 82853cdbc3dSStefano Zampini PetscFunctionBegin; 82953cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 83053cdbc3dSStefano Zampini PetscFunctionReturn(0); 83153cdbc3dSStefano Zampini } 8321e6b0712SBarry Smith 83353cdbc3dSStefano Zampini #undef __FUNCT__ 83453cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 83553cdbc3dSStefano Zampini /*@ 836785d1243SStefano Zampini PCBDDCGetNeumannBoundaries - Get parallel IS for Neumann boundaries 83753cdbc3dSStefano Zampini 838785d1243SStefano Zampini Collective 839785d1243SStefano Zampini 840785d1243SStefano Zampini Input Parameters: 841785d1243SStefano Zampini . pc - the preconditioning context 842785d1243SStefano Zampini 843785d1243SStefano Zampini Output Parameters: 844785d1243SStefano Zampini . NeumannBoundaries - index set defining the Neumann boundaries 845785d1243SStefano Zampini 846785d1243SStefano Zampini Level: intermediate 847785d1243SStefano Zampini 8480f202f7eSStefano Zampini Notes: 8490f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetNeumannBoundaries 850785d1243SStefano Zampini 851785d1243SStefano Zampini .seealso: PCBDDC 852785d1243SStefano Zampini @*/ 853785d1243SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 854785d1243SStefano Zampini { 855785d1243SStefano Zampini PetscErrorCode ierr; 856785d1243SStefano Zampini 857785d1243SStefano Zampini PetscFunctionBegin; 858785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 859785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 860785d1243SStefano Zampini PetscFunctionReturn(0); 861785d1243SStefano Zampini } 862785d1243SStefano Zampini /* -------------------------------------------------------------------------- */ 863785d1243SStefano Zampini 864785d1243SStefano Zampini #undef __FUNCT__ 865785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal_BDDC" 866785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries) 867785d1243SStefano Zampini { 868785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 869785d1243SStefano Zampini 870785d1243SStefano Zampini PetscFunctionBegin; 871785d1243SStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundariesLocal; 872785d1243SStefano Zampini PetscFunctionReturn(0); 873785d1243SStefano Zampini } 874785d1243SStefano Zampini 875785d1243SStefano Zampini #undef __FUNCT__ 87682ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal" 87753cdbc3dSStefano Zampini /*@ 87882ba6b80SStefano Zampini PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering) 87953cdbc3dSStefano Zampini 880785d1243SStefano Zampini Collective 88153cdbc3dSStefano Zampini 88253cdbc3dSStefano Zampini Input Parameters: 88328509bceSStefano Zampini . pc - the preconditioning context 88453cdbc3dSStefano Zampini 88553cdbc3dSStefano Zampini Output Parameters: 88628509bceSStefano Zampini . NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 88753cdbc3dSStefano Zampini 88853cdbc3dSStefano Zampini Level: intermediate 88953cdbc3dSStefano Zampini 89053cdbc3dSStefano Zampini Notes: 8910f202f7eSStefano 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). 8920f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 89353cdbc3dSStefano Zampini 89453cdbc3dSStefano Zampini .seealso: PCBDDC 89553cdbc3dSStefano Zampini @*/ 89682ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries) 89753cdbc3dSStefano Zampini { 89853cdbc3dSStefano Zampini PetscErrorCode ierr; 89953cdbc3dSStefano Zampini 90053cdbc3dSStefano Zampini PetscFunctionBegin; 90153cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 90282ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 9030c7d97c5SJed Brown PetscFunctionReturn(0); 9040c7d97c5SJed Brown } 90536e030ebSStefano Zampini /* -------------------------------------------------------------------------- */ 9061e6b0712SBarry Smith 90736e030ebSStefano Zampini #undef __FUNCT__ 908da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC" 9091a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 91036e030ebSStefano Zampini { 91136e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 912da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 91356282151SStefano Zampini PetscBool same_data = PETSC_FALSE; 914da1bb401SStefano Zampini PetscErrorCode ierr; 91536e030ebSStefano Zampini 91636e030ebSStefano Zampini PetscFunctionBegin; 9178687889aSStefano Zampini if (!nvtxs) { 9188687889aSStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 9198687889aSStefano Zampini PetscFunctionReturn(0); 9208687889aSStefano Zampini } 92156282151SStefano Zampini if (mat_graph->nvtxs_csr == nvtxs) { 92256282151SStefano Zampini if (mat_graph->xadj == xadj && mat_graph->adjncy == adjncy) same_data = PETSC_TRUE; 92356282151SStefano Zampini if (!same_data && mat_graph->xadj[nvtxs] == xadj[nvtxs]) { 92456282151SStefano Zampini ierr = PetscMemcmp(adjncy,mat_graph->adjncy,nvtxs*sizeof(PetscInt),&same_data);CHKERRQ(ierr); 92556282151SStefano Zampini } 92656282151SStefano Zampini } 92756282151SStefano Zampini if (!same_data) { 928674ae819SStefano Zampini /* free old CSR */ 929674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 930674ae819SStefano Zampini /* get CSR into graph structure */ 931da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 932854ce69bSBarry Smith ierr = PetscMalloc1(nvtxs+1,&mat_graph->xadj);CHKERRQ(ierr); 933785e854fSJed Brown ierr = PetscMalloc1(xadj[nvtxs],&mat_graph->adjncy);CHKERRQ(ierr); 934674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 935674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 936da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 9371a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 9381a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 939674ae819SStefano Zampini } 940575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 94156282151SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 94256282151SStefano Zampini } 94336e030ebSStefano Zampini PetscFunctionReturn(0); 94436e030ebSStefano Zampini } 9451e6b0712SBarry Smith 94636e030ebSStefano Zampini #undef __FUNCT__ 947da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph" 94836e030ebSStefano Zampini /*@ 9490f202f7eSStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local matrix 95036e030ebSStefano Zampini 95136e030ebSStefano Zampini Not collective 95236e030ebSStefano Zampini 95336e030ebSStefano Zampini Input Parameters: 95436e030ebSStefano Zampini + pc - the preconditioning context 9550f202f7eSStefano Zampini . nvtxs - number of local vertices of the graph (i.e., the size of the local problem) 95628509bceSStefano Zampini . xadj, adjncy - the CSR graph 95728509bceSStefano Zampini - copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER. 95836e030ebSStefano Zampini 95936e030ebSStefano Zampini Level: intermediate 96036e030ebSStefano Zampini 96136e030ebSStefano Zampini Notes: 96236e030ebSStefano Zampini 96328509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode 96436e030ebSStefano Zampini @*/ 9651a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 96636e030ebSStefano Zampini { 967575ad6abSStefano Zampini void (*f)(void) = 0; 96836e030ebSStefano Zampini PetscErrorCode ierr; 96936e030ebSStefano Zampini 97036e030ebSStefano Zampini PetscFunctionBegin; 97136e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 9728687889aSStefano Zampini if (nvtxs) { 973674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 974d7de1dd9SStefano Zampini PetscValidIntPointer(adjncy,4); 9758687889aSStefano Zampini } 9766c4ed002SBarry Smith if (copymode != PETSC_COPY_VALUES && copymode != PETSC_OWN_POINTER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d",copymode); 9771a83f524SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 978575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 979575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 980575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 981575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 982575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 983da1bb401SStefano Zampini } 98436e030ebSStefano Zampini PetscFunctionReturn(0); 98536e030ebSStefano Zampini } 9869c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 9871e6b0712SBarry Smith 9889c0446d6SStefano Zampini #undef __FUNCT__ 98963602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal_BDDC" 99063602bcaSStefano Zampini static PetscErrorCode PCBDDCSetDofsSplittingLocal_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 99163602bcaSStefano Zampini { 99263602bcaSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 99363602bcaSStefano Zampini PetscInt i; 99456282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 99563602bcaSStefano Zampini PetscErrorCode ierr; 99663602bcaSStefano Zampini 99763602bcaSStefano Zampini PetscFunctionBegin; 99856282151SStefano Zampini if (pcbddc->n_ISForDofsLocal == n_is) { 99956282151SStefano Zampini for (i=0;i<n_is;i++) { 100056282151SStefano Zampini PetscBool isequalt; 100156282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofsLocal[i],&isequalt);CHKERRQ(ierr); 100256282151SStefano Zampini if (!isequalt) break; 100356282151SStefano Zampini } 100456282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 100556282151SStefano Zampini } 100656282151SStefano Zampini for (i=0;i<n_is;i++) { 100756282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 100856282151SStefano Zampini } 100963602bcaSStefano Zampini /* Destroy ISes if they were already set */ 101063602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 101163602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 101263602bcaSStefano Zampini } 101363602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 101463602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 101563602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 101663602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 101763602bcaSStefano Zampini } 101863602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 101963602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 102063602bcaSStefano Zampini /* allocate space then set */ 1021d02579f5SStefano Zampini if (n_is) { 1022d02579f5SStefano Zampini ierr = PetscMalloc1(n_is,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1023d02579f5SStefano Zampini } 102463602bcaSStefano Zampini for (i=0;i<n_is;i++) { 102563602bcaSStefano Zampini pcbddc->ISForDofsLocal[i] = ISForDofs[i]; 102663602bcaSStefano Zampini } 102763602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = n_is; 102863602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 102956282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 103063602bcaSStefano Zampini PetscFunctionReturn(0); 103163602bcaSStefano Zampini } 103263602bcaSStefano Zampini 103363602bcaSStefano Zampini #undef __FUNCT__ 103463602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal" 103563602bcaSStefano Zampini /*@ 103663602bcaSStefano Zampini PCBDDCSetDofsSplittingLocal - Set index sets defining fields of the local subdomain matrix 103763602bcaSStefano Zampini 103863602bcaSStefano Zampini Collective 103963602bcaSStefano Zampini 104063602bcaSStefano Zampini Input Parameters: 104163602bcaSStefano Zampini + pc - the preconditioning context 10420f202f7eSStefano Zampini . n_is - number of index sets defining the fields 10430f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in local ordering 104463602bcaSStefano Zampini 104563602bcaSStefano Zampini Level: intermediate 104663602bcaSStefano Zampini 10470f202f7eSStefano Zampini Notes: 10480f202f7eSStefano Zampini n_is should be the same among processes. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 104963602bcaSStefano Zampini 105063602bcaSStefano Zampini .seealso: PCBDDC 105163602bcaSStefano Zampini @*/ 105263602bcaSStefano Zampini PetscErrorCode PCBDDCSetDofsSplittingLocal(PC pc,PetscInt n_is, IS ISForDofs[]) 105363602bcaSStefano Zampini { 105463602bcaSStefano Zampini PetscInt i; 105563602bcaSStefano Zampini PetscErrorCode ierr; 105663602bcaSStefano Zampini 105763602bcaSStefano Zampini PetscFunctionBegin; 105863602bcaSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 105963602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 106063602bcaSStefano Zampini for (i=0;i<n_is;i++) { 106163602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 106263602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 106363602bcaSStefano Zampini } 1064e71e7a71SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplittingLocal_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 106563602bcaSStefano Zampini PetscFunctionReturn(0); 106663602bcaSStefano Zampini } 106763602bcaSStefano Zampini /* -------------------------------------------------------------------------- */ 106863602bcaSStefano Zampini 106963602bcaSStefano Zampini #undef __FUNCT__ 10709c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 10719c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 10729c0446d6SStefano Zampini { 10739c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 10749c0446d6SStefano Zampini PetscInt i; 107556282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 10769c0446d6SStefano Zampini PetscErrorCode ierr; 10779c0446d6SStefano Zampini 10789c0446d6SStefano Zampini PetscFunctionBegin; 107956282151SStefano Zampini if (pcbddc->n_ISForDofs == n_is) { 108056282151SStefano Zampini for (i=0;i<n_is;i++) { 108156282151SStefano Zampini PetscBool isequalt; 108256282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofs[i],&isequalt);CHKERRQ(ierr); 108356282151SStefano Zampini if (!isequalt) break; 108456282151SStefano Zampini } 108556282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 108656282151SStefano Zampini } 108756282151SStefano Zampini for (i=0;i<n_is;i++) { 108856282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 108956282151SStefano Zampini } 1090da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 10919c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 10929c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 10939c0446d6SStefano Zampini } 1094d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 109563602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 109663602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 109763602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 109863602bcaSStefano Zampini } 109963602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 110063602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 1101da1bb401SStefano Zampini /* allocate space then set */ 1102d02579f5SStefano Zampini if (n_is) { 1103785e854fSJed Brown ierr = PetscMalloc1(n_is,&pcbddc->ISForDofs);CHKERRQ(ierr); 1104d02579f5SStefano Zampini } 11059c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 1106da1bb401SStefano Zampini pcbddc->ISForDofs[i] = ISForDofs[i]; 11079c0446d6SStefano Zampini } 11089c0446d6SStefano Zampini pcbddc->n_ISForDofs = n_is; 110963602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 111056282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 11119c0446d6SStefano Zampini PetscFunctionReturn(0); 11129c0446d6SStefano Zampini } 11131e6b0712SBarry Smith 11149c0446d6SStefano Zampini #undef __FUNCT__ 11159c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 11169c0446d6SStefano Zampini /*@ 111763602bcaSStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of the global matrix 11189c0446d6SStefano Zampini 111963602bcaSStefano Zampini Collective 11209c0446d6SStefano Zampini 11219c0446d6SStefano Zampini Input Parameters: 11229c0446d6SStefano Zampini + pc - the preconditioning context 11230f202f7eSStefano Zampini . n_is - number of index sets defining the fields 11240f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in global ordering 11259c0446d6SStefano Zampini 11269c0446d6SStefano Zampini Level: intermediate 11279c0446d6SStefano Zampini 11280f202f7eSStefano Zampini Notes: 11290f202f7eSStefano Zampini Any process can list any global node. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 11309c0446d6SStefano Zampini 11319c0446d6SStefano Zampini .seealso: PCBDDC 11329c0446d6SStefano Zampini @*/ 11339c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 11349c0446d6SStefano Zampini { 11352b510759SStefano Zampini PetscInt i; 11369c0446d6SStefano Zampini PetscErrorCode ierr; 11379c0446d6SStefano Zampini 11389c0446d6SStefano Zampini PetscFunctionBegin; 11399c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 114063602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 11412b510759SStefano Zampini for (i=0;i<n_is;i++) { 114263602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 114363602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 11442b510759SStefano Zampini } 11459c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 11469c0446d6SStefano Zampini PetscFunctionReturn(0); 11479c0446d6SStefano Zampini } 1148906d46d4SStefano Zampini 1149da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 1150534831adSStefano Zampini #undef __FUNCT__ 1151534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC" 1152534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 1153534831adSStefano Zampini /* 1154534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 1155534831adSStefano Zampini guess if a transformation of basis approach has been selected. 11569c0446d6SStefano Zampini 1157534831adSStefano Zampini Input Parameter: 1158534831adSStefano Zampini + pc - the preconditioner contex 1159534831adSStefano Zampini 1160534831adSStefano Zampini Application Interface Routine: PCPreSolve() 1161534831adSStefano Zampini 1162534831adSStefano Zampini Notes: 1163534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 1164534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1165534831adSStefano Zampini */ 1166534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1167534831adSStefano Zampini { 1168534831adSStefano Zampini PetscErrorCode ierr; 1169534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1170534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 11713972b0daSStefano Zampini Vec used_vec; 11728d00608fSStefano Zampini PetscBool copy_rhs = PETSC_TRUE; 1173a3df083aSStefano Zampini PetscBool iscg = PETSC_FALSE; 1174534831adSStefano Zampini 1175534831adSStefano Zampini PetscFunctionBegin; 117685c4d303SStefano Zampini /* if we are working with cg, one dirichlet solve can be avoided during Krylov iterations */ 117785c4d303SStefano Zampini if (ksp) { 117885c4d303SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr); 117916909a7fSStefano Zampini if (!iscg || pcbddc->switch_static) { 118085c4d303SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 118185c4d303SStefano Zampini } 118285c4d303SStefano Zampini } 118385c4d303SStefano Zampini /* Creates parallel work vectors used in presolve */ 118462a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 118562a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 118662a6ff1dSStefano Zampini } 118762a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 118862a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 118962a6ff1dSStefano Zampini } 11908d00608fSStefano Zampini 11911dd7afcfSStefano Zampini ierr = VecSet(pcbddc->temp_solution,0.);CHKERRQ(ierr); 11923972b0daSStefano Zampini if (x) { 11933972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 11943972b0daSStefano Zampini used_vec = x; 11958d00608fSStefano Zampini } else { /* it can only happen when calling PCBDDCMatFETIDPGetRHS */ 11963972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 11973972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 11983972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 11993972b0daSStefano Zampini } 12008efcfb23SStefano Zampini 12018efcfb23SStefano Zampini /* hack into ksp data structure since PCPreSolve comes earlier than setting to zero the guess in src/ksp/ksp/interface/itfunc.c */ 12023972b0daSStefano Zampini if (ksp) { 1203a0cb1b98SStefano Zampini /* store the flag for the initial guess since it will be restored back during PCPostSolve_BDDC */ 12048efcfb23SStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 12058efcfb23SStefano Zampini if (!pcbddc->ksp_guess_nonzero) { 12063972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 12073972b0daSStefano Zampini } 12083972b0daSStefano Zampini } 12093308cffdSStefano Zampini 12108d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 12113972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 121270c64980SStefano Zampini if (rhs && pcbddc->eliminate_dirdofs) { 12133975b054SStefano Zampini IS dirIS = NULL; 12143975b054SStefano Zampini 1215a07ea27aSStefano Zampini /* DirichletBoundariesLocal may not be consistent among neighbours; gets a dirichlet dofs IS from graph (may be cached) */ 12163975b054SStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 12173975b054SStefano Zampini if (dirIS) { 1218906d46d4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1219785d1243SStefano Zampini PetscInt dirsize,i,*is_indices; 12202b095fd8SStefano Zampini PetscScalar *array_x; 12212b095fd8SStefano Zampini const PetscScalar *array_diagonal; 1222785d1243SStefano Zampini 12233972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 12243972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 1225e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1226e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1227e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1228e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 122982ba6b80SStefano Zampini ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr); 12303972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 12312b095fd8SStefano Zampini ierr = VecGetArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 12323972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 12332fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 12343972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 12352b095fd8SStefano Zampini ierr = VecRestoreArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 12363972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 1237e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1238e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 12398d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 12401b968477SStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 12418efcfb23SStefano Zampini } 1242a07ea27aSStefano Zampini } 1243b76ba322SStefano Zampini 12448efcfb23SStefano Zampini /* remove the computed solution or the initial guess from the rhs */ 12458d00608fSStefano Zampini if (pcbddc->rhs_change || (ksp && pcbddc->ksp_guess_nonzero) ) { 12468d00608fSStefano Zampini /* store the original rhs */ 12478d00608fSStefano Zampini if (copy_rhs) { 12488d00608fSStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 12498d00608fSStefano Zampini copy_rhs = PETSC_FALSE; 12508d00608fSStefano Zampini } 12518d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 12523972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 12530369aaf7SStefano Zampini ierr = MatMultAdd(pc->mat,used_vec,rhs,rhs);CHKERRQ(ierr); 12543972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 12558efcfb23SStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 12567acc28cbSStefano Zampini if (ksp) { 12577acc28cbSStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_FALSE);CHKERRQ(ierr); 12587acc28cbSStefano Zampini } 12593308cffdSStefano Zampini } 12608efcfb23SStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 1261b76ba322SStefano Zampini 12621dd7afcfSStefano Zampini /* compute initial vector in benign space (TODO: what about FETI-DP?)*/ 12630369aaf7SStefano Zampini if (rhs && pcbddc->benign_saddle_point) { 12640369aaf7SStefano Zampini /* compute u^*_h as in Xuemin Tu's thesis (see Section 4.8.1) */ 12650369aaf7SStefano Zampini if (!pcbddc->benign_vec) { 12660369aaf7SStefano Zampini ierr = VecDuplicate(rhs,&pcbddc->benign_vec);CHKERRQ(ierr); 12670369aaf7SStefano Zampini } 12684fee134fSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_TRUE; 12691dd7afcfSStefano Zampini ierr = PCApply_BDDC(pc,rhs,pcbddc->benign_vec);CHKERRQ(ierr); 12704fee134fSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_FALSE; 12711dd7afcfSStefano Zampini /* TODO: what about Stokes? */ 12721dd7afcfSStefano Zampini #if 0 12731dd7afcfSStefano Zampini ierr = VecNorm(pcbddc->benign_vec,NORM_INFINITY,&norm);CHKERRQ(ierr); 12741dd7afcfSStefano Zampini if (norm < PETSC_SMALL) benign_correction_is_zero = PETSC_TRUE; 12751dd7afcfSStefano Zampini #endif 127692e3dcfbSStefano Zampini } 127792e3dcfbSStefano Zampini 12780369aaf7SStefano Zampini /* remove non-benign solution from the rhs */ 12790369aaf7SStefano Zampini if (pcbddc->benign_saddle_point) { 12800369aaf7SStefano Zampini /* store the original rhs */ 12810369aaf7SStefano Zampini if (copy_rhs) { 12820369aaf7SStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 12830369aaf7SStefano Zampini copy_rhs = PETSC_FALSE; 12840369aaf7SStefano Zampini } 12851dd7afcfSStefano Zampini /* this code is disabled, until I test against incompressible Stokes */ 12861dd7afcfSStefano Zampini #if 0 128751694757SStefano Zampini if (benign_correction_is_zero) { /* still need to understand why it works great */ 128851694757SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 128951694757SStefano Zampini ierr = PCApply_BDDC(pc,rhs,pcbddc->benign_vec);CHKERRQ(ierr); 129051694757SStefano Zampini } 12911dd7afcfSStefano Zampini #endif 12920369aaf7SStefano Zampini ierr = VecScale(pcbddc->benign_vec,-1.0);CHKERRQ(ierr); 12930369aaf7SStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,rhs,rhs);CHKERRQ(ierr); 12940369aaf7SStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 12951dd7afcfSStefano Zampini ierr = VecAXPY(pcbddc->temp_solution,-1.0,pcbddc->benign_vec);CHKERRQ(ierr); 12960369aaf7SStefano Zampini } 12970369aaf7SStefano Zampini 12980369aaf7SStefano Zampini /* set initial guess if using PCG */ 12990369aaf7SStefano Zampini if (x && pcbddc->use_exact_dirichlet_trick) { 13000369aaf7SStefano Zampini ierr = VecSet(x,0.0);CHKERRQ(ierr); 13011dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 13021dd7afcfSStefano Zampini if (pcbddc->benign_saddle_point) { /* we have already saved the changed rhs */ 13031dd7afcfSStefano Zampini ierr = VecLockPop(pcis->vec1_global);CHKERRQ(ierr); 13041dd7afcfSStefano Zampini } else { 13051dd7afcfSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,rhs,pcis->vec1_global);CHKERRQ(ierr); 13061dd7afcfSStefano Zampini } 13071dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13081dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec1_global,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13091dd7afcfSStefano Zampini } else { 13100369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13110369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13121dd7afcfSStefano Zampini } 13130369aaf7SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 13141dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && pcbddc->change_interior) { 13151dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.);CHKERRQ(ierr); 13161dd7afcfSStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13171dd7afcfSStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13181dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x);CHKERRQ(ierr); 13191dd7afcfSStefano Zampini } else { 13200369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13210369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13221dd7afcfSStefano Zampini } 13230369aaf7SStefano Zampini if (ksp) { 13240369aaf7SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 13250369aaf7SStefano Zampini } 13260369aaf7SStefano Zampini } 1327534831adSStefano Zampini PetscFunctionReturn(0); 1328534831adSStefano Zampini } 1329906d46d4SStefano Zampini 1330534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 1331534831adSStefano Zampini #undef __FUNCT__ 1332534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC" 1333534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 1334534831adSStefano Zampini /* 1335534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 1336534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 1337534831adSStefano Zampini 1338534831adSStefano Zampini Input Parameter: 1339534831adSStefano Zampini + pc - the preconditioner contex 1340534831adSStefano Zampini 1341534831adSStefano Zampini Application Interface Routine: PCPostSolve() 1342534831adSStefano Zampini 1343534831adSStefano Zampini Notes: 1344534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 1345534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1346534831adSStefano Zampini */ 1347534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1348534831adSStefano Zampini { 1349534831adSStefano Zampini PetscErrorCode ierr; 1350534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1351534831adSStefano Zampini 1352534831adSStefano Zampini PetscFunctionBegin; 13533972b0daSStefano Zampini /* add solution removed in presolve */ 13546bcfc461SStefano Zampini if (x && pcbddc->rhs_change) { 13553425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 13563425bc38SStefano Zampini } 1357fb223d50SStefano Zampini /* restore rhs to its original state */ 13588d00608fSStefano Zampini if (rhs && pcbddc->rhs_change) { 1359fb223d50SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,rhs);CHKERRQ(ierr); 1360fb223d50SStefano Zampini } 13618d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 13628efcfb23SStefano Zampini /* restore ksp guess state */ 13638efcfb23SStefano Zampini if (ksp) { 13648efcfb23SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 13658efcfb23SStefano Zampini } 1366534831adSStefano Zampini PetscFunctionReturn(0); 1367534831adSStefano Zampini } 1368534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 136953cdbc3dSStefano Zampini #undef __FUNCT__ 137053cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 13710c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 13720c7d97c5SJed Brown /* 13730c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 13740c7d97c5SJed Brown by setting data structures and options. 13750c7d97c5SJed Brown 13760c7d97c5SJed Brown Input Parameter: 137753cdbc3dSStefano Zampini + pc - the preconditioner context 13780c7d97c5SJed Brown 13790c7d97c5SJed Brown Application Interface Routine: PCSetUp() 13800c7d97c5SJed Brown 13810c7d97c5SJed Brown Notes: 13820c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 13830c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 13840c7d97c5SJed Brown */ 138553cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 13860c7d97c5SJed Brown { 13870c7d97c5SJed Brown PetscErrorCode ierr; 13880c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 13895e8657edSStefano Zampini Mat_IS* matis; 139008122e43SStefano Zampini MatNullSpace nearnullspace; 1391c9ed8603SStefano Zampini IS zerodiag = NULL; 139291e8d312SStefano Zampini PetscInt nrows,ncols; 139308122e43SStefano Zampini PetscBool computetopography,computesolvers,computesubschurs; 13948de1fae6SStefano Zampini PetscBool computeconstraintsmatrix; 13955e8657edSStefano Zampini PetscBool new_nearnullspace_provided,ismatis; 13960c7d97c5SJed Brown 13970c7d97c5SJed Brown PetscFunctionBegin; 13985e8657edSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATIS,&ismatis);CHKERRQ(ierr); 13996c4ed002SBarry Smith if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner requires matrix of type MATIS"); 140091e8d312SStefano Zampini ierr = MatGetSize(pc->pmat,&nrows,&ncols);CHKERRQ(ierr); 14016c4ed002SBarry Smith if (nrows != ncols) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PCBDDC preconditioner requires a square preconditioning matrix"); 14025e8657edSStefano Zampini matis = (Mat_IS*)pc->pmat->data; 1403f4ddd8eeSStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other future nonoverlapping preconditioners */ 14043b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 1405fcd409f5SStefano Zampini Also, BDDC directly build the Dirichlet problem */ 1406f4ddd8eeSStefano Zampini /* split work */ 1407674ae819SStefano Zampini if (pc->setupcalled) { 1408d1e9a80fSBarry Smith if (pc->flag == SAME_NONZERO_PATTERN) { 1409674ae819SStefano Zampini computetopography = PETSC_FALSE; 1410674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1411674ae819SStefano Zampini } else { /* DIFFERENT_NONZERO_PATTERN */ 1412674ae819SStefano Zampini computetopography = PETSC_TRUE; 1413674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1414674ae819SStefano Zampini } 1415674ae819SStefano Zampini } else { 1416674ae819SStefano Zampini computetopography = PETSC_TRUE; 1417674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1418674ae819SStefano Zampini } 1419fb180af4SStefano Zampini if (pcbddc->recompute_topography) { 1420fb180af4SStefano Zampini computetopography = PETSC_TRUE; 1421fb180af4SStefano Zampini } 142256282151SStefano Zampini pcbddc->recompute_topography = computetopography; 14238de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_FALSE; 1424b087196eSStefano Zampini 1425b087196eSStefano Zampini /* check parameters' compatibility */ 1426b7ab4a40SStefano Zampini if (!pcbddc->use_deluxe_scaling) pcbddc->deluxe_zerorows = PETSC_FALSE; 14279d54b7f4SStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_threshold > 0.0); 1428bf3a8328SStefano Zampini pcbddc->adaptive_userdefined = (PetscBool)(pcbddc->adaptive_selection && pcbddc->adaptive_userdefined); 1429862806e4SStefano Zampini if (pcbddc->adaptive_selection) pcbddc->use_faces = PETSC_TRUE; 1430862806e4SStefano Zampini 14315a95e1ceSStefano Zampini computesubschurs = (PetscBool)(pcbddc->adaptive_selection || pcbddc->use_deluxe_scaling); 143216909a7fSStefano Zampini if (pcbddc->switch_static) { 143316909a7fSStefano Zampini PetscBool ismatis; 143416909a7fSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->mat,MATIS,&ismatis);CHKERRQ(ierr); 143516909a7fSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"When the static switch is one, the iteration matrix should be of type MATIS"); 143616909a7fSStefano Zampini } 143716909a7fSStefano Zampini 1438f4ddd8eeSStefano Zampini /* Get stdout for dbg */ 143970cf5478SStefano Zampini if (pcbddc->dbg_flag) { 144070cf5478SStefano Zampini if (!pcbddc->dbg_viewer) { 144158a03d70SStefano Zampini pcbddc->dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pc)); 14421575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 1443f4ddd8eeSStefano Zampini } 144458a03d70SStefano Zampini ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1445f4ddd8eeSStefano Zampini } 1446f4ddd8eeSStefano Zampini 14475e8657edSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 14485e8657edSStefano Zampini /* use_change_of_basis flag is used to automatically compute a change of basis from constraints */ 14495e8657edSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 14505e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 14515e8657edSStefano Zampini } else { 1452b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 14535e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 14545e8657edSStefano Zampini pcbddc->local_mat = matis->A; 1455d16cbb6bSStefano Zampini } 1456d16cbb6bSStefano Zampini 14574f1b2e48SStefano Zampini /* detect local disconnected subdomains if requested and not done before */ 14584f1b2e48SStefano Zampini if (pcbddc->detect_disconnected && !pcbddc->n_local_subs) { 14594f1b2e48SStefano Zampini ierr = MatDetectDisconnectedComponents(pcbddc->local_mat,PETSC_FALSE,&pcbddc->n_local_subs,&pcbddc->local_subs);CHKERRQ(ierr); 14604f1b2e48SStefano Zampini } 14614f1b2e48SStefano Zampini 14624f1b2e48SStefano Zampini /* 14631dd7afcfSStefano Zampini Compute change of basis on local pressures (aka zerodiag dofs) 14644f1b2e48SStefano Zampini This should come earlier then PCISSetUp for extracting the correct subdomain matrices 14654f1b2e48SStefano Zampini */ 14661dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 1467d16cbb6bSStefano Zampini if (pcbddc->benign_saddle_point) { 14689f47a83aSStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 14699f47a83aSStefano Zampini 147005b28244SStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->use_change_of_basis || !computesubschurs) pcbddc->benign_change_explicit = PETSC_TRUE; 1471339f8db1SStefano Zampini /* detect local saddle point and change the basis in pcbddc->local_mat */ 1472339f8db1SStefano Zampini ierr = PCBDDCBenignDetectSaddlePoint(pc,&zerodiag);CHKERRQ(ierr); 1473a3df083aSStefano Zampini /* pop B0 mat from local mat */ 1474c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 14751dd7afcfSStefano Zampini /* give pcis a hint to not reuse submatrices during PCISCreate */ 14761dd7afcfSStefano Zampini if (pc->flag == SAME_NONZERO_PATTERN && pcis->reusesubmatrices == PETSC_TRUE) { 14771dd7afcfSStefano Zampini if (pcbddc->benign_n && (pcbddc->benign_change_explicit || pcbddc->dbg_flag)) { 14781dd7afcfSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 14791dd7afcfSStefano Zampini } else { 1480a3df083aSStefano Zampini pcis->reusesubmatrices = PETSC_TRUE; 14811dd7afcfSStefano Zampini } 1482a3df083aSStefano Zampini } else { 14839f47a83aSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 1484674ae819SStefano Zampini } 1485a3df083aSStefano Zampini } 1486f1a72664SStefano Zampini /* propagate relevant information */ 14874f1b2e48SStefano Zampini #if !defined(PETSC_USE_COMPLEX) /* workaround for reals */ 14883301b35fSStefano Zampini if (matis->A->symmetric_set) { 14893301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 14903301b35fSStefano Zampini } 1491e496cd5dSStefano Zampini #endif 149206a4e24aSStefano Zampini if (matis->A->symmetric_set) { 149306a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 149406a4e24aSStefano Zampini } 149506a4e24aSStefano Zampini if (matis->A->spd_set) { 149606a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SPD,matis->A->spd);CHKERRQ(ierr); 149706a4e24aSStefano Zampini } 1498e496cd5dSStefano Zampini 14995e8657edSStefano Zampini /* Set up all the "iterative substructuring" common block without computing solvers */ 15005e8657edSStefano Zampini { 15015e8657edSStefano Zampini Mat temp_mat; 15025e8657edSStefano Zampini 15035e8657edSStefano Zampini temp_mat = matis->A; 15045e8657edSStefano Zampini matis->A = pcbddc->local_mat; 15055e8657edSStefano Zampini ierr = PCISSetUp(pc,PETSC_FALSE);CHKERRQ(ierr); 15065e8657edSStefano Zampini pcbddc->local_mat = matis->A; 15075e8657edSStefano Zampini matis->A = temp_mat; 15085e8657edSStefano Zampini } 1509684f6988SStefano Zampini 151081d14e9dSStefano Zampini /* Analyze interface */ 1511674ae819SStefano Zampini if (computetopography) { 1512674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 15138de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1514674ae819SStefano Zampini } 1515fb8d54d4SStefano Zampini 15165408967cSStefano Zampini /* check existence of a divergence free extension, i.e. 15175408967cSStefano Zampini b(v_I,p_0) = 0 for all v_I (raise error if not). 15185408967cSStefano Zampini Also, check that PCBDDCBenignGetOrSetP0 works */ 15195408967cSStefano Zampini #if defined(PETSC_USE_DEBUG) 152009f581a4SStefano Zampini if (pcbddc->benign_saddle_point) { 15215408967cSStefano Zampini ierr = PCBDDCBenignCheck(pc,zerodiag);CHKERRQ(ierr); 152209f581a4SStefano Zampini } 15235408967cSStefano Zampini #endif 15244f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 152506f24817SStefano Zampini 1526b96c3477SStefano Zampini /* Setup local dirichlet solver ksp_D and sub_schurs solvers */ 1527684f6988SStefano Zampini if (computesolvers) { 1528d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 1529d5574798SStefano Zampini 1530d5574798SStefano Zampini if (computesubschurs && computetopography) { 153108122e43SStefano Zampini ierr = PCBDDCInitSubSchurs(pc);CHKERRQ(ierr); 1532b1b3d7a2SStefano Zampini } 15339d54b7f4SStefano Zampini /* SetUp Scaling operator (scaling matrices could be needed in SubSchursSetUp)*/ 15349d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) { 15359d54b7f4SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 15369d54b7f4SStefano Zampini } 1537df4d28bfSStefano Zampini if (sub_schurs->schur_explicit) { 15382070dbb6SStefano Zampini if (computesubschurs) { 153908122e43SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 15402070dbb6SStefano Zampini } 1541d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 1542d5574798SStefano Zampini } else { 1543d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 15442070dbb6SStefano Zampini if (computesubschurs) { 1545d5574798SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 1546d5574798SStefano Zampini } 15472070dbb6SStefano Zampini } 154808122e43SStefano Zampini if (pcbddc->adaptive_selection) { 154908122e43SStefano Zampini ierr = PCBDDCAdaptiveSelection(pc);CHKERRQ(ierr); 15508de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1551b7eb3628SStefano Zampini } 1552b1b3d7a2SStefano Zampini } 1553684f6988SStefano Zampini 1554f4ddd8eeSStefano Zampini /* infer if NullSpace object attached to Mat via MatSetNearNullSpace has changed */ 1555fb8d54d4SStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1556f4ddd8eeSStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullspace);CHKERRQ(ierr); 1557f4ddd8eeSStefano Zampini if (pcbddc->onearnullspace) { /* already used nearnullspace */ 1558f4ddd8eeSStefano Zampini if (!nearnullspace) { /* near null space attached to mat has been destroyed */ 1559f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1560f4ddd8eeSStefano Zampini } else { 1561f4ddd8eeSStefano Zampini /* determine if the two nullspaces are different (should be lightweight) */ 1562f4ddd8eeSStefano Zampini if (nearnullspace != pcbddc->onearnullspace) { 1563f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1564165b64e2SStefano Zampini } else { /* maybe the user has changed the content of the nearnullspace so check vectors ObjectStateId */ 1565f4ddd8eeSStefano Zampini PetscInt i; 1566165b64e2SStefano Zampini const Vec *nearnullvecs; 1567165b64e2SStefano Zampini PetscObjectState state; 1568165b64e2SStefano Zampini PetscInt nnsp_size; 1569165b64e2SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullspace,NULL,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1570f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1571f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&state);CHKERRQ(ierr); 1572165b64e2SStefano Zampini if (pcbddc->onearnullvecs_state[i] != state) { 1573f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1574f4ddd8eeSStefano Zampini break; 1575f4ddd8eeSStefano Zampini } 1576f4ddd8eeSStefano Zampini } 1577f4ddd8eeSStefano Zampini } 1578f4ddd8eeSStefano Zampini } 1579f4ddd8eeSStefano Zampini } else { 1580f4ddd8eeSStefano Zampini if (!nearnullspace) { /* both nearnullspaces are null */ 1581f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1582f4ddd8eeSStefano Zampini } else { /* nearnullspace attached later */ 1583f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1584f4ddd8eeSStefano Zampini } 1585f4ddd8eeSStefano Zampini } 1586f4ddd8eeSStefano Zampini 1587f4ddd8eeSStefano Zampini /* Setup constraints and related work vectors */ 1588727cdba6SStefano Zampini /* reset primal space flags */ 1589f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 1590727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 15918de1fae6SStefano Zampini if (computeconstraintsmatrix || new_nearnullspace_provided) { 1592727cdba6SStefano Zampini /* It also sets the primal space flags */ 1593674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 1594e7b262bdSStefano Zampini /* Allocate needed local vectors (which depends on quantities defined during ConstraintsSetUp) */ 1595f4ddd8eeSStefano Zampini ierr = PCBDDCSetUpLocalWorkVectors(pc);CHKERRQ(ierr); 15963975b054SStefano Zampini } 15975e8657edSStefano Zampini 15983975b054SStefano Zampini if (computesolvers || pcbddc->new_primal_space) { 15995e8657edSStefano Zampini if (pcbddc->use_change_of_basis) { 16005e8657edSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 16015e8657edSStefano Zampini 16025e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 16034f1b2e48SStefano Zampini if (pcbddc->benign_change) { 16041dd7afcfSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 1605c263805aSStefano Zampini /* pop B0 from pcbddc->local_mat */ 1606c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 1607c263805aSStefano Zampini } 16085e8657edSStefano Zampini /* get submatrices */ 16095e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 16105e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 16115e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 16125e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 16135e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 16145e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 16153975b054SStefano Zampini /* set flag in pcis to not reuse submatrices during PCISCreate */ 16163975b054SStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 16179c6a02ceSStefano Zampini } else if (!pcbddc->user_ChangeOfBasisMatrix && !pcbddc->benign_change) { 1618b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 16195e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 16205e8657edSStefano Zampini pcbddc->local_mat = matis->A; 16215e8657edSStefano Zampini } 1622b96c3477SStefano Zampini /* SetUp coarse and local Neumann solvers */ 162399cc7994SStefano Zampini ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr); 1624b96c3477SStefano Zampini /* SetUp Scaling operator */ 16259d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 1626674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 16270c7d97c5SJed Brown } 16289d54b7f4SStefano Zampini } 16291dd7afcfSStefano Zampini /* mark topography as done */ 163056282151SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 16310369aaf7SStefano Zampini 16321dd7afcfSStefano Zampini /* wrap pcis->A_IB and pcis->A_BI if we did not change explicitly the variables on the pressures */ 16331dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_FALSE);CHKERRQ(ierr); 16341dd7afcfSStefano Zampini 163558a03d70SStefano Zampini if (pcbddc->dbg_flag) { 163658a03d70SStefano Zampini ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 16372b510759SStefano Zampini } 16380c7d97c5SJed Brown PetscFunctionReturn(0); 16390c7d97c5SJed Brown } 16400c7d97c5SJed Brown 16410c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 16420c7d97c5SJed Brown /* 164350efa1b5SStefano Zampini PCApply_BDDC - Applies the BDDC operator to a vector. 16440c7d97c5SJed Brown 16450c7d97c5SJed Brown Input Parameters: 16460f202f7eSStefano Zampini + pc - the preconditioner context 16470f202f7eSStefano Zampini - r - input vector (global) 16480c7d97c5SJed Brown 16490c7d97c5SJed Brown Output Parameter: 16500c7d97c5SJed Brown . z - output vector (global) 16510c7d97c5SJed Brown 16520c7d97c5SJed Brown Application Interface Routine: PCApply() 16530c7d97c5SJed Brown */ 16540c7d97c5SJed Brown #undef __FUNCT__ 16550c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 165653cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 16570c7d97c5SJed Brown { 16580c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 16590c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1660b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 16610c7d97c5SJed Brown PetscErrorCode ierr; 16623b03a366Sstefano_zampini const PetscScalar one = 1.0; 16633b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 16642617d88aSStefano Zampini const PetscScalar zero = 0.0; 16650c7d97c5SJed Brown 16660c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 16670c7d97c5SJed Brown NN interface preconditioner changed to BDDC 1668b097fa66SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static == PETSC_TRUE) */ 16690c7d97c5SJed Brown 16700c7d97c5SJed Brown PetscFunctionBegin; 16711dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 16721dd7afcfSStefano Zampini Vec swap; 16731dd7afcfSStefano Zampini ierr = VecCopy(r,pcbddc->work_change);CHKERRQ(ierr); 16741dd7afcfSStefano Zampini swap = pcbddc->work_change; 16751dd7afcfSStefano Zampini pcbddc->work_change = r; 16761dd7afcfSStefano Zampini r = swap; 16771dd7afcfSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,r);CHKERRQ(ierr); 16781dd7afcfSStefano Zampini /* save rhs so that we don't need to apply the change of basis for the exact dirichlet trick in PreSolve */ 16791dd7afcfSStefano Zampini if (pcbddc->benign_apply_coarse_only && pcbddc->use_exact_dirichlet_trick && pcbddc->change_interior) { 16801dd7afcfSStefano Zampini ierr = VecCopy(r,pcis->vec1_global);CHKERRQ(ierr); 16811dd7afcfSStefano Zampini ierr = VecLockPush(pcis->vec1_global);CHKERRQ(ierr); 16821dd7afcfSStefano Zampini } 16831dd7afcfSStefano Zampini } 1684015636ebSStefano Zampini if (pcbddc->benign_saddle_point) { /* get p0 from r */ 1685015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1686efc2fbd9SStefano Zampini } 168785c4d303SStefano Zampini if (!pcbddc->use_exact_dirichlet_trick) { 1688b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 16890c7d97c5SJed Brown /* First Dirichlet solve */ 16900c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16910c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16920c7d97c5SJed Brown /* 16930c7d97c5SJed Brown Assembling right hand side for BDDC operator 1694b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 1695674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 16960c7d97c5SJed Brown */ 1697b097fa66SStefano Zampini if (n_D) { 1698b097fa66SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 16990c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 170016909a7fSStefano Zampini if (pcbddc->switch_static) { 170116909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 170216909a7fSStefano Zampini 170316909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 170416909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 170516909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 170616909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 170716909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 170816909a7fSStefano Zampini } else { 170916909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 171016909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 171116909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 171216909a7fSStefano Zampini } 171316909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 171416909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 171516909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 171616909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 171716909a7fSStefano Zampini } else { 1718b097fa66SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 171916909a7fSStefano Zampini } 1720b097fa66SStefano Zampini } else { 1721b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1722b097fa66SStefano Zampini } 17230c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 17240c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1725674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 1726b76ba322SStefano Zampini } else { 17274fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 1728674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 1729b76ba322SStefano Zampini } 17304fee134fSStefano Zampini } 1731b76ba322SStefano Zampini 17322617d88aSStefano Zampini /* Apply interface preconditioner 17332617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1734dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 17352617d88aSStefano Zampini 1736674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 1737674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 17380c7d97c5SJed Brown 17393b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 17400c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17410c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1742b097fa66SStefano Zampini if (n_B) { 174316909a7fSStefano Zampini if (pcbddc->switch_static) { 174416909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 174516909a7fSStefano Zampini 174616909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 174716909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 174816909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 174916909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 175016909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 175116909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 175216909a7fSStefano Zampini } else { 175316909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 175416909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 175516909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 175616909a7fSStefano Zampini } 175716909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 175816909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 175916909a7fSStefano Zampini } else { 17600c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 176116909a7fSStefano Zampini } 176216909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 176316909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 176416909a7fSStefano Zampini 176516909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 176616909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 176716909a7fSStefano Zampini } else { 176816909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 176916909a7fSStefano Zampini ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 177016909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 177116909a7fSStefano Zampini } 1772b097fa66SStefano Zampini } 1773df187020SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 1774efc2fbd9SStefano Zampini 1775b097fa66SStefano Zampini if (!pcbddc->use_exact_dirichlet_trick) { 1776b097fa66SStefano Zampini if (pcbddc->switch_static) { 1777b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 1778b097fa66SStefano Zampini } else { 1779b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 1780b097fa66SStefano Zampini } 17810c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 17820c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1783b097fa66SStefano Zampini } else { 1784b097fa66SStefano Zampini if (pcbddc->switch_static) { 1785b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 1786b097fa66SStefano Zampini } else { 1787b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 1788b097fa66SStefano Zampini } 1789b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1790b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1791b097fa66SStefano Zampini } 1792efc2fbd9SStefano Zampini 1793015636ebSStefano Zampini if (pcbddc->benign_saddle_point) { /* set p0 (computed in PCBDDCApplyInterface) */ 17941dd7afcfSStefano Zampini if (pcbddc->benign_apply_coarse_only) { 17951dd7afcfSStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 17961dd7afcfSStefano Zampini } 1797015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 1798efc2fbd9SStefano Zampini } 17991dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 18001dd7afcfSStefano Zampini Vec swap; 18011dd7afcfSStefano Zampini 18021dd7afcfSStefano Zampini swap = r; 18031dd7afcfSStefano Zampini r = pcbddc->work_change; 18041dd7afcfSStefano Zampini pcbddc->work_change = swap; 18051dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 18061dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 18071dd7afcfSStefano Zampini } 18080c7d97c5SJed Brown PetscFunctionReturn(0); 18090c7d97c5SJed Brown } 181050efa1b5SStefano Zampini 181150efa1b5SStefano Zampini /* -------------------------------------------------------------------------- */ 181250efa1b5SStefano Zampini /* 181350efa1b5SStefano Zampini PCApplyTranspose_BDDC - Applies the transpose of the BDDC operator to a vector. 181450efa1b5SStefano Zampini 181550efa1b5SStefano Zampini Input Parameters: 18160f202f7eSStefano Zampini + pc - the preconditioner context 18170f202f7eSStefano Zampini - r - input vector (global) 181850efa1b5SStefano Zampini 181950efa1b5SStefano Zampini Output Parameter: 182050efa1b5SStefano Zampini . z - output vector (global) 182150efa1b5SStefano Zampini 182250efa1b5SStefano Zampini Application Interface Routine: PCApplyTranspose() 182350efa1b5SStefano Zampini */ 182450efa1b5SStefano Zampini #undef __FUNCT__ 182550efa1b5SStefano Zampini #define __FUNCT__ "PCApplyTranspose_BDDC" 182650efa1b5SStefano Zampini PetscErrorCode PCApplyTranspose_BDDC(PC pc,Vec r,Vec z) 182750efa1b5SStefano Zampini { 182850efa1b5SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 182950efa1b5SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1830b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 183150efa1b5SStefano Zampini PetscErrorCode ierr; 183250efa1b5SStefano Zampini const PetscScalar one = 1.0; 183350efa1b5SStefano Zampini const PetscScalar m_one = -1.0; 183450efa1b5SStefano Zampini const PetscScalar zero = 0.0; 183550efa1b5SStefano Zampini 183650efa1b5SStefano Zampini PetscFunctionBegin; 18371dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 18381dd7afcfSStefano Zampini Vec swap; 18391dd7afcfSStefano Zampini ierr = VecCopy(r,pcbddc->work_change);CHKERRQ(ierr); 18401dd7afcfSStefano Zampini swap = pcbddc->work_change; 18411dd7afcfSStefano Zampini pcbddc->work_change = r; 18421dd7afcfSStefano Zampini r = swap; 18431dd7afcfSStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,r);CHKERRQ(ierr); 18441dd7afcfSStefano Zampini } 1845537c1cdfSStefano Zampini if (pcbddc->benign_saddle_point) { /* get p0 from r */ 1846537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1847537c1cdfSStefano Zampini } 184850efa1b5SStefano Zampini if (!pcbddc->use_exact_dirichlet_trick) { 1849b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 185050efa1b5SStefano Zampini /* First Dirichlet solve */ 185150efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 185250efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 185350efa1b5SStefano Zampini /* 185450efa1b5SStefano Zampini Assembling right hand side for BDDC operator 1855b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 185650efa1b5SStefano Zampini - pcis->vec1_B the interface part of the global vector z 185750efa1b5SStefano Zampini */ 1858b097fa66SStefano Zampini if (n_D) { 1859b097fa66SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 186050efa1b5SStefano Zampini ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 186116909a7fSStefano Zampini if (pcbddc->switch_static) { 186216909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 186316909a7fSStefano Zampini 186416909a7fSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 186516909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 186616909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 186716909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 186816909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 186916909a7fSStefano Zampini } else { 187016909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 187116909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 187216909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 187316909a7fSStefano Zampini } 187416909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 187516909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec1_D,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 187616909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 187716909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec2_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 187816909a7fSStefano Zampini } else { 1879b097fa66SStefano Zampini ierr = MatMultTranspose(pcis->A_IB,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 188016909a7fSStefano Zampini } 1881b097fa66SStefano Zampini } else { 1882b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1883b097fa66SStefano Zampini } 188450efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 188550efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 188650efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 188750efa1b5SStefano Zampini } else { 188850efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 188950efa1b5SStefano Zampini } 189050efa1b5SStefano Zampini 189150efa1b5SStefano Zampini /* Apply interface preconditioner 189250efa1b5SStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1893dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_TRUE);CHKERRQ(ierr); 189450efa1b5SStefano Zampini 189550efa1b5SStefano Zampini /* Apply transpose of partition of unity operator */ 189650efa1b5SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 189750efa1b5SStefano Zampini 189850efa1b5SStefano Zampini /* Second Dirichlet solve and assembling of output */ 189950efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 190050efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1901b097fa66SStefano Zampini if (n_B) { 190216909a7fSStefano Zampini if (pcbddc->switch_static) { 190316909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 190416909a7fSStefano Zampini 190516909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 190616909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec1_D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 190716909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 190816909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 190916909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 191016909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 191116909a7fSStefano Zampini } else { 191216909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 191316909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec2_N,pcis->vec1_N);CHKERRQ(ierr); 191416909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 191516909a7fSStefano Zampini } 191616909a7fSStefano Zampini ierr = VecScatterBegin(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 191716909a7fSStefano Zampini ierr = VecScatterEnd(pcis->N_to_D,pcis->vec2_N,pcis->vec3_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 191816909a7fSStefano Zampini } else { 191950efa1b5SStefano Zampini ierr = MatMultTranspose(pcis->A_BI,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 192016909a7fSStefano Zampini } 192116909a7fSStefano Zampini } else if (pcbddc->switch_static) { /* n_B is zero */ 192216909a7fSStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 192316909a7fSStefano Zampini 192416909a7fSStefano Zampini if (!pcbddc->switch_static_change) { 192516909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 192616909a7fSStefano Zampini } else { 192716909a7fSStefano Zampini ierr = MatMult(pcbddc->switch_static_change,pcis->vec1_D,pcis->vec1_N);CHKERRQ(ierr); 192816909a7fSStefano Zampini ierr = MatMultTranspose(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 192916909a7fSStefano Zampini ierr = MatMultTranspose(pcbddc->switch_static_change,pcis->vec2_N,pcis->vec3_D);CHKERRQ(ierr); 193016909a7fSStefano Zampini } 1931b097fa66SStefano Zampini } 1932b0147a47SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 1933b097fa66SStefano Zampini if (!pcbddc->use_exact_dirichlet_trick) { 1934b097fa66SStefano Zampini if (pcbddc->switch_static) { 1935b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 1936b097fa66SStefano Zampini } else { 1937b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 1938b097fa66SStefano Zampini } 193950efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 194050efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1941b097fa66SStefano Zampini } else { 1942b097fa66SStefano Zampini if (pcbddc->switch_static) { 1943b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 1944b097fa66SStefano Zampini } else { 1945b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 1946b097fa66SStefano Zampini } 1947b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1948b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1949b097fa66SStefano Zampini } 1950537c1cdfSStefano Zampini if (pcbddc->benign_saddle_point) { /* set p0 (computed in PCBDDCApplyInterface) */ 1951537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 1952537c1cdfSStefano Zampini } 19531dd7afcfSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 19541dd7afcfSStefano Zampini Vec swap; 19551dd7afcfSStefano Zampini 19561dd7afcfSStefano Zampini swap = r; 19571dd7afcfSStefano Zampini r = pcbddc->work_change; 19581dd7afcfSStefano Zampini pcbddc->work_change = swap; 19591dd7afcfSStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 19601dd7afcfSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 19611dd7afcfSStefano Zampini } 196250efa1b5SStefano Zampini PetscFunctionReturn(0); 196350efa1b5SStefano Zampini } 1964da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 1965674ae819SStefano Zampini 1966da1bb401SStefano Zampini #undef __FUNCT__ 1967da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC" 1968da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 1969da1bb401SStefano Zampini { 1970da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1971da1bb401SStefano Zampini PetscErrorCode ierr; 1972da1bb401SStefano Zampini 1973da1bb401SStefano Zampini PetscFunctionBegin; 1974674ae819SStefano Zampini /* free BDDC custom data */ 1975674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 1976674ae819SStefano Zampini /* destroy objects related to topography */ 1977674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 1978674ae819SStefano Zampini /* free allocated graph structure */ 1979da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr); 1980b96c3477SStefano Zampini /* free allocated sub schurs structure */ 1981b96c3477SStefano Zampini ierr = PetscFree(pcbddc->sub_schurs);CHKERRQ(ierr); 198234a97f8cSStefano Zampini /* destroy objects for scaling operator */ 1983674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 198434a97f8cSStefano Zampini ierr = PetscFree(pcbddc->deluxe_ctx);CHKERRQ(ierr); 1985674ae819SStefano Zampini /* free solvers stuff */ 1986674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 198762a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 198862a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 198962a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 19901dd7afcfSStefano Zampini /* free data created by PCIS */ 19911dd7afcfSStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 19923425bc38SStefano Zampini /* remove functions */ 1993906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",NULL);CHKERRQ(ierr); 1994674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 199530368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",NULL);CHKERRQ(ierr); 1996bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 19972b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr); 1998b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr); 19992b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr); 2000bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",NULL);CHKERRQ(ierr); 2001bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 200282ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2003bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 200482ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2005bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 200682ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 2007bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 2008785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 2009bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 201063602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",NULL);CHKERRQ(ierr); 2011bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 2012bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 2013bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 2014bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 2015674ae819SStefano Zampini /* Free the private data structure */ 2016674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 2017da1bb401SStefano Zampini PetscFunctionReturn(0); 2018da1bb401SStefano Zampini } 20193425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 20201e6b0712SBarry Smith 20213425bc38SStefano Zampini #undef __FUNCT__ 20223425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC" 20233425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 20243425bc38SStefano Zampini { 2025674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 2026c08af4c6SStefano Zampini Vec copy_standard_rhs; 20273425bc38SStefano Zampini PC_IS* pcis; 20283425bc38SStefano Zampini PC_BDDC* pcbddc; 20293425bc38SStefano Zampini PetscErrorCode ierr; 20300c7d97c5SJed Brown 20313425bc38SStefano Zampini PetscFunctionBegin; 20323425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 20333425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 20343425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 20353425bc38SStefano Zampini 2036c08af4c6SStefano Zampini /* 2037c08af4c6SStefano Zampini change of basis for physical rhs if needed 2038c08af4c6SStefano Zampini It also changes the rhs in case of dirichlet boundaries 2039c08af4c6SStefano Zampini TODO: better management when FETIDP will have its own class 2040c08af4c6SStefano Zampini */ 2041c08af4c6SStefano Zampini ierr = VecDuplicate(standard_rhs,©_standard_rhs);CHKERRQ(ierr); 2042c08af4c6SStefano Zampini ierr = VecCopy(standard_rhs,copy_standard_rhs);CHKERRQ(ierr); 2043c08af4c6SStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,copy_standard_rhs,NULL);CHKERRQ(ierr); 20443425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 2045c08af4c6SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,copy_standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2046c08af4c6SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,copy_standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2047fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 2048fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 2049c08af4c6SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2050c08af4c6SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2051674ae819SStefano Zampini /* Apply partition of unity */ 20523425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 2053c08af4c6SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,copy_standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 20548eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 20553425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 20563425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 20573425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 20583425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 2059c08af4c6SStefano Zampini ierr = VecSet(copy_standard_rhs,0.0);CHKERRQ(ierr); 2060c08af4c6SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,copy_standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2061c08af4c6SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,copy_standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2062c08af4c6SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,copy_standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 2063c08af4c6SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2064c08af4c6SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20653425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 20663425bc38SStefano Zampini } 2067c08af4c6SStefano Zampini ierr = VecDestroy(©_standard_rhs);CHKERRQ(ierr); 20683425bc38SStefano Zampini /* BDDC rhs */ 20693425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 20708eeda7d8SStefano Zampini if (pcbddc->switch_static) { 20713425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 20723425bc38SStefano Zampini } 20733425bc38SStefano Zampini /* apply BDDC */ 2074dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 20753425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 20763425bc38SStefano Zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 20773425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 20783425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20793425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20803425bc38SStefano Zampini PetscFunctionReturn(0); 20813425bc38SStefano Zampini } 20821e6b0712SBarry Smith 20833425bc38SStefano Zampini #undef __FUNCT__ 20843425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS" 20853425bc38SStefano Zampini /*@ 20860f202f7eSStefano Zampini PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETI-DP linear system using the physical right-hand side 20873425bc38SStefano Zampini 20883425bc38SStefano Zampini Collective 20893425bc38SStefano Zampini 20903425bc38SStefano Zampini Input Parameters: 20910f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix object obtained by a call to PCBDDCCreateFETIDPOperators 20920f202f7eSStefano Zampini - standard_rhs - the right-hand side of the original linear system 20933425bc38SStefano Zampini 20943425bc38SStefano Zampini Output Parameters: 20950f202f7eSStefano Zampini . fetidp_flux_rhs - the right-hand side for the FETI-DP linear system 20963425bc38SStefano Zampini 20973425bc38SStefano Zampini Level: developer 20983425bc38SStefano Zampini 20993425bc38SStefano Zampini Notes: 21003425bc38SStefano Zampini 21010f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetSolution 21023425bc38SStefano Zampini @*/ 21033425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 21043425bc38SStefano Zampini { 2105674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 21063425bc38SStefano Zampini PetscErrorCode ierr; 21073425bc38SStefano Zampini 21083425bc38SStefano Zampini PetscFunctionBegin; 21093425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 21103425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 21113425bc38SStefano Zampini PetscFunctionReturn(0); 21123425bc38SStefano Zampini } 21133425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 21141e6b0712SBarry Smith 21153425bc38SStefano Zampini #undef __FUNCT__ 21163425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC" 21173425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 21183425bc38SStefano Zampini { 2119674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 21203425bc38SStefano Zampini PC_IS* pcis; 21213425bc38SStefano Zampini PC_BDDC* pcbddc; 21223425bc38SStefano Zampini PetscErrorCode ierr; 21233425bc38SStefano Zampini 21243425bc38SStefano Zampini PetscFunctionBegin; 21253425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 21263425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 21273425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 21283425bc38SStefano Zampini 21293425bc38SStefano Zampini /* apply B_delta^T */ 21303425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21313425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21323425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 21333425bc38SStefano Zampini /* compute rhs for BDDC application */ 21343425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 21358eeda7d8SStefano Zampini if (pcbddc->switch_static) { 21363425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 21373425bc38SStefano Zampini } 21383425bc38SStefano Zampini /* apply BDDC */ 2139dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 21403425bc38SStefano Zampini /* put values into standard global vector */ 21413425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21423425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21438eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 21443425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 21453425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 21463425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_D,-1.0,pcis->vec1_D);CHKERRQ(ierr); 21473425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 21483425bc38SStefano Zampini } 21493425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21503425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21513425bc38SStefano Zampini /* final change of basis if needed 21523425bc38SStefano Zampini Is also sums the dirichlet part removed during RHS assembling */ 21533308cffdSStefano Zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 21543425bc38SStefano Zampini PetscFunctionReturn(0); 21553425bc38SStefano Zampini } 21561e6b0712SBarry Smith 21573425bc38SStefano Zampini #undef __FUNCT__ 21583425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution" 21593425bc38SStefano Zampini /*@ 21600f202f7eSStefano Zampini PCBDDCMatFETIDPGetSolution - Compute the physical solution using the solution of the FETI-DP linear system 21613425bc38SStefano Zampini 21623425bc38SStefano Zampini Collective 21633425bc38SStefano Zampini 21643425bc38SStefano Zampini Input Parameters: 21650f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix obtained by a call to PCBDDCCreateFETIDPOperators 21660f202f7eSStefano Zampini - fetidp_flux_sol - the solution of the FETI-DP linear system 21673425bc38SStefano Zampini 21683425bc38SStefano Zampini Output Parameters: 21690f202f7eSStefano Zampini . standard_sol - the solution defined on the physical domain 21703425bc38SStefano Zampini 21713425bc38SStefano Zampini Level: developer 21723425bc38SStefano Zampini 21733425bc38SStefano Zampini Notes: 21743425bc38SStefano Zampini 21750f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetRHS 21763425bc38SStefano Zampini @*/ 21773425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 21783425bc38SStefano Zampini { 2179674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 21803425bc38SStefano Zampini PetscErrorCode ierr; 21813425bc38SStefano Zampini 21823425bc38SStefano Zampini PetscFunctionBegin; 21833425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 21843425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 21853425bc38SStefano Zampini PetscFunctionReturn(0); 21863425bc38SStefano Zampini } 21873425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 21881e6b0712SBarry Smith 2189f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec); 2190edf7251bSStefano Zampini extern PetscErrorCode FETIDPMatMultTranspose(Mat,Vec,Vec); 2191f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat); 2192f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec); 2193edf7251bSStefano Zampini extern PetscErrorCode FETIDPPCApplyTranspose(PC,Vec,Vec); 2194f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC); 2195674ae819SStefano Zampini 21963425bc38SStefano Zampini #undef __FUNCT__ 21973425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC" 21983425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 21993425bc38SStefano Zampini { 2200674ae819SStefano Zampini 2201674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 22023425bc38SStefano Zampini Mat newmat; 2203674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 22043425bc38SStefano Zampini PC newpc; 2205ce94432eSBarry Smith MPI_Comm comm; 22063425bc38SStefano Zampini PetscErrorCode ierr; 22073425bc38SStefano Zampini 22083425bc38SStefano Zampini PetscFunctionBegin; 2209ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 22103425bc38SStefano Zampini /* FETIDP linear matrix */ 22113425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 22123425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 22133425bc38SStefano Zampini ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 22143425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 2215edf7251bSStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT_TRANSPOSE,(void (*)(void))FETIDPMatMultTranspose);CHKERRQ(ierr); 22163425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 22173425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 22183425bc38SStefano Zampini /* FETIDP preconditioner */ 22193425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 22203425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 22213425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 22223425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 22233425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 22243425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 2225edf7251bSStefano Zampini ierr = PCShellSetApplyTranspose(newpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 22263425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 222723ee1639SBarry Smith ierr = PCSetOperators(newpc,newmat,newmat);CHKERRQ(ierr); 22283425bc38SStefano Zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 22293425bc38SStefano Zampini /* return pointers for objects created */ 22303425bc38SStefano Zampini *fetidp_mat=newmat; 22313425bc38SStefano Zampini *fetidp_pc=newpc; 22323425bc38SStefano Zampini PetscFunctionReturn(0); 22333425bc38SStefano Zampini } 22341e6b0712SBarry Smith 22353425bc38SStefano Zampini #undef __FUNCT__ 22363425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators" 22373425bc38SStefano Zampini /*@ 22380f202f7eSStefano Zampini PCBDDCCreateFETIDPOperators - Create FETI-DP operators 22393425bc38SStefano Zampini 22403425bc38SStefano Zampini Collective 22413425bc38SStefano Zampini 22423425bc38SStefano Zampini Input Parameters: 22430f202f7eSStefano Zampini . pc - the BDDC preconditioning context (setup should have been called before) 224428509bceSStefano Zampini 224528509bceSStefano Zampini Output Parameters: 22460f202f7eSStefano Zampini + fetidp_mat - shell FETI-DP matrix object 22470f202f7eSStefano Zampini - fetidp_pc - shell Dirichlet preconditioner for FETI-DP matrix 224828509bceSStefano Zampini 224928509bceSStefano Zampini Options Database Keys: 22500f202f7eSStefano Zampini . -fetidp_fullyredundant <false> - use or not a fully redundant set of Lagrange multipliers 22513425bc38SStefano Zampini 22523425bc38SStefano Zampini Level: developer 22533425bc38SStefano Zampini 22543425bc38SStefano Zampini Notes: 22550f202f7eSStefano Zampini Currently the only operations provided for FETI-DP matrix are MatMult and MatMultTranspose 22563425bc38SStefano Zampini 22570f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCMatFETIDPGetRHS, PCBDDCMatFETIDPGetSolution 22583425bc38SStefano Zampini @*/ 22593425bc38SStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 22603425bc38SStefano Zampini { 22613425bc38SStefano Zampini PetscErrorCode ierr; 22623425bc38SStefano Zampini 22633425bc38SStefano Zampini PetscFunctionBegin; 22643425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 22653425bc38SStefano Zampini if (pc->setupcalled) { 2266516d51a7SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,Mat*,PC*),(pc,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 2267f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n"); 22683425bc38SStefano Zampini PetscFunctionReturn(0); 22693425bc38SStefano Zampini } 22700c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2271da1bb401SStefano Zampini /*MC 2272da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 22730c7d97c5SJed Brown 227428509bceSStefano Zampini An implementation of the BDDC preconditioner based on 227528509bceSStefano Zampini 227628509bceSStefano Zampini .vb 227728509bceSStefano Zampini [1] C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 227828509bceSStefano 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 227928509bceSStefano Zampini [3] J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", http://arxiv.org/abs/0712.3977 22800f202f7eSStefano 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 228128509bceSStefano Zampini .ve 228228509bceSStefano Zampini 228328509bceSStefano Zampini The matrix to be preconditioned (Pmat) must be of type MATIS. 228428509bceSStefano Zampini 22850f202f7eSStefano Zampini Currently works with MATIS matrices with local matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers. 228628509bceSStefano Zampini 228728509bceSStefano Zampini It also works with unsymmetric and indefinite problems. 228828509bceSStefano Zampini 2289b6fdb6dfSStefano 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. 2290b6fdb6dfSStefano Zampini 22910f202f7eSStefano Zampini Approximate local solvers are automatically adapted for singular linear problems (see [1]) if the user has provided the nullspace using PCBDDCSetNullSpace() 229228509bceSStefano Zampini 22930f202f7eSStefano 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() 229430368db7SStefano Zampini Additional information on dofs can be provided by using PCBDDCSetDofsSplitting(), PCBDDCSetDirichletBoundaries(), PCBDDCSetNeumannBoundaries(), and PCBDDCSetPrimalVerticesIS() and their local counterparts. 229528509bceSStefano Zampini 22960f202f7eSStefano Zampini Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace(). Non-singular modes are retained via SVD. 229728509bceSStefano Zampini 22980f202f7eSStefano 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. 22990f202f7eSStefano Zampini User defined change of basis can be passed to PCBDDC by using PCBDDCSetChangeOfBasisMat() 230028509bceSStefano Zampini 23010f202f7eSStefano Zampini The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using a MatPartitioning object. 230228509bceSStefano Zampini 2303df4d28bfSStefano 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. 230428509bceSStefano Zampini 23050f202f7eSStefano 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. 23060f202f7eSStefano Zampini Deluxe scaling is not supported yet for FETI-DP. 23070f202f7eSStefano Zampini 23080f202f7eSStefano Zampini Options Database Keys (some of them, run with -h for a complete list): 23090f202f7eSStefano Zampini 23100f202f7eSStefano Zampini . -pc_bddc_use_vertices <true> - use or not vertices in primal space 23110f202f7eSStefano Zampini . -pc_bddc_use_edges <true> - use or not edges in primal space 23120f202f7eSStefano Zampini . -pc_bddc_use_faces <false> - use or not faces in primal space 23130f202f7eSStefano Zampini . -pc_bddc_symmetric <true> - symmetric computation of primal basis functions. Specify false for unsymmetric problems 23140f202f7eSStefano Zampini . -pc_bddc_use_change_of_basis <false> - use change of basis approach (on edges only) 23150f202f7eSStefano Zampini . -pc_bddc_use_change_on_faces <false> - use change of basis approach on faces if change of basis has been requested 23160f202f7eSStefano Zampini . -pc_bddc_switch_static <false> - switches from M_2 (default) to M_3 operator (see reference article [1]) 231728509bceSStefano Zampini . -pc_bddc_levels <0> - maximum number of levels for multilevel 23180f202f7eSStefano 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) 23190f202f7eSStefano 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) 23200f202f7eSStefano Zampini . -pc_bddc_use_deluxe_scaling <false> - use deluxe scaling 23210f202f7eSStefano 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) 2322df4d28bfSStefano 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) 232328509bceSStefano Zampini - -pc_bddc_check_level <0> - set verbosity level of debugging output 232428509bceSStefano Zampini 232528509bceSStefano Zampini Options for Dirichlet, Neumann or coarse solver can be set with 232628509bceSStefano Zampini .vb 232728509bceSStefano Zampini -pc_bddc_dirichlet_ 232828509bceSStefano Zampini -pc_bddc_neumann_ 232928509bceSStefano Zampini -pc_bddc_coarse_ 233028509bceSStefano Zampini .ve 23310f202f7eSStefano Zampini e.g -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg. PCBDDC uses by default KPSPREONLY and PCLU. 233228509bceSStefano Zampini 23330f202f7eSStefano Zampini When using a multilevel approach, solvers' options at the N-th level (N > 1) can be specified as 233428509bceSStefano Zampini .vb 2335312be037SStefano Zampini -pc_bddc_dirichlet_lN_ 2336312be037SStefano Zampini -pc_bddc_neumann_lN_ 2337312be037SStefano Zampini -pc_bddc_coarse_lN_ 233828509bceSStefano Zampini .ve 23390f202f7eSStefano Zampini Note that level number ranges from the finest (0) to the coarsest (N). 23400f202f7eSStefano 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. 23410f202f7eSStefano Zampini .vb 23420f202f7eSStefano Zampini -pc_bddc_coarse_pc_bddc_adaptive_threshold 5 -pc_bddc_coarse_l1_pc_bddc_redistribute 3 23430f202f7eSStefano Zampini .ve 23440f202f7eSStefano 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 2345da1bb401SStefano Zampini 2346da1bb401SStefano Zampini Level: intermediate 2347da1bb401SStefano Zampini 2348b6fdb6dfSStefano Zampini Developer notes: 2349da1bb401SStefano Zampini 2350da1bb401SStefano Zampini Contributed by Stefano Zampini 2351da1bb401SStefano Zampini 2352da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 2353da1bb401SStefano Zampini M*/ 2354b2573a8aSBarry Smith 2355da1bb401SStefano Zampini #undef __FUNCT__ 2356da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC" 23578cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 2358da1bb401SStefano Zampini { 2359da1bb401SStefano Zampini PetscErrorCode ierr; 2360da1bb401SStefano Zampini PC_BDDC *pcbddc; 2361da1bb401SStefano Zampini 2362da1bb401SStefano Zampini PetscFunctionBegin; 2363da1bb401SStefano Zampini /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 2364b00a9115SJed Brown ierr = PetscNewLog(pc,&pcbddc);CHKERRQ(ierr); 2365da1bb401SStefano Zampini pc->data = (void*)pcbddc; 2366da1bb401SStefano Zampini 2367da1bb401SStefano Zampini /* create PCIS data structure */ 2368da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 2369da1bb401SStefano Zampini 237047d04d0dSStefano Zampini /* BDDC customization */ 237108a5cf49SStefano Zampini pcbddc->use_local_adj = PETSC_TRUE; 237247d04d0dSStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 237347d04d0dSStefano Zampini pcbddc->use_edges = PETSC_TRUE; 237447d04d0dSStefano Zampini pcbddc->use_faces = PETSC_FALSE; 237547d04d0dSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 237647d04d0dSStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 237747d04d0dSStefano Zampini pcbddc->switch_static = PETSC_FALSE; 2378fa434743SStefano Zampini pcbddc->use_nnsp_true = PETSC_FALSE; 2379fa434743SStefano Zampini pcbddc->use_qr_single = PETSC_FALSE; 23803301b35fSStefano Zampini pcbddc->symmetric_primal = PETSC_TRUE; 238106a4e24aSStefano Zampini pcbddc->benign_saddle_point = PETSC_FALSE; 238214f95afaSStefano Zampini pcbddc->vertex_size = 1; 238347d04d0dSStefano Zampini pcbddc->dbg_flag = 0; 2384b9d89cd5SStefano Zampini /* private */ 2385727cdba6SStefano Zampini pcbddc->local_primal_size = 0; 23860e6343abSStefano Zampini pcbddc->local_primal_size_cc = 0; 23870e6343abSStefano Zampini pcbddc->local_primal_ref_node = 0; 23880e6343abSStefano Zampini pcbddc->local_primal_ref_mult = 0; 2389e9189074SStefano Zampini pcbddc->n_vertices = 0; 2390727cdba6SStefano Zampini pcbddc->primal_indices_local_idxs = 0; 2391fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 239268457ee5SStefano Zampini pcbddc->coarse_size = -1; 2393f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 2394727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 2395f4ddd8eeSStefano Zampini pcbddc->global_primal_indices = 0; 2396f4ddd8eeSStefano Zampini pcbddc->onearnullspace = 0; 2397f4ddd8eeSStefano Zampini pcbddc->onearnullvecs_state = 0; 2398674ae819SStefano Zampini pcbddc->user_primal_vertices = 0; 239930368db7SStefano Zampini pcbddc->user_primal_vertices_local = 0; 24000bdf917eSStefano Zampini pcbddc->NullSpace = 0; 24013972b0daSStefano Zampini pcbddc->temp_solution = 0; 2402534831adSStefano Zampini pcbddc->original_rhs = 0; 2403534831adSStefano Zampini pcbddc->local_mat = 0; 2404534831adSStefano Zampini pcbddc->ChangeOfBasisMatrix = 0; 2405b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = 0; 2406da1bb401SStefano Zampini pcbddc->coarse_vec = 0; 2407da1bb401SStefano Zampini pcbddc->coarse_ksp = 0; 2408da1bb401SStefano Zampini pcbddc->coarse_phi_B = 0; 2409da1bb401SStefano Zampini pcbddc->coarse_phi_D = 0; 241015aaf578SStefano Zampini pcbddc->coarse_psi_B = 0; 241115aaf578SStefano Zampini pcbddc->coarse_psi_D = 0; 2412da1bb401SStefano Zampini pcbddc->vec1_P = 0; 2413da1bb401SStefano Zampini pcbddc->vec1_R = 0; 2414da1bb401SStefano Zampini pcbddc->vec2_R = 0; 2415da1bb401SStefano Zampini pcbddc->local_auxmat1 = 0; 2416da1bb401SStefano Zampini pcbddc->local_auxmat2 = 0; 2417da1bb401SStefano Zampini pcbddc->R_to_B = 0; 2418da1bb401SStefano Zampini pcbddc->R_to_D = 0; 2419da1bb401SStefano Zampini pcbddc->ksp_D = 0; 2420da1bb401SStefano Zampini pcbddc->ksp_R = 0; 2421da1bb401SStefano Zampini pcbddc->NeumannBoundaries = 0; 2422785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = 0; 2423785d1243SStefano Zampini pcbddc->DirichletBoundaries = 0; 2424785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = 0; 242560d44989SStefano Zampini pcbddc->user_provided_isfordofs = PETSC_FALSE; 242660d44989SStefano Zampini pcbddc->n_ISForDofs = 0; 242763602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 2428da1bb401SStefano Zampini pcbddc->ISForDofs = 0; 242963602bcaSStefano Zampini pcbddc->ISForDofsLocal = 0; 2430da1bb401SStefano Zampini pcbddc->ConstraintMatrix = 0; 243185c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 243247d04d0dSStefano Zampini pcbddc->coarse_loc_to_glob = 0; 243347d04d0dSStefano Zampini pcbddc->coarsening_ratio = 8; 2434b0c7d250SStefano Zampini pcbddc->coarse_adj_red = 0; 24354fad6a16SStefano Zampini pcbddc->current_level = 0; 24362b510759SStefano Zampini pcbddc->max_levels = 0; 2437323d395dSStefano Zampini pcbddc->use_coarse_estimates = PETSC_FALSE; 243857de7509SStefano Zampini pcbddc->coarse_eqs_per_proc = 1; 2439f3bde8b3SStefano Zampini pcbddc->coarse_subassembling = 0; 24404f1b2e48SStefano Zampini pcbddc->detect_disconnected = PETSC_FALSE; 24414f1b2e48SStefano Zampini pcbddc->n_local_subs = 0; 24424f1b2e48SStefano Zampini pcbddc->local_subs = NULL; 244381d14e9dSStefano Zampini 244481d14e9dSStefano Zampini /* benign subspace trick */ 244581d14e9dSStefano Zampini pcbddc->benign_change = 0; 24460369aaf7SStefano Zampini pcbddc->benign_vec = 0; 24470369aaf7SStefano Zampini pcbddc->benign_original_mat = 0; 24480369aaf7SStefano Zampini pcbddc->benign_sf = 0; 24494f1b2e48SStefano Zampini pcbddc->benign_B0 = 0; 24504f1b2e48SStefano Zampini pcbddc->benign_n = 0; 24514f1b2e48SStefano Zampini pcbddc->benign_p0 = NULL; 24524f1b2e48SStefano Zampini pcbddc->benign_p0_lidx = NULL; 24534f1b2e48SStefano Zampini pcbddc->benign_p0_gidx = NULL; 2454b0f5fe93SStefano Zampini pcbddc->benign_null = PETSC_FALSE; 245581d14e9dSStefano Zampini 2456674ae819SStefano Zampini /* create local graph structure */ 2457674ae819SStefano Zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 2458674ae819SStefano Zampini 2459674ae819SStefano Zampini /* scaling */ 2460674ae819SStefano Zampini pcbddc->work_scaling = 0; 246134a97f8cSStefano Zampini pcbddc->use_deluxe_scaling = PETSC_FALSE; 2462b96c3477SStefano Zampini 2463b96c3477SStefano Zampini /* create sub schurs structure */ 2464b96c3477SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 2465b96c3477SStefano Zampini pcbddc->sub_schurs_rebuild = PETSC_FALSE; 2466b96c3477SStefano Zampini pcbddc->sub_schurs_layers = -1; 2467b96c3477SStefano Zampini pcbddc->sub_schurs_use_useradj = PETSC_FALSE; 2468b96c3477SStefano Zampini 2469b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_FALSE; 2470da1bb401SStefano Zampini 2471b7eb3628SStefano Zampini /* adaptivity */ 2472f6f667cfSStefano Zampini pcbddc->adaptive_threshold = 0.0; 247308122e43SStefano Zampini pcbddc->adaptive_nmax = 0; 2474f6f667cfSStefano Zampini pcbddc->adaptive_nmin = 0; 2475b7eb3628SStefano Zampini 2476da1bb401SStefano Zampini /* function pointers */ 2477da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 247893bd9ae7SStefano Zampini pc->ops->applytranspose = PCApplyTranspose_BDDC; 2479da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 2480da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 2481da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 24826b78500eSPatrick Sanan pc->ops->view = PCView_BDDC; 2483da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 2484da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 2485da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 2486534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 2487534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 2488da1bb401SStefano Zampini 2489da1bb401SStefano Zampini /* composing function */ 2490906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",PCBDDCSetChangeOfBasisMat_BDDC);CHKERRQ(ierr); 2491674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 249230368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",PCBDDCSetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 2493bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 24942b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr); 2495b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr); 24962b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr); 2497bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",PCBDDCSetNullSpace_BDDC);CHKERRQ(ierr); 2498bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 249982ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2500bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 250182ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2502bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 250382ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2504bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 250582ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2506bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 250763602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",PCBDDCSetDofsSplittingLocal_BDDC);CHKERRQ(ierr); 2508bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 2509bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 2510bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 2511bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 2512da1bb401SStefano Zampini PetscFunctionReturn(0); 2513da1bb401SStefano Zampini } 25143425bc38SStefano Zampini 2515