153cdbc3dSStefano Zampini /* TODOLIST 2da1bb401SStefano Zampini DofSplitting and DM attached to pc? 3da1bb401SStefano Zampini Change SetNeumannBoundaries to SetNeumannBoundariesLocal and provide new SetNeumannBoundaries (same Dirichlet) 4a0ba757dSStefano Zampini change how to deal with the coarse problem (PCBDDCSetCoarseEnvironment): 5a0ba757dSStefano Zampini - simplify coarse problem structure -> PCBDDC or PCREDUDANT, nothing else -> same comm for all levels? 6a0ba757dSStefano Zampini - remove coarse enums and allow use of PCBDDCGetCoarseKSP 7674ae819SStefano Zampini - remove metis dependency -> use MatPartitioning for multilevel -> Assemble serial adjacency in PCBDDCAnalyzeInterface? 8a0ba757dSStefano Zampini code refactoring: 9a0ba757dSStefano Zampini - pick up better names for static functions 10a0ba757dSStefano Zampini change options structure: 11a0ba757dSStefano Zampini - insert BDDC into MG framework? 12a0ba757dSStefano Zampini provide other ops? Ask to developers 13a0ba757dSStefano Zampini remove all unused printf 14a0ba757dSStefano Zampini man pages 1553cdbc3dSStefano Zampini */ 160c7d97c5SJed Brown 1753cdbc3dSStefano Zampini /* ---------------------------------------------------------------------------------------------------------------------------------------------- 180c7d97c5SJed Brown Implementation of BDDC preconditioner based on: 190c7d97c5SJed Brown C. Dohrmann "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 2053cdbc3dSStefano Zampini ---------------------------------------------------------------------------------------------------------------------------------------------- */ 2153cdbc3dSStefano Zampini 22674ae819SStefano Zampini #include "bddc.h" /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 23674ae819SStefano Zampini #include "bddcprivate.h" 243b03a366Sstefano_zampini #include <petscblaslapack.h> 25674ae819SStefano Zampini 26674ae819SStefano Zampini /* prototypes for static functions contained in bddc.c */ 27674ae819SStefano Zampini static PetscErrorCode PCBDDCSetLevel(PC,PetscInt); 28674ae819SStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC); 29674ae819SStefano Zampini 300c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 310c7d97c5SJed Brown #undef __FUNCT__ 320c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC" 330c7d97c5SJed Brown PetscErrorCode PCSetFromOptions_BDDC(PC pc) 340c7d97c5SJed Brown { 350c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 360c7d97c5SJed Brown PetscErrorCode ierr; 370c7d97c5SJed Brown 380c7d97c5SJed Brown PetscFunctionBegin; 390c7d97c5SJed Brown ierr = PetscOptionsHead("BDDC options");CHKERRQ(ierr); 400c7d97c5SJed Brown /* Verbose debugging of main data structures */ 419d9e44b6SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_check_level" ,"Verbose (debugging) output for PCBDDC" ,"none",pcbddc->dbg_flag ,&pcbddc->dbg_flag ,NULL);CHKERRQ(ierr); 420c7d97c5SJed Brown /* Some customization for default primal space */ 430298fd71SBarry Smith ierr = PetscOptionsBool("-pc_bddc_vertices_only" ,"Use only vertices in coarse space (i.e. discard constraints)","none",pcbddc->vertices_flag ,&pcbddc->vertices_flag ,NULL);CHKERRQ(ierr); 440298fd71SBarry Smith ierr = PetscOptionsBool("-pc_bddc_constraints_only","Use only constraints in coarse space (i.e. discard vertices)","none",pcbddc->constraints_flag,&pcbddc->constraints_flag,NULL);CHKERRQ(ierr); 450298fd71SBarry Smith ierr = PetscOptionsBool("-pc_bddc_faces_only" ,"Use only faces among constraints of coarse space (i.e. discard edges)" ,"none",pcbddc->faces_flag ,&pcbddc->faces_flag ,NULL);CHKERRQ(ierr); 460298fd71SBarry Smith ierr = PetscOptionsBool("-pc_bddc_edges_only" ,"Use only edges among constraints of coarse space (i.e. discard faces)" ,"none",pcbddc->edges_flag ,&pcbddc->edges_flag ,NULL);CHKERRQ(ierr); 470c7d97c5SJed Brown /* Coarse solver context */ 486c667b0aSStefano Zampini static const char * const avail_coarse_problems[] = {"sequential","replicated","parallel","multilevel","CoarseProblemType","PC_BDDC_",0}; /*order of choiches depends on ENUM defined in bddc.h */ 490298fd71SBarry Smith ierr = PetscOptionsEnum("-pc_bddc_coarse_problem_type","Set coarse problem type","none",avail_coarse_problems,(PetscEnum)pcbddc->coarse_problem_type,(PetscEnum*)&pcbddc->coarse_problem_type,NULL);CHKERRQ(ierr); 500c7d97c5SJed Brown /* Two different application of BDDC to the whole set of dofs, internal and interface */ 510298fd71SBarry Smith ierr = PetscOptionsBool("-pc_bddc_switch_preconditioning_type","Switch between M_2 (default) and M_3 preconditioners (as defined by Dohrmann)","none",pcbddc->inexact_prec_type,&pcbddc->inexact_prec_type,NULL);CHKERRQ(ierr); 52674ae819SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_change_of_basis","Use change of basis approach for primal space","none",pcbddc->use_change_of_basis,&pcbddc->use_change_of_basis,NULL);CHKERRQ(ierr); 53674ae819SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_change_on_faces","Use change of basis approach for face constraints","none",pcbddc->use_change_on_faces,&pcbddc->use_change_on_faces,NULL);CHKERRQ(ierr); 54674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 55674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 56674ae819SStefano Zampini } 570298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr); 580298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_max_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr); 59674ae819SStefano 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); 600c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 610c7d97c5SJed Brown PetscFunctionReturn(0); 620c7d97c5SJed Brown } 630c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 64674ae819SStefano Zampini #undef __FUNCT__ 65674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS_BDDC" 66674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 67674ae819SStefano Zampini { 68674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 69674ae819SStefano Zampini PetscErrorCode ierr; 701e6b0712SBarry Smith 71674ae819SStefano Zampini PetscFunctionBegin; 72674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 73674ae819SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 74674ae819SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 75674ae819SStefano Zampini PetscFunctionReturn(0); 76674ae819SStefano Zampini } 77674ae819SStefano Zampini #undef __FUNCT__ 78674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS" 79674ae819SStefano Zampini /*@ 80674ae819SStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set user defined primal vertices in PCBDDC. 81674ae819SStefano Zampini 82674ae819SStefano Zampini Not collective 83674ae819SStefano Zampini 84674ae819SStefano Zampini Input Parameters: 85674ae819SStefano Zampini + pc - the preconditioning context 86674ae819SStefano Zampini - PrimalVertices - index sets of primal vertices in local numbering 87674ae819SStefano Zampini 88674ae819SStefano Zampini Level: intermediate 89674ae819SStefano Zampini 90674ae819SStefano Zampini Notes: 91674ae819SStefano Zampini 92674ae819SStefano Zampini .seealso: PCBDDC 93674ae819SStefano Zampini @*/ 94674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 95674ae819SStefano Zampini { 96674ae819SStefano Zampini PetscErrorCode ierr; 97674ae819SStefano Zampini 98674ae819SStefano Zampini PetscFunctionBegin; 99674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 100674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 101674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 102674ae819SStefano Zampini PetscFunctionReturn(0); 103674ae819SStefano Zampini } 104674ae819SStefano Zampini /* -------------------------------------------------------------------------- */ 1050c7d97c5SJed Brown #undef __FUNCT__ 1060c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType_BDDC" 10753cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetCoarseProblemType_BDDC(PC pc, CoarseProblemType CPT) 1080c7d97c5SJed Brown { 1090c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1100c7d97c5SJed Brown 1110c7d97c5SJed Brown PetscFunctionBegin; 1120c7d97c5SJed Brown pcbddc->coarse_problem_type = CPT; 1130c7d97c5SJed Brown PetscFunctionReturn(0); 1140c7d97c5SJed Brown } 1151e6b0712SBarry Smith 1160c7d97c5SJed Brown #undef __FUNCT__ 1170c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType" 11853cdbc3dSStefano Zampini /*@ 1199c0446d6SStefano Zampini PCBDDCSetCoarseProblemType - Set coarse problem type in PCBDDC. 12053cdbc3dSStefano Zampini 1219c0446d6SStefano Zampini Not collective 12253cdbc3dSStefano Zampini 12353cdbc3dSStefano Zampini Input Parameters: 12453cdbc3dSStefano Zampini + pc - the preconditioning context 12553cdbc3dSStefano Zampini - CoarseProblemType - pick a better name and explain what this is 12653cdbc3dSStefano Zampini 12753cdbc3dSStefano Zampini Level: intermediate 12853cdbc3dSStefano Zampini 12953cdbc3dSStefano Zampini Notes: 130da1bb401SStefano Zampini Not collective but all procs must call with same arguments. 13153cdbc3dSStefano Zampini 13253cdbc3dSStefano Zampini .seealso: PCBDDC 13353cdbc3dSStefano Zampini @*/ 1340c7d97c5SJed Brown PetscErrorCode PCBDDCSetCoarseProblemType(PC pc, CoarseProblemType CPT) 1350c7d97c5SJed Brown { 1360c7d97c5SJed Brown PetscErrorCode ierr; 1370c7d97c5SJed Brown 1380c7d97c5SJed Brown PetscFunctionBegin; 1390c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1400c7d97c5SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetCoarseProblemType_C",(PC,CoarseProblemType),(pc,CPT));CHKERRQ(ierr); 1410c7d97c5SJed Brown PetscFunctionReturn(0); 1420c7d97c5SJed Brown } 1430c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1440c7d97c5SJed Brown #undef __FUNCT__ 1454fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio_BDDC" 1464fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 1474fad6a16SStefano Zampini { 1484fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1494fad6a16SStefano Zampini 1504fad6a16SStefano Zampini PetscFunctionBegin; 1514fad6a16SStefano Zampini pcbddc->coarsening_ratio=k; 1524fad6a16SStefano Zampini PetscFunctionReturn(0); 1534fad6a16SStefano Zampini } 1541e6b0712SBarry Smith 1554fad6a16SStefano Zampini #undef __FUNCT__ 1564fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio" 1574fad6a16SStefano Zampini /*@ 1584fad6a16SStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel coarsening 1594fad6a16SStefano Zampini 1604fad6a16SStefano Zampini Logically collective on PC 1614fad6a16SStefano Zampini 1624fad6a16SStefano Zampini Input Parameters: 1634fad6a16SStefano Zampini + pc - the preconditioning context 1644fad6a16SStefano Zampini - k - coarsening ratio 1654fad6a16SStefano Zampini 1664fad6a16SStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level. 1674fad6a16SStefano Zampini 1684fad6a16SStefano Zampini Level: intermediate 1694fad6a16SStefano Zampini 1704fad6a16SStefano Zampini Notes: 1714fad6a16SStefano Zampini 1724fad6a16SStefano Zampini .seealso: PCBDDC 1734fad6a16SStefano Zampini @*/ 1744fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 1754fad6a16SStefano Zampini { 1764fad6a16SStefano Zampini PetscErrorCode ierr; 1774fad6a16SStefano Zampini 1784fad6a16SStefano Zampini PetscFunctionBegin; 1794fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1804fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 1814fad6a16SStefano Zampini PetscFunctionReturn(0); 1824fad6a16SStefano Zampini } 1834fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 1841e6b0712SBarry Smith 1854fad6a16SStefano Zampini #undef __FUNCT__ 1864fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetMaxLevels_BDDC" 1874fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetMaxLevels_BDDC(PC pc,PetscInt max_levels) 1884fad6a16SStefano Zampini { 1894fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1904fad6a16SStefano Zampini 1914fad6a16SStefano Zampini PetscFunctionBegin; 1924fad6a16SStefano Zampini pcbddc->max_levels=max_levels; 1934fad6a16SStefano Zampini PetscFunctionReturn(0); 1944fad6a16SStefano Zampini } 1951e6b0712SBarry Smith 1964fad6a16SStefano Zampini #undef __FUNCT__ 1974fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetMaxLevels" 1984fad6a16SStefano Zampini /*@ 1994fad6a16SStefano Zampini PCBDDCSetMaxLevels - Sets the maximum number of levels within the multilevel approach. 2004fad6a16SStefano Zampini 2014fad6a16SStefano Zampini Logically collective on PC 2024fad6a16SStefano Zampini 2034fad6a16SStefano Zampini Input Parameters: 2044fad6a16SStefano Zampini + pc - the preconditioning context 2054fad6a16SStefano Zampini - max_levels - the maximum number of levels 2064fad6a16SStefano Zampini 2074fad6a16SStefano Zampini Default value is 1, i.e. coarse problem will be solved inexactly with one application 2084fad6a16SStefano Zampini of PCBDDC preconditioner if the multilevel approach is requested. 2094fad6a16SStefano Zampini 2104fad6a16SStefano Zampini Level: intermediate 2114fad6a16SStefano Zampini 2124fad6a16SStefano Zampini Notes: 2134fad6a16SStefano Zampini 2144fad6a16SStefano Zampini .seealso: PCBDDC 2154fad6a16SStefano Zampini @*/ 2164fad6a16SStefano Zampini PetscErrorCode PCBDDCSetMaxLevels(PC pc,PetscInt max_levels) 2174fad6a16SStefano Zampini { 2184fad6a16SStefano Zampini PetscErrorCode ierr; 2194fad6a16SStefano Zampini 2204fad6a16SStefano Zampini PetscFunctionBegin; 2214fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2224fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetMaxLevels_C",(PC,PetscInt),(pc,max_levels));CHKERRQ(ierr); 2234fad6a16SStefano Zampini PetscFunctionReturn(0); 2244fad6a16SStefano Zampini } 2254fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 2261e6b0712SBarry Smith 2274fad6a16SStefano Zampini #undef __FUNCT__ 2280bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace_BDDC" 2290bdf917eSStefano Zampini static PetscErrorCode PCBDDCSetNullSpace_BDDC(PC pc,MatNullSpace NullSpace) 2300bdf917eSStefano Zampini { 2310bdf917eSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2320bdf917eSStefano Zampini PetscErrorCode ierr; 2330bdf917eSStefano Zampini 2340bdf917eSStefano Zampini PetscFunctionBegin; 2350bdf917eSStefano Zampini ierr = PetscObjectReference((PetscObject)NullSpace);CHKERRQ(ierr); 2360bdf917eSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 2370bdf917eSStefano Zampini pcbddc->NullSpace=NullSpace; 2380bdf917eSStefano Zampini PetscFunctionReturn(0); 2390bdf917eSStefano Zampini } 2401e6b0712SBarry Smith 2410bdf917eSStefano Zampini #undef __FUNCT__ 2420bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace" 2430bdf917eSStefano Zampini /*@ 2440bdf917eSStefano Zampini PCBDDCSetNullSpace - Set NullSpace of global operator of BDDC preconditioned mat. 2450bdf917eSStefano Zampini 2460bdf917eSStefano Zampini Logically collective on PC and MatNullSpace 2470bdf917eSStefano Zampini 2480bdf917eSStefano Zampini Input Parameters: 2490bdf917eSStefano Zampini + pc - the preconditioning context 2500bdf917eSStefano Zampini - NullSpace - Null space of the linear operator to be preconditioned. 2510bdf917eSStefano Zampini 2520bdf917eSStefano Zampini Level: intermediate 2530bdf917eSStefano Zampini 2540bdf917eSStefano Zampini Notes: 2550bdf917eSStefano Zampini 2560bdf917eSStefano Zampini .seealso: PCBDDC 2570bdf917eSStefano Zampini @*/ 2580bdf917eSStefano Zampini PetscErrorCode PCBDDCSetNullSpace(PC pc,MatNullSpace NullSpace) 2590bdf917eSStefano Zampini { 2600bdf917eSStefano Zampini PetscErrorCode ierr; 2610bdf917eSStefano Zampini 2620bdf917eSStefano Zampini PetscFunctionBegin; 2630bdf917eSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 264674ae819SStefano Zampini PetscValidHeaderSpecific(NullSpace,MAT_NULLSPACE_CLASSID,2); 2650bdf917eSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNullSpace_C",(PC,MatNullSpace),(pc,NullSpace));CHKERRQ(ierr); 2660bdf917eSStefano Zampini PetscFunctionReturn(0); 2670bdf917eSStefano Zampini } 2680bdf917eSStefano Zampini /* -------------------------------------------------------------------------- */ 2691e6b0712SBarry Smith 2700bdf917eSStefano Zampini #undef __FUNCT__ 2713b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC" 2723b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 2733b03a366Sstefano_zampini { 2743b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2753b03a366Sstefano_zampini PetscErrorCode ierr; 2763b03a366Sstefano_zampini 2773b03a366Sstefano_zampini PetscFunctionBegin; 2783b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 27936e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 28036e030ebSStefano Zampini pcbddc->DirichletBoundaries=DirichletBoundaries; 2813b03a366Sstefano_zampini PetscFunctionReturn(0); 2823b03a366Sstefano_zampini } 2831e6b0712SBarry Smith 2843b03a366Sstefano_zampini #undef __FUNCT__ 2853b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries" 2863b03a366Sstefano_zampini /*@ 287da1bb401SStefano Zampini PCBDDCSetDirichletBoundaries - Set index set defining subdomain part (in local ordering) 288da1bb401SStefano Zampini of Dirichlet boundaries for the global problem. 2893b03a366Sstefano_zampini 2903b03a366Sstefano_zampini Not collective 2913b03a366Sstefano_zampini 2923b03a366Sstefano_zampini Input Parameters: 2933b03a366Sstefano_zampini + pc - the preconditioning context 2940298fd71SBarry Smith - DirichletBoundaries - sequential index set defining the subdomain part of Dirichlet boundaries (can be NULL) 2953b03a366Sstefano_zampini 2963b03a366Sstefano_zampini Level: intermediate 2973b03a366Sstefano_zampini 2983b03a366Sstefano_zampini Notes: 2993b03a366Sstefano_zampini 3003b03a366Sstefano_zampini .seealso: PCBDDC 3013b03a366Sstefano_zampini @*/ 3023b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 3033b03a366Sstefano_zampini { 3043b03a366Sstefano_zampini PetscErrorCode ierr; 3053b03a366Sstefano_zampini 3063b03a366Sstefano_zampini PetscFunctionBegin; 3073b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 308674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 3093b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 3103b03a366Sstefano_zampini PetscFunctionReturn(0); 3113b03a366Sstefano_zampini } 3123b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 3131e6b0712SBarry Smith 3143b03a366Sstefano_zampini #undef __FUNCT__ 3150c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 31653cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 3170c7d97c5SJed Brown { 3180c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 31953cdbc3dSStefano Zampini PetscErrorCode ierr; 3200c7d97c5SJed Brown 3210c7d97c5SJed Brown PetscFunctionBegin; 32253cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 32336e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 32436e030ebSStefano Zampini pcbddc->NeumannBoundaries=NeumannBoundaries; 3250c7d97c5SJed Brown PetscFunctionReturn(0); 3260c7d97c5SJed Brown } 3271e6b0712SBarry Smith 3280c7d97c5SJed Brown #undef __FUNCT__ 3290c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 33057527edcSJed Brown /*@ 331da1bb401SStefano Zampini PCBDDCSetNeumannBoundaries - Set index set defining subdomain part (in local ordering) 332da1bb401SStefano Zampini of Neumann boundaries for the global problem. 33357527edcSJed Brown 3349c0446d6SStefano Zampini Not collective 33557527edcSJed Brown 33657527edcSJed Brown Input Parameters: 33757527edcSJed Brown + pc - the preconditioning context 3380298fd71SBarry Smith - NeumannBoundaries - sequential index set defining the subdomain part of Neumann boundaries (can be NULL) 33957527edcSJed Brown 34057527edcSJed Brown Level: intermediate 34157527edcSJed Brown 34257527edcSJed Brown Notes: 34357527edcSJed Brown 34457527edcSJed Brown .seealso: PCBDDC 34557527edcSJed Brown @*/ 34653cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 3470c7d97c5SJed Brown { 3480c7d97c5SJed Brown PetscErrorCode ierr; 3490c7d97c5SJed Brown 3500c7d97c5SJed Brown PetscFunctionBegin; 3510c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 352674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 35353cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 35453cdbc3dSStefano Zampini PetscFunctionReturn(0); 35553cdbc3dSStefano Zampini } 35653cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 3571e6b0712SBarry Smith 35853cdbc3dSStefano Zampini #undef __FUNCT__ 359da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC" 360da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 361da1bb401SStefano Zampini { 362da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 363da1bb401SStefano Zampini 364da1bb401SStefano Zampini PetscFunctionBegin; 365da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 366da1bb401SStefano Zampini PetscFunctionReturn(0); 367da1bb401SStefano Zampini } 3681e6b0712SBarry Smith 369da1bb401SStefano Zampini #undef __FUNCT__ 370da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries" 371da1bb401SStefano Zampini /*@ 372da1bb401SStefano Zampini PCBDDCGetDirichletBoundaries - Get index set defining subdomain part (in local ordering) 373da1bb401SStefano Zampini of Dirichlet boundaries for the global problem. 374da1bb401SStefano Zampini 375da1bb401SStefano Zampini Not collective 376da1bb401SStefano Zampini 377da1bb401SStefano Zampini Input Parameters: 378da1bb401SStefano Zampini + pc - the preconditioning context 379da1bb401SStefano Zampini 380da1bb401SStefano Zampini Output Parameters: 381da1bb401SStefano Zampini + DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 382da1bb401SStefano Zampini 383da1bb401SStefano Zampini Level: intermediate 384da1bb401SStefano Zampini 385da1bb401SStefano Zampini Notes: 386da1bb401SStefano Zampini 387da1bb401SStefano Zampini .seealso: PCBDDC 388da1bb401SStefano Zampini @*/ 389da1bb401SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 390da1bb401SStefano Zampini { 391da1bb401SStefano Zampini PetscErrorCode ierr; 392da1bb401SStefano Zampini 393da1bb401SStefano Zampini PetscFunctionBegin; 394da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 395da1bb401SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 396da1bb401SStefano Zampini PetscFunctionReturn(0); 397da1bb401SStefano Zampini } 398da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 3991e6b0712SBarry Smith 400da1bb401SStefano Zampini #undef __FUNCT__ 40153cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 40253cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 40353cdbc3dSStefano Zampini { 40453cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 40553cdbc3dSStefano Zampini 40653cdbc3dSStefano Zampini PetscFunctionBegin; 40753cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 40853cdbc3dSStefano Zampini PetscFunctionReturn(0); 40953cdbc3dSStefano Zampini } 4101e6b0712SBarry Smith 41153cdbc3dSStefano Zampini #undef __FUNCT__ 41253cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 41353cdbc3dSStefano Zampini /*@ 414da1bb401SStefano Zampini PCBDDCGetNeumannBoundaries - Get index set defining subdomain part (in local ordering) 415da1bb401SStefano Zampini of Neumann boundaries for the global problem. 41653cdbc3dSStefano Zampini 4179c0446d6SStefano Zampini Not collective 41853cdbc3dSStefano Zampini 41953cdbc3dSStefano Zampini Input Parameters: 42053cdbc3dSStefano Zampini + pc - the preconditioning context 42153cdbc3dSStefano Zampini 42253cdbc3dSStefano Zampini Output Parameters: 42353cdbc3dSStefano Zampini + NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 42453cdbc3dSStefano Zampini 42553cdbc3dSStefano Zampini Level: intermediate 42653cdbc3dSStefano Zampini 42753cdbc3dSStefano Zampini Notes: 42853cdbc3dSStefano Zampini 42953cdbc3dSStefano Zampini .seealso: PCBDDC 43053cdbc3dSStefano Zampini @*/ 43153cdbc3dSStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 43253cdbc3dSStefano Zampini { 43353cdbc3dSStefano Zampini PetscErrorCode ierr; 43453cdbc3dSStefano Zampini 43553cdbc3dSStefano Zampini PetscFunctionBegin; 43653cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 43753cdbc3dSStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 4380c7d97c5SJed Brown PetscFunctionReturn(0); 4390c7d97c5SJed Brown } 44036e030ebSStefano Zampini /* -------------------------------------------------------------------------- */ 4411e6b0712SBarry Smith 44236e030ebSStefano Zampini #undef __FUNCT__ 443da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC" 4441a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 44536e030ebSStefano Zampini { 44636e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 447da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 448da1bb401SStefano Zampini PetscErrorCode ierr; 44936e030ebSStefano Zampini 45036e030ebSStefano Zampini PetscFunctionBegin; 451674ae819SStefano Zampini /* free old CSR */ 452674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 453fb223d50SStefano Zampini /* TODO: PCBDDCGraphSetAdjacency */ 454674ae819SStefano Zampini /* get CSR into graph structure */ 455da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 456674ae819SStefano Zampini ierr = PetscMalloc((nvtxs+1)*sizeof(PetscInt),&mat_graph->xadj);CHKERRQ(ierr); 457674ae819SStefano Zampini ierr = PetscMalloc(xadj[nvtxs]*sizeof(PetscInt),&mat_graph->adjncy);CHKERRQ(ierr); 458674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 459674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 460da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 4611a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 4621a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 463674ae819SStefano Zampini } 464575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 46536e030ebSStefano Zampini PetscFunctionReturn(0); 46636e030ebSStefano Zampini } 4671e6b0712SBarry Smith 46836e030ebSStefano Zampini #undef __FUNCT__ 469da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph" 47036e030ebSStefano Zampini /*@ 471da1bb401SStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set CSR graph of local matrix for use of PCBDDC. 47236e030ebSStefano Zampini 47336e030ebSStefano Zampini Not collective 47436e030ebSStefano Zampini 47536e030ebSStefano Zampini Input Parameters: 47636e030ebSStefano Zampini + pc - the preconditioning context 477da1bb401SStefano Zampini - nvtxs - number of local vertices of the graph 478da1bb401SStefano Zampini - xadj, adjncy - the CSR graph 479da1bb401SStefano Zampini - copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER. In the former case the user must free the array passed in; 480da1bb401SStefano Zampini in the latter case, memory must be obtained with PetscMalloc. 48136e030ebSStefano Zampini 48236e030ebSStefano Zampini Level: intermediate 48336e030ebSStefano Zampini 48436e030ebSStefano Zampini Notes: 48536e030ebSStefano Zampini 48636e030ebSStefano Zampini .seealso: PCBDDC 48736e030ebSStefano Zampini @*/ 4881a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 48936e030ebSStefano Zampini { 490575ad6abSStefano Zampini void (*f)(void) = 0; 49136e030ebSStefano Zampini PetscErrorCode ierr; 49236e030ebSStefano Zampini 49336e030ebSStefano Zampini PetscFunctionBegin; 49436e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 495674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 496674ae819SStefano Zampini PetscValidIntPointer(xadj,4); 497674ae819SStefano Zampini if (copymode != PETSC_COPY_VALUES && copymode != PETSC_OWN_POINTER) { 498674ae819SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d in %s\n",copymode,__FUNCT__); 499da1bb401SStefano Zampini } 50036e030ebSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 501575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 502575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 503575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 504575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 505575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 50636e030ebSStefano Zampini } 50736e030ebSStefano Zampini PetscFunctionReturn(0); 50836e030ebSStefano Zampini } 5099c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 5101e6b0712SBarry Smith 5119c0446d6SStefano Zampini #undef __FUNCT__ 5129c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 5139c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 5149c0446d6SStefano Zampini { 5159c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5169c0446d6SStefano Zampini PetscInt i; 5179c0446d6SStefano Zampini PetscErrorCode ierr; 5189c0446d6SStefano Zampini 5199c0446d6SStefano Zampini PetscFunctionBegin; 520da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 5219c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 5229c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 5239c0446d6SStefano Zampini } 524d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 525da1bb401SStefano Zampini /* allocate space then set */ 5269c0446d6SStefano Zampini ierr = PetscMalloc(n_is*sizeof(IS),&pcbddc->ISForDofs);CHKERRQ(ierr); 5279c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 528da1bb401SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 529da1bb401SStefano Zampini pcbddc->ISForDofs[i]=ISForDofs[i]; 5309c0446d6SStefano Zampini } 5319c0446d6SStefano Zampini pcbddc->n_ISForDofs=n_is; 5329c0446d6SStefano Zampini PetscFunctionReturn(0); 5339c0446d6SStefano Zampini } 5341e6b0712SBarry Smith 5359c0446d6SStefano Zampini #undef __FUNCT__ 5369c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 5379c0446d6SStefano Zampini /*@ 538da1bb401SStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of local mat. 5399c0446d6SStefano Zampini 5409c0446d6SStefano Zampini Not collective 5419c0446d6SStefano Zampini 5429c0446d6SStefano Zampini Input Parameters: 5439c0446d6SStefano Zampini + pc - the preconditioning context 544da1bb401SStefano Zampini - n - number of index sets defining the fields 545da1bb401SStefano Zampini - IS[] - array of IS describing the fields 5469c0446d6SStefano Zampini 5479c0446d6SStefano Zampini Level: intermediate 5489c0446d6SStefano Zampini 5499c0446d6SStefano Zampini Notes: 5509c0446d6SStefano Zampini 5519c0446d6SStefano Zampini .seealso: PCBDDC 5529c0446d6SStefano Zampini @*/ 5539c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 5549c0446d6SStefano Zampini { 5559c0446d6SStefano Zampini PetscErrorCode ierr; 5569c0446d6SStefano Zampini 5579c0446d6SStefano Zampini PetscFunctionBegin; 5589c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5599c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 5609c0446d6SStefano Zampini PetscFunctionReturn(0); 5619c0446d6SStefano Zampini } 562da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 563534831adSStefano Zampini #undef __FUNCT__ 564534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC" 565534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 566534831adSStefano Zampini /* 567534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 568534831adSStefano Zampini guess if a transformation of basis approach has been selected. 5699c0446d6SStefano Zampini 570534831adSStefano Zampini Input Parameter: 571534831adSStefano Zampini + pc - the preconditioner contex 572534831adSStefano Zampini 573534831adSStefano Zampini Application Interface Routine: PCPreSolve() 574534831adSStefano Zampini 575534831adSStefano Zampini Notes: 576534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 577534831adSStefano Zampini the user, but instead is called by KSPSolve(). 578534831adSStefano Zampini */ 579534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 580534831adSStefano Zampini { 581534831adSStefano Zampini PetscErrorCode ierr; 582534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 583534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 584534831adSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 585534831adSStefano Zampini Mat temp_mat; 5863972b0daSStefano Zampini IS dirIS; 5873972b0daSStefano Zampini PetscInt dirsize,i,*is_indices; 5883972b0daSStefano Zampini PetscScalar *array_x,*array_diagonal; 5893972b0daSStefano Zampini Vec used_vec; 5903972b0daSStefano Zampini PetscBool guess_nonzero; 591534831adSStefano Zampini 592534831adSStefano Zampini PetscFunctionBegin; 59362a6ff1dSStefano Zampini /* Creates parallel work vectors used in presolve. */ 59462a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 59562a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 59662a6ff1dSStefano Zampini } 59762a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 59862a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 59962a6ff1dSStefano Zampini } 6003972b0daSStefano Zampini if (x) { 6013972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 6023972b0daSStefano Zampini used_vec = x; 6033972b0daSStefano Zampini } else { 6043972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 6053972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 6063972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 6073972b0daSStefano Zampini } 6083972b0daSStefano Zampini /* hack into ksp data structure PCPreSolve comes earlier in src/ksp/ksp/interface/itfunc.c */ 6093972b0daSStefano Zampini if (ksp) { 6103972b0daSStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&guess_nonzero);CHKERRQ(ierr); 6113972b0daSStefano Zampini if ( !guess_nonzero ) { 6123972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 6133972b0daSStefano Zampini } 6143972b0daSStefano Zampini } 6153308cffdSStefano Zampini 61662a6ff1dSStefano Zampini if (rhs) { /* TODO: wiser handling of rhs removal, which is only needed in case of zeroed rows */ 6173972b0daSStefano Zampini /* store the original rhs */ 6183972b0daSStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 6193972b0daSStefano Zampini 6203972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 6213972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 6223972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 6233972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6243972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6253972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6263972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6273972b0daSStefano Zampini ierr = PCBDDCGetDirichletBoundaries(pc,&dirIS);CHKERRQ(ierr); 6283972b0daSStefano Zampini if (dirIS) { 6293972b0daSStefano Zampini ierr = ISGetSize(dirIS,&dirsize);CHKERRQ(ierr); 6303972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 6313972b0daSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 6323972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6332fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 6343972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6353972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 6363972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 6373972b0daSStefano Zampini } 6383972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6393972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 640b76ba322SStefano Zampini 6413972b0daSStefano Zampini /* remove the computed solution from the rhs */ 6423972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 6433972b0daSStefano Zampini ierr = MatMultAdd(pc->pmat,used_vec,rhs,rhs);CHKERRQ(ierr); 6443972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 6453308cffdSStefano Zampini } 646b76ba322SStefano Zampini 647b76ba322SStefano Zampini /* store partially computed solution and set initial guess */ 6483972b0daSStefano Zampini if (x) { 6493972b0daSStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 6503972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 65115aaf578SStefano Zampini if (pcbddc->use_exact_dirichlet && !pcbddc->coarse_psi_B) { 652b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 653b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 654b76ba322SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 655b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 656b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 657b76ba322SStefano Zampini if (ksp) { 658b76ba322SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 659b76ba322SStefano Zampini } 660b76ba322SStefano Zampini } 6613972b0daSStefano Zampini } 662b76ba322SStefano Zampini 663674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 664b76ba322SStefano Zampini /* swap pointers for local matrices */ 665b76ba322SStefano Zampini temp_mat = matis->A; 666b76ba322SStefano Zampini matis->A = pcbddc->local_mat; 667b76ba322SStefano Zampini pcbddc->local_mat = temp_mat; 6683308cffdSStefano Zampini } 6693308cffdSStefano Zampini if (pcbddc->use_change_of_basis && rhs) { 670b76ba322SStefano Zampini /* Get local rhs and apply transformation of basis */ 671b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 672b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 673b76ba322SStefano Zampini /* from original basis to modified basis */ 674b76ba322SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 675b76ba322SStefano Zampini /* put back modified values into the global vec using INSERT_VALUES copy mode */ 676b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 677b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 678674ae819SStefano Zampini } 6790bdf917eSStefano Zampini if (ksp && pcbddc->NullSpace) { 680d0195637SJed Brown ierr = MatNullSpaceRemove(pcbddc->NullSpace,used_vec);CHKERRQ(ierr); 681d0195637SJed Brown ierr = MatNullSpaceRemove(pcbddc->NullSpace,rhs);CHKERRQ(ierr); 682b76ba322SStefano Zampini } 6830bdf917eSStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 684534831adSStefano Zampini PetscFunctionReturn(0); 685534831adSStefano Zampini } 686534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 687534831adSStefano Zampini #undef __FUNCT__ 688534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC" 689534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 690534831adSStefano Zampini /* 691534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 692534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 693534831adSStefano Zampini 694534831adSStefano Zampini Input Parameter: 695534831adSStefano Zampini + pc - the preconditioner contex 696534831adSStefano Zampini 697534831adSStefano Zampini Application Interface Routine: PCPostSolve() 698534831adSStefano Zampini 699534831adSStefano Zampini Notes: 700534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 701534831adSStefano Zampini the user, but instead is called by KSPSolve(). 702534831adSStefano Zampini */ 703534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 704534831adSStefano Zampini { 705534831adSStefano Zampini PetscErrorCode ierr; 706534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 707534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 708534831adSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 709534831adSStefano Zampini Mat temp_mat; 710534831adSStefano Zampini 711534831adSStefano Zampini PetscFunctionBegin; 712674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 713534831adSStefano Zampini /* swap pointers for local matrices */ 714534831adSStefano Zampini temp_mat = matis->A; 715534831adSStefano Zampini matis->A = pcbddc->local_mat; 716534831adSStefano Zampini pcbddc->local_mat = temp_mat; 7173425bc38SStefano Zampini } 7183308cffdSStefano Zampini if (pcbddc->use_change_of_basis && x) { 719534831adSStefano Zampini /* Get Local boundary and apply transformation of basis to solution vector */ 720534831adSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 721534831adSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 722534831adSStefano Zampini /* from modified basis to original basis */ 723534831adSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 724534831adSStefano Zampini /* put back modified values into the global vec using INSERT_VALUES copy mode */ 725534831adSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 726534831adSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 727534831adSStefano Zampini } 7283972b0daSStefano Zampini /* add solution removed in presolve */ 7293425bc38SStefano Zampini if (x) { 7303425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 7313425bc38SStefano Zampini } 732fb223d50SStefano Zampini /* restore rhs to its original state */ 733fb223d50SStefano Zampini if (rhs) { 734fb223d50SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,rhs);CHKERRQ(ierr); 735fb223d50SStefano Zampini } 736534831adSStefano Zampini PetscFunctionReturn(0); 737534831adSStefano Zampini } 738534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 73953cdbc3dSStefano Zampini #undef __FUNCT__ 74053cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 7410c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 7420c7d97c5SJed Brown /* 7430c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 7440c7d97c5SJed Brown by setting data structures and options. 7450c7d97c5SJed Brown 7460c7d97c5SJed Brown Input Parameter: 74753cdbc3dSStefano Zampini + pc - the preconditioner context 7480c7d97c5SJed Brown 7490c7d97c5SJed Brown Application Interface Routine: PCSetUp() 7500c7d97c5SJed Brown 7510c7d97c5SJed Brown Notes: 7520c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 7530c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 7540c7d97c5SJed Brown */ 75553cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 7560c7d97c5SJed Brown { 7570c7d97c5SJed Brown PetscErrorCode ierr; 7580c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 759674ae819SStefano Zampini MatStructure flag; 760674ae819SStefano Zampini PetscBool computeis,computetopography,computesolvers; 7610c7d97c5SJed Brown 7620c7d97c5SJed Brown PetscFunctionBegin; 763674ae819SStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other nonoverlapping preconditioners */ 7643b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 7659c0446d6SStefano Zampini So, we set to pcnone the Neumann problem of pcis in order to avoid unneeded computation 7660c7d97c5SJed Brown Also, we decide to directly build the (same) Dirichlet problem */ 7670c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localN_pc_type","none");CHKERRQ(ierr); 7680c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localD_pc_type","none");CHKERRQ(ierr); 7693b03a366Sstefano_zampini /* Get stdout for dbg */ 770674ae819SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->dbg_viewer) { 771ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pc),&pcbddc->dbg_viewer);CHKERRQ(ierr); 772e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 773e269702eSStefano Zampini } 774674ae819SStefano Zampini /* first attempt to split work */ 775674ae819SStefano Zampini if (pc->setupcalled) { 776674ae819SStefano Zampini computeis = PETSC_FALSE; 777674ae819SStefano Zampini ierr = PCGetOperators(pc,NULL,NULL,&flag);CHKERRQ(ierr); 778674ae819SStefano Zampini if (flag == SAME_PRECONDITIONER) { 779674ae819SStefano Zampini computetopography = PETSC_FALSE; 780674ae819SStefano Zampini computesolvers = PETSC_FALSE; 781674ae819SStefano Zampini } else if (flag == SAME_NONZERO_PATTERN) { 782674ae819SStefano Zampini computetopography = PETSC_FALSE; 783674ae819SStefano Zampini computesolvers = PETSC_TRUE; 784674ae819SStefano Zampini } else { /* DIFFERENT_NONZERO_PATTERN */ 785674ae819SStefano Zampini computetopography = PETSC_TRUE; 786674ae819SStefano Zampini computesolvers = PETSC_TRUE; 787674ae819SStefano Zampini } 788674ae819SStefano Zampini } else { 789674ae819SStefano Zampini computeis = PETSC_TRUE; 790674ae819SStefano Zampini computetopography = PETSC_TRUE; 791674ae819SStefano Zampini computesolvers = PETSC_TRUE; 792674ae819SStefano Zampini } 793674ae819SStefano Zampini /* Set up all the "iterative substructuring" common block */ 794674ae819SStefano Zampini if (computeis) { 795674ae819SStefano Zampini ierr = PCISSetUp(pc);CHKERRQ(ierr); 796674ae819SStefano Zampini } 797674ae819SStefano Zampini /* Analyze interface and set up local constraint and change of basis matrices */ 798674ae819SStefano Zampini if (computetopography) { 799674ae819SStefano Zampini /* reset data */ 800674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 801674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 802674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 803674ae819SStefano Zampini } 804674ae819SStefano Zampini if (computesolvers) { 805674ae819SStefano Zampini /* reset data */ 806674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 807674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 8080c7d97c5SJed Brown /* Create coarse and local stuffs used for evaluating action of preconditioner */ 8090c7d97c5SJed Brown ierr = PCBDDCCoarseSetUp(pc);CHKERRQ(ierr); 810674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 8110c7d97c5SJed Brown } 8120c7d97c5SJed Brown PetscFunctionReturn(0); 8130c7d97c5SJed Brown } 8140c7d97c5SJed Brown 8150c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 8160c7d97c5SJed Brown /* 8170c7d97c5SJed Brown PCApply_BDDC - Applies the BDDC preconditioner to a vector. 8180c7d97c5SJed Brown 8190c7d97c5SJed Brown Input Parameters: 8200c7d97c5SJed Brown . pc - the preconditioner context 8210c7d97c5SJed Brown . r - input vector (global) 8220c7d97c5SJed Brown 8230c7d97c5SJed Brown Output Parameter: 8240c7d97c5SJed Brown . z - output vector (global) 8250c7d97c5SJed Brown 8260c7d97c5SJed Brown Application Interface Routine: PCApply() 8270c7d97c5SJed Brown */ 8280c7d97c5SJed Brown #undef __FUNCT__ 8290c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 83053cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 8310c7d97c5SJed Brown { 8320c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 8330c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 8340c7d97c5SJed Brown PetscErrorCode ierr; 8353b03a366Sstefano_zampini const PetscScalar one = 1.0; 8363b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 8372617d88aSStefano Zampini const PetscScalar zero = 0.0; 8380c7d97c5SJed Brown 8390c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 8400c7d97c5SJed Brown NN interface preconditioner changed to BDDC 84129622bf0SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->inexact_prec_type = PETSC_TRUE) */ 8420c7d97c5SJed Brown 8430c7d97c5SJed Brown PetscFunctionBegin; 84415aaf578SStefano Zampini if (!pcbddc->use_exact_dirichlet || pcbddc->coarse_psi_B) { 8450c7d97c5SJed Brown /* First Dirichlet solve */ 8460c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8470c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 84853cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 8490c7d97c5SJed Brown /* 8500c7d97c5SJed Brown Assembling right hand side for BDDC operator 851674ae819SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE) 852674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 8530c7d97c5SJed Brown */ 8540c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 8550c7d97c5SJed Brown ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 85629622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 8570c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 8580c7d97c5SJed Brown ierr = VecCopy(r,z);CHKERRQ(ierr); 8590c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8600c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 861674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 862b76ba322SStefano Zampini } else { 8630bdf917eSStefano Zampini ierr = VecSet(pcis->vec1_D,zero);CHKERRQ(ierr); 864b76ba322SStefano Zampini ierr = VecSet(pcis->vec2_D,zero);CHKERRQ(ierr); 865674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 866b76ba322SStefano Zampini } 867b76ba322SStefano Zampini 8682617d88aSStefano Zampini /* Apply interface preconditioner 8692617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 8702617d88aSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc);CHKERRQ(ierr); 8712617d88aSStefano Zampini 872674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 873674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 8740c7d97c5SJed Brown 8753b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 8760c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8770c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8780c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 87929622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 88053cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr); 8810c7d97c5SJed Brown ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr); 88229622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); } 8830c7d97c5SJed Brown ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr); 8840c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8850c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8860c7d97c5SJed Brown PetscFunctionReturn(0); 8870c7d97c5SJed Brown } 888da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 889674ae819SStefano Zampini 890da1bb401SStefano Zampini #undef __FUNCT__ 891da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC" 892da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 893da1bb401SStefano Zampini { 894da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 895da1bb401SStefano Zampini PetscErrorCode ierr; 896da1bb401SStefano Zampini 897da1bb401SStefano Zampini PetscFunctionBegin; 898da1bb401SStefano Zampini /* free data created by PCIS */ 899da1bb401SStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 900674ae819SStefano Zampini /* free BDDC custom data */ 901674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 902674ae819SStefano Zampini /* destroy objects related to topography */ 903674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 904674ae819SStefano Zampini /* free allocated graph structure */ 905da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr); 906674ae819SStefano Zampini /* free data for scaling operator */ 907674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 908674ae819SStefano Zampini /* free solvers stuff */ 909674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 91033bc96a4SStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 91133bc96a4SStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 912ac78edfcSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 91362a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 91462a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 91562a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 9163425bc38SStefano Zampini /* remove functions */ 917674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 918bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 919bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetMaxLevels_C",NULL);CHKERRQ(ierr); 920bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",NULL);CHKERRQ(ierr); 921bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 922bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 923bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 924bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 925bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseProblemType_C",NULL);CHKERRQ(ierr); 926bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 927bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 928bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 929bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 930bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 931674ae819SStefano Zampini /* Free the private data structure */ 932674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 933da1bb401SStefano Zampini PetscFunctionReturn(0); 934da1bb401SStefano Zampini } 9353425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 9361e6b0712SBarry Smith 9373425bc38SStefano Zampini #undef __FUNCT__ 9383425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC" 9393425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 9403425bc38SStefano Zampini { 941674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 9423425bc38SStefano Zampini PC_IS* pcis; 9433425bc38SStefano Zampini PC_BDDC* pcbddc; 9443425bc38SStefano Zampini PetscErrorCode ierr; 9450c7d97c5SJed Brown 9463425bc38SStefano Zampini PetscFunctionBegin; 9473425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 9483425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 9493425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 9503425bc38SStefano Zampini 9513425bc38SStefano Zampini /* change of basis for physical rhs if needed 9523425bc38SStefano Zampini It also changes the rhs in case of dirichlet boundaries */ 9533308cffdSStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,standard_rhs,NULL);CHKERRQ(ierr); 9543425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 9553425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9563425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 957fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 958fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 9593425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9603425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 961674ae819SStefano Zampini /* Apply partition of unity */ 9623425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 963674ae819SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 96429622bf0SStefano Zampini if (!pcbddc->inexact_prec_type) { 9653425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 9663425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 9673425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 9683425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 9693425bc38SStefano Zampini ierr = VecSet(standard_rhs,0.0);CHKERRQ(ierr); 9703425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9713425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 972674ae819SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 9733425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9743425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9753425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 9763425bc38SStefano Zampini } 9773425bc38SStefano Zampini /* BDDC rhs */ 9783425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 97929622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { 9803425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 9813425bc38SStefano Zampini } 9823425bc38SStefano Zampini /* apply BDDC */ 9833425bc38SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr); 9843425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 9853425bc38SStefano Zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 9863425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 9873425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9883425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9893425bc38SStefano Zampini /* restore original rhs */ 9903425bc38SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,standard_rhs);CHKERRQ(ierr); 9913425bc38SStefano Zampini PetscFunctionReturn(0); 9923425bc38SStefano Zampini } 9931e6b0712SBarry Smith 9943425bc38SStefano Zampini #undef __FUNCT__ 9953425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS" 9963425bc38SStefano Zampini /*@ 9973425bc38SStefano Zampini PCBDDCMatFETIDPGetRHS - Get rhs for FETIDP linear system. 9983425bc38SStefano Zampini 9993425bc38SStefano Zampini Collective 10003425bc38SStefano Zampini 10013425bc38SStefano Zampini Input Parameters: 10023425bc38SStefano Zampini + fetidp_mat - the FETIDP mat obtained by a call to PCBDDCCreateFETIDPOperators 10033425bc38SStefano Zampini + standard_rhs - the rhs of your linear system 10043425bc38SStefano Zampini 10053425bc38SStefano Zampini Output Parameters: 10063425bc38SStefano Zampini + fetidp_flux_rhs - the rhs of the FETIDP linear system 10073425bc38SStefano Zampini 10083425bc38SStefano Zampini Level: developer 10093425bc38SStefano Zampini 10103425bc38SStefano Zampini Notes: 10113425bc38SStefano Zampini 10123425bc38SStefano Zampini .seealso: PCBDDC 10133425bc38SStefano Zampini @*/ 10143425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 10153425bc38SStefano Zampini { 1016674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 10173425bc38SStefano Zampini PetscErrorCode ierr; 10183425bc38SStefano Zampini 10193425bc38SStefano Zampini PetscFunctionBegin; 10203425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10213425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 10223425bc38SStefano Zampini PetscFunctionReturn(0); 10233425bc38SStefano Zampini } 10243425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 10251e6b0712SBarry Smith 10263425bc38SStefano Zampini #undef __FUNCT__ 10273425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC" 10283425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 10293425bc38SStefano Zampini { 1030674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 10313425bc38SStefano Zampini PC_IS* pcis; 10323425bc38SStefano Zampini PC_BDDC* pcbddc; 10333425bc38SStefano Zampini PetscErrorCode ierr; 10343425bc38SStefano Zampini 10353425bc38SStefano Zampini PetscFunctionBegin; 10363425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10373425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 10383425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 10393425bc38SStefano Zampini 10403425bc38SStefano Zampini /* apply B_delta^T */ 10413425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10423425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10433425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 10443425bc38SStefano Zampini /* compute rhs for BDDC application */ 10453425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 104629622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { 10473425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 10483425bc38SStefano Zampini } 10493425bc38SStefano Zampini /* apply BDDC */ 10503425bc38SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr); 10513425bc38SStefano Zampini /* put values into standard global vector */ 10523425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10533425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 105429622bf0SStefano Zampini if (!pcbddc->inexact_prec_type) { 10553425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 10563425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 10573425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_D,-1.0,pcis->vec1_D);CHKERRQ(ierr); 10583425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 10593425bc38SStefano Zampini } 10603425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10613425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10623425bc38SStefano Zampini /* final change of basis if needed 10633425bc38SStefano Zampini Is also sums the dirichlet part removed during RHS assembling */ 10643308cffdSStefano Zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 10653425bc38SStefano Zampini PetscFunctionReturn(0); 10663425bc38SStefano Zampini } 10671e6b0712SBarry Smith 10683425bc38SStefano Zampini #undef __FUNCT__ 10693425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution" 10703425bc38SStefano Zampini /*@ 10713425bc38SStefano Zampini PCBDDCMatFETIDPGetSolution - Get Solution for FETIDP linear system. 10723425bc38SStefano Zampini 10733425bc38SStefano Zampini Collective 10743425bc38SStefano Zampini 10753425bc38SStefano Zampini Input Parameters: 10763425bc38SStefano Zampini + fetidp_mat - the FETIDP mat obtained by a call to PCBDDCCreateFETIDPOperators 10773425bc38SStefano Zampini + fetidp_flux_sol - the solution of the FETIDP linear system 10783425bc38SStefano Zampini 10793425bc38SStefano Zampini Output Parameters: 10803425bc38SStefano Zampini + standard_sol - the solution on the global domain 10813425bc38SStefano Zampini 10823425bc38SStefano Zampini Level: developer 10833425bc38SStefano Zampini 10843425bc38SStefano Zampini Notes: 10853425bc38SStefano Zampini 10863425bc38SStefano Zampini .seealso: PCBDDC 10873425bc38SStefano Zampini @*/ 10883425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 10893425bc38SStefano Zampini { 1090674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 10913425bc38SStefano Zampini PetscErrorCode ierr; 10923425bc38SStefano Zampini 10933425bc38SStefano Zampini PetscFunctionBegin; 10943425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10953425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 10963425bc38SStefano Zampini PetscFunctionReturn(0); 10973425bc38SStefano Zampini } 10983425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 10991e6b0712SBarry Smith 1100f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec); 1101f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat); 1102f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec); 1103f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC); 1104674ae819SStefano Zampini 11053425bc38SStefano Zampini #undef __FUNCT__ 11063425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC" 11073425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 11083425bc38SStefano Zampini { 1109674ae819SStefano Zampini 1110674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 11113425bc38SStefano Zampini Mat newmat; 1112674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 11133425bc38SStefano Zampini PC newpc; 1114ce94432eSBarry Smith MPI_Comm comm; 11153425bc38SStefano Zampini PetscErrorCode ierr; 11163425bc38SStefano Zampini 11173425bc38SStefano Zampini PetscFunctionBegin; 1118ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 11193425bc38SStefano Zampini /* FETIDP linear matrix */ 11203425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 11213425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 11223425bc38SStefano Zampini ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 11233425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 11243425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 11253425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 11263425bc38SStefano Zampini /* FETIDP preconditioner */ 11273425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 11283425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 11293425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 11303425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 11313425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 11323425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 11333425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 11343425bc38SStefano Zampini ierr = PCSetOperators(newpc,newmat,newmat,SAME_PRECONDITIONER);CHKERRQ(ierr); 11353425bc38SStefano Zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 11363425bc38SStefano Zampini /* return pointers for objects created */ 11373425bc38SStefano Zampini *fetidp_mat=newmat; 11383425bc38SStefano Zampini *fetidp_pc=newpc; 11393425bc38SStefano Zampini PetscFunctionReturn(0); 11403425bc38SStefano Zampini } 11411e6b0712SBarry Smith 11423425bc38SStefano Zampini #undef __FUNCT__ 11433425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators" 11443425bc38SStefano Zampini /*@ 11453425bc38SStefano Zampini PCBDDCCreateFETIDPOperators - Create operators for FETIDP. 11463425bc38SStefano Zampini 11473425bc38SStefano Zampini Collective 11483425bc38SStefano Zampini 11493425bc38SStefano Zampini Input Parameters: 11503425bc38SStefano Zampini + pc - the BDDC preconditioning context (setup must be already called) 11513425bc38SStefano Zampini 11523425bc38SStefano Zampini Level: developer 11533425bc38SStefano Zampini 11543425bc38SStefano Zampini Notes: 11553425bc38SStefano Zampini 11563425bc38SStefano Zampini .seealso: PCBDDC 11573425bc38SStefano Zampini @*/ 11583425bc38SStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 11593425bc38SStefano Zampini { 11603425bc38SStefano Zampini PetscErrorCode ierr; 11613425bc38SStefano Zampini 11623425bc38SStefano Zampini PetscFunctionBegin; 11633425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 11643425bc38SStefano Zampini if (pc->setupcalled) { 11653425bc38SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,Mat*,PC*),(pc,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 1166f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n"); 11673425bc38SStefano Zampini PetscFunctionReturn(0); 11683425bc38SStefano Zampini } 11690c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1170da1bb401SStefano Zampini /*MC 1171da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 11720c7d97c5SJed Brown 1173da1bb401SStefano Zampini Options Database Keys: 1174da1bb401SStefano Zampini . -pcbddc ??? - 1175da1bb401SStefano Zampini 1176da1bb401SStefano Zampini Level: intermediate 1177da1bb401SStefano Zampini 1178da1bb401SStefano Zampini Notes: The matrix used with this preconditioner must be of type MATIS 1179da1bb401SStefano Zampini 1180da1bb401SStefano Zampini Unlike more 'conventional' interface preconditioners, this iterates over ALL the 1181da1bb401SStefano Zampini degrees of freedom, NOT just those on the interface (this allows the use of approximate solvers 1182da1bb401SStefano Zampini on the subdomains). 1183da1bb401SStefano Zampini 1184da1bb401SStefano Zampini Options for the coarse grid preconditioner can be set with - 1185da1bb401SStefano Zampini Options for the Dirichlet subproblem can be set with - 1186da1bb401SStefano Zampini Options for the Neumann subproblem can be set with - 1187da1bb401SStefano Zampini 1188da1bb401SStefano Zampini Contributed by Stefano Zampini 1189da1bb401SStefano Zampini 1190da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 1191da1bb401SStefano Zampini M*/ 1192b2573a8aSBarry Smith 1193da1bb401SStefano Zampini #undef __FUNCT__ 1194da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC" 11958cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 1196da1bb401SStefano Zampini { 1197da1bb401SStefano Zampini PetscErrorCode ierr; 1198da1bb401SStefano Zampini PC_BDDC *pcbddc; 1199da1bb401SStefano Zampini 1200da1bb401SStefano Zampini PetscFunctionBegin; 1201da1bb401SStefano Zampini /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 1202da1bb401SStefano Zampini ierr = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr); 1203da1bb401SStefano Zampini pc->data = (void*)pcbddc; 1204da1bb401SStefano Zampini 1205da1bb401SStefano Zampini /* create PCIS data structure */ 1206da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 1207da1bb401SStefano Zampini 1208da1bb401SStefano Zampini /* BDDC specific */ 1209674ae819SStefano Zampini pcbddc->user_primal_vertices = 0; 12100bdf917eSStefano Zampini pcbddc->NullSpace = 0; 12113972b0daSStefano Zampini pcbddc->temp_solution = 0; 1212534831adSStefano Zampini pcbddc->original_rhs = 0; 1213534831adSStefano Zampini pcbddc->local_mat = 0; 1214534831adSStefano Zampini pcbddc->ChangeOfBasisMatrix = 0; 1215674ae819SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 1216674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 1217da1bb401SStefano Zampini pcbddc->coarse_vec = 0; 1218da1bb401SStefano Zampini pcbddc->coarse_rhs = 0; 1219da1bb401SStefano Zampini pcbddc->coarse_ksp = 0; 1220da1bb401SStefano Zampini pcbddc->coarse_phi_B = 0; 1221da1bb401SStefano Zampini pcbddc->coarse_phi_D = 0; 122215aaf578SStefano Zampini pcbddc->coarse_psi_B = 0; 122315aaf578SStefano Zampini pcbddc->coarse_psi_D = 0; 1224da1bb401SStefano Zampini pcbddc->vec1_P = 0; 1225da1bb401SStefano Zampini pcbddc->vec1_R = 0; 1226da1bb401SStefano Zampini pcbddc->vec2_R = 0; 1227da1bb401SStefano Zampini pcbddc->local_auxmat1 = 0; 1228da1bb401SStefano Zampini pcbddc->local_auxmat2 = 0; 1229da1bb401SStefano Zampini pcbddc->R_to_B = 0; 1230da1bb401SStefano Zampini pcbddc->R_to_D = 0; 1231da1bb401SStefano Zampini pcbddc->ksp_D = 0; 1232da1bb401SStefano Zampini pcbddc->ksp_R = 0; 1233da1bb401SStefano Zampini pcbddc->local_primal_indices = 0; 123429622bf0SStefano Zampini pcbddc->inexact_prec_type = PETSC_FALSE; 1235da1bb401SStefano Zampini pcbddc->NeumannBoundaries = 0; 1236da1bb401SStefano Zampini pcbddc->ISForDofs = 0; 1237da1bb401SStefano Zampini pcbddc->ConstraintMatrix = 0; 1238da1bb401SStefano Zampini pcbddc->use_nnsp_true = PETSC_FALSE; 1239da1bb401SStefano Zampini pcbddc->local_primal_sizes = 0; 1240da1bb401SStefano Zampini pcbddc->local_primal_displacements = 0; 1241da1bb401SStefano Zampini pcbddc->coarse_loc_to_glob = 0; 12429d9e44b6SStefano Zampini pcbddc->dbg_flag = 0; 1243da1bb401SStefano Zampini pcbddc->coarsening_ratio = 8; 1244b76ba322SStefano Zampini pcbddc->use_exact_dirichlet = PETSC_TRUE; 12454fad6a16SStefano Zampini pcbddc->current_level = 0; 12464fad6a16SStefano Zampini pcbddc->max_levels = 1; 1247674ae819SStefano Zampini pcbddc->replicated_local_primal_indices = 0; 1248674ae819SStefano Zampini pcbddc->replicated_local_primal_values = 0; 1249da1bb401SStefano Zampini 1250674ae819SStefano Zampini /* create local graph structure */ 1251674ae819SStefano Zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 1252674ae819SStefano Zampini 1253674ae819SStefano Zampini /* scaling */ 1254674ae819SStefano Zampini pcbddc->use_deluxe_scaling = PETSC_FALSE; 1255674ae819SStefano Zampini pcbddc->work_scaling = 0; 1256da1bb401SStefano Zampini 1257da1bb401SStefano Zampini /* function pointers */ 1258da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 1259da1bb401SStefano Zampini pc->ops->applytranspose = 0; 1260da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 1261da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 1262da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 1263da1bb401SStefano Zampini pc->ops->view = 0; 1264da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 1265da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 1266da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 1267534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 1268534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 1269da1bb401SStefano Zampini 1270da1bb401SStefano Zampini /* composing function */ 1271674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 1272bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 1273bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetMaxLevels_C",PCBDDCSetMaxLevels_BDDC);CHKERRQ(ierr); 1274bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",PCBDDCSetNullSpace_BDDC);CHKERRQ(ierr); 1275bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 1276bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 1277bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 1278bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 1279bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseProblemType_C",PCBDDCSetCoarseProblemType_BDDC);CHKERRQ(ierr); 1280bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 1281bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 1282bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 1283bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 1284bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 1285da1bb401SStefano Zampini PetscFunctionReturn(0); 1286da1bb401SStefano Zampini } 12873425bc38SStefano Zampini 1288da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 1289da1bb401SStefano Zampini /* All static functions from now on */ 1290da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 129129622bf0SStefano Zampini 129229622bf0SStefano Zampini #undef __FUNCT__ 12934fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel" 12944fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 12954fad6a16SStefano Zampini { 12964fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 12974fad6a16SStefano Zampini 12984fad6a16SStefano Zampini PetscFunctionBegin; 12994fad6a16SStefano Zampini pcbddc->current_level=level; 13004fad6a16SStefano Zampini PetscFunctionReturn(0); 13014fad6a16SStefano Zampini } 13023425bc38SStefano Zampini 13033b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 13040c7d97c5SJed Brown #undef __FUNCT__ 13050c7d97c5SJed Brown #define __FUNCT__ "PCBDDCCoarseSetUp" 130653cdbc3dSStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC pc) 13070c7d97c5SJed Brown { 13080c7d97c5SJed Brown PC_IS* pcis = (PC_IS*)(pc->data); 13090c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 13100c7d97c5SJed Brown IS is_R_local; 1311dcedc2aeSStefano Zampini PetscErrorCode ierr; 1312dcedc2aeSStefano Zampini 1313dcedc2aeSStefano Zampini PetscFunctionBegin; 1314dcedc2aeSStefano Zampini /* compute matrix after change of basis and extract local submatrices */ 1315dcedc2aeSStefano Zampini ierr = PCBDDCSetUpLocalMatrices(pc);CHKERRQ(ierr); 1316dcedc2aeSStefano Zampini 1317dcedc2aeSStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 1318dcedc2aeSStefano Zampini if (pcbddc->NullSpace && pcbddc->use_change_of_basis) { 1319dcedc2aeSStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 1320dcedc2aeSStefano Zampini } 1321dcedc2aeSStefano Zampini 1322dcedc2aeSStefano Zampini /* Allocate needed vectors */ 1323dcedc2aeSStefano Zampini ierr = PCBDDCCreateWorkVectors(pc);CHKERRQ(ierr); 1324dcedc2aeSStefano Zampini 1325dcedc2aeSStefano Zampini /* setup local scatters R_to_B and (optionally) R_to_D : PCBDDCCreateWorkVectors should be called first! */ 1326dcedc2aeSStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc,&is_R_local);CHKERRQ(ierr); 1327dcedc2aeSStefano Zampini 1328dcedc2aeSStefano Zampini /* setup local solvers ksp_D and ksp_R */ 1329dcedc2aeSStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,pcis->is_I_local,is_R_local);CHKERRQ(ierr); 1330dcedc2aeSStefano Zampini 1331*88ebb749SStefano Zampini /* setup local correction and local part of coarse basis */ 1332*88ebb749SStefano Zampini ierr = PCBDDCSetUpCorrectionAndBasis(pc,is_R_local);CHKERRQ(ierr); 13330c7d97c5SJed Brown 13340c7d97c5SJed Brown /* free memory */ 13350c7d97c5SJed Brown ierr = ISDestroy(&is_R_local);CHKERRQ(ierr); 1336674ae819SStefano Zampini 13370c7d97c5SJed Brown PetscFunctionReturn(0); 13380c7d97c5SJed Brown } 13390c7d97c5SJed Brown 13400c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 13410c7d97c5SJed Brown 13427cbb387bSStefano Zampini /* BDDC requires metis 5.0.1 for multilevel */ 13437cbb387bSStefano Zampini #if defined(PETSC_HAVE_METIS) 13447cbb387bSStefano Zampini #include "metis.h" 13457cbb387bSStefano Zampini #define MetisInt idx_t 13467cbb387bSStefano Zampini #define MetisScalar real_t 13477cbb387bSStefano Zampini #endif 13487cbb387bSStefano Zampini 13490c7d97c5SJed Brown #undef __FUNCT__ 1350674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseEnvironment" 1351*88ebb749SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseEnvironment(PC pc,PetscScalar* coarse_submat_vals) 13520c7d97c5SJed Brown { 1353674ae819SStefano Zampini 1354674ae819SStefano Zampini 13550c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 13560c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 13570c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 1358ce94432eSBarry Smith MPI_Comm prec_comm; 13590c7d97c5SJed Brown MPI_Comm coarse_comm; 13600c7d97c5SJed Brown 1361674ae819SStefano Zampini MatNullSpace CoarseNullSpace; 1362674ae819SStefano Zampini 13630c7d97c5SJed Brown /* common to all choiches */ 13640c7d97c5SJed Brown PetscScalar *temp_coarse_mat_vals; 13650c7d97c5SJed Brown PetscScalar *ins_coarse_mat_vals; 13660c7d97c5SJed Brown PetscInt *ins_local_primal_indices; 13670c7d97c5SJed Brown PetscMPIInt *localsizes2,*localdispl2; 13680c7d97c5SJed Brown PetscMPIInt size_prec_comm; 13690c7d97c5SJed Brown PetscMPIInt rank_prec_comm; 13700c7d97c5SJed Brown PetscMPIInt active_rank=MPI_PROC_NULL; 13710c7d97c5SJed Brown PetscMPIInt master_proc=0; 13720c7d97c5SJed Brown PetscInt ins_local_primal_size; 13730c7d97c5SJed Brown /* specific to MULTILEVEL_BDDC */ 13745b08dc53SStefano Zampini PetscMPIInt *ranks_recv=0; 13750c7d97c5SJed Brown PetscMPIInt count_recv=0; 13765b08dc53SStefano Zampini PetscMPIInt rank_coarse_proc_send_to=-1; 13770c7d97c5SJed Brown PetscMPIInt coarse_color = MPI_UNDEFINED; 13780c7d97c5SJed Brown ISLocalToGlobalMapping coarse_ISLG; 13790c7d97c5SJed Brown /* some other variables */ 13800c7d97c5SJed Brown PetscErrorCode ierr; 138119fd82e9SBarry Smith MatType coarse_mat_type; 138219fd82e9SBarry Smith PCType coarse_pc_type; 138319fd82e9SBarry Smith KSPType coarse_ksp_type; 138453cdbc3dSStefano Zampini PC pc_temp; 13854fad6a16SStefano Zampini PetscInt i,j,k; 13863b03a366Sstefano_zampini PetscInt max_it_coarse_ksp=1; /* don't increase this value */ 1387e269702eSStefano Zampini /* verbose output viewer */ 1388e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 13895b08dc53SStefano Zampini PetscInt dbg_flag=pcbddc->dbg_flag; 1390142dfd88SStefano Zampini 1391ea7e1babSStefano Zampini PetscInt offset,offset2; 1392a929c220SStefano Zampini PetscMPIInt im_active,active_procs; 1393523858cfSStefano Zampini PetscInt *dnz,*onz; 1394142dfd88SStefano Zampini 1395142dfd88SStefano Zampini PetscBool setsym,issym=PETSC_FALSE; 13960c7d97c5SJed Brown 13970c7d97c5SJed Brown PetscFunctionBegin; 13984b2d0b89SJed Brown ierr = PetscObjectGetComm((PetscObject)pc,&prec_comm);CHKERRQ(ierr); 13990c7d97c5SJed Brown ins_local_primal_indices = 0; 14000c7d97c5SJed Brown ins_coarse_mat_vals = 0; 14010c7d97c5SJed Brown localsizes2 = 0; 14020c7d97c5SJed Brown localdispl2 = 0; 14030c7d97c5SJed Brown temp_coarse_mat_vals = 0; 14040c7d97c5SJed Brown coarse_ISLG = 0; 14050c7d97c5SJed Brown 140653cdbc3dSStefano Zampini ierr = MPI_Comm_size(prec_comm,&size_prec_comm);CHKERRQ(ierr); 140753cdbc3dSStefano Zampini ierr = MPI_Comm_rank(prec_comm,&rank_prec_comm);CHKERRQ(ierr); 1408142dfd88SStefano Zampini ierr = MatIsSymmetricKnown(pc->pmat,&setsym,&issym);CHKERRQ(ierr); 1409142dfd88SStefano Zampini 1410beed3852SStefano Zampini /* Assign global numbering to coarse dofs */ 1411beed3852SStefano Zampini { 1412674ae819SStefano Zampini PetscInt *auxlocal_primal,*aux_idx; 1413ef028eecSStefano Zampini PetscMPIInt mpi_local_primal_size; 1414ef028eecSStefano Zampini PetscScalar coarsesum,*array; 1415ef028eecSStefano Zampini 1416ef028eecSStefano Zampini mpi_local_primal_size = (PetscMPIInt)pcbddc->local_primal_size; 1417beed3852SStefano Zampini 1418beed3852SStefano Zampini /* Construct needed data structures for message passing */ 1419ffe5efe1SStefano Zampini j = 0; 1420142dfd88SStefano Zampini if (rank_prec_comm == 0 || pcbddc->coarse_problem_type == REPLICATED_BDDC || pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 1421ffe5efe1SStefano Zampini j = size_prec_comm; 1422ffe5efe1SStefano Zampini } 1423ffe5efe1SStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->local_primal_sizes);CHKERRQ(ierr); 1424ffe5efe1SStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 1425beed3852SStefano Zampini /* Gather local_primal_size information for all processes */ 1426142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == REPLICATED_BDDC || pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 14275619798eSStefano Zampini ierr = MPI_Allgather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,prec_comm);CHKERRQ(ierr); 1428ffe5efe1SStefano Zampini } else { 1429ffe5efe1SStefano Zampini ierr = MPI_Gather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 1430ffe5efe1SStefano Zampini } 1431beed3852SStefano Zampini pcbddc->replicated_primal_size = 0; 1432ffe5efe1SStefano Zampini for (i=0; i<j; i++) { 1433beed3852SStefano Zampini pcbddc->local_primal_displacements[i] = pcbddc->replicated_primal_size ; 1434beed3852SStefano Zampini pcbddc->replicated_primal_size += pcbddc->local_primal_sizes[i]; 1435beed3852SStefano Zampini } 1436beed3852SStefano Zampini 1437da1bb401SStefano Zampini /* First let's count coarse dofs. 1438beed3852SStefano Zampini This code fragment assumes that the number of local constraints per connected component 1439beed3852SStefano Zampini is not greater than the number of nodes defined for the connected component 1440beed3852SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 1441ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscInt),&auxlocal_primal);CHKERRQ(ierr); 1442674ae819SStefano Zampini ierr = PCBDDCGetPrimalVerticesLocalIdx(pc,&i,&aux_idx);CHKERRQ(ierr); 1443674ae819SStefano Zampini ierr = PetscMemcpy(auxlocal_primal,aux_idx,i*sizeof(PetscInt));CHKERRQ(ierr); 1444674ae819SStefano Zampini ierr = PetscFree(aux_idx);CHKERRQ(ierr); 1445674ae819SStefano Zampini ierr = PCBDDCGetPrimalConstraintsLocalIdx(pc,&j,&aux_idx);CHKERRQ(ierr); 1446674ae819SStefano Zampini ierr = PetscMemcpy(&auxlocal_primal[i],aux_idx,j*sizeof(PetscInt));CHKERRQ(ierr); 1447674ae819SStefano Zampini ierr = PetscFree(aux_idx);CHKERRQ(ierr); 1448ef028eecSStefano Zampini /* Compute number of coarse dofs */ 1449674ae819SStefano Zampini ierr = PCBDDCSubsetNumbering(prec_comm,matis->mapping,pcbddc->local_primal_size,auxlocal_primal,NULL,&pcbddc->coarse_size,&pcbddc->local_primal_indices);CHKERRQ(ierr); 1450ef028eecSStefano Zampini 1451ef028eecSStefano Zampini if (dbg_flag) { 14522e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14532e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 14542e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Check coarse indices\n");CHKERRQ(ierr); 14552e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 14562e8d2280SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14572fa5cd67SKarl Rupp for (i=0;i<pcbddc->local_primal_size;i++) array[auxlocal_primal[i]]=1.0; 1458beed3852SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14592e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 1460da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1461da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1462da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1463da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1464da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14652e8d2280SStefano Zampini for (i=0;i<pcis->n;i++) { 14662e8d2280SStefano Zampini if (array[i] == 1.0) { 14672e8d2280SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,1,&i,&j);CHKERRQ(ierr); 14682e8d2280SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d: WRONG COARSE INDEX %d (local %d)\n",PetscGlobalRank,j,i);CHKERRQ(ierr); 14692e8d2280SStefano Zampini } 14702e8d2280SStefano Zampini } 14712e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14722e8d2280SStefano Zampini for (i=0;i<pcis->n;i++) { 14735b08dc53SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 14742e8d2280SStefano Zampini } 1475da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14762e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 1477da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1478da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1479da1bb401SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 14802e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem SHOULD be %lf\n",coarsesum);CHKERRQ(ierr); 14812e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14822e8d2280SStefano Zampini } 1483142dfd88SStefano Zampini ierr = PetscFree(auxlocal_primal);CHKERRQ(ierr); 14840bdf917eSStefano Zampini } 14850bdf917eSStefano Zampini 14862e8d2280SStefano Zampini if (dbg_flag) { 14877cf533a6SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem is %d\n",pcbddc->coarse_size);CHKERRQ(ierr); 14889d9e44b6SStefano Zampini if (dbg_flag > 1) { 1489674ae819SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 14902e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1491674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 1492674ae819SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 1493674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_primal_indices[%d]=%d \n",i,pcbddc->local_primal_indices[i]); 1494674ae819SStefano Zampini } 14952e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14962e8d2280SStefano Zampini } 14972e8d2280SStefano Zampini } 14982e8d2280SStefano Zampini 1499a929c220SStefano Zampini im_active = 0; 15002fa5cd67SKarl Rupp if (pcis->n) im_active = 1; 1501a929c220SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,prec_comm);CHKERRQ(ierr); 15020bdf917eSStefano Zampini 15030bdf917eSStefano Zampini /* adapt coarse problem type */ 15047cbb387bSStefano Zampini #if defined(PETSC_HAVE_METIS) 15054fad6a16SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 15064fad6a16SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 1507a929c220SStefano Zampini if ( (active_procs/pcbddc->coarsening_ratio) < 2 ) { 15080bdf917eSStefano Zampini if (dbg_flag) { 1509a929c220SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Not enough active processes on level %d (active %d,ratio %d). Parallel direct solve for coarse problem\n",pcbddc->current_level,active_procs,pcbddc->coarsening_ratio);CHKERRQ(ierr); 15100bdf917eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 15110bdf917eSStefano Zampini } 15120bdf917eSStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 1513142dfd88SStefano Zampini } 15144fad6a16SStefano Zampini } else { 15154fad6a16SStefano Zampini if (dbg_flag) { 1516a929c220SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Max number of levels reached. Using parallel direct solve for coarse problem\n",pcbddc->max_levels,active_procs,pcbddc->coarsening_ratio);CHKERRQ(ierr); 15174fad6a16SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 15184fad6a16SStefano Zampini } 15194fad6a16SStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 15204fad6a16SStefano Zampini } 15214fad6a16SStefano Zampini } 15227cbb387bSStefano Zampini #else 15237cbb387bSStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 15247cbb387bSStefano Zampini #endif 1525beed3852SStefano Zampini 15260c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 15270c7d97c5SJed Brown 1528da1bb401SStefano Zampini case(MULTILEVEL_BDDC): /* we define a coarse mesh where subdomains are elements */ 15290c7d97c5SJed Brown { 15307cbb387bSStefano Zampini #if defined(PETSC_HAVE_METIS) 15310c7d97c5SJed Brown /* we need additional variables */ 15320c7d97c5SJed Brown MetisInt n_subdomains,n_parts,objval,ncon,faces_nvtxs; 15330c7d97c5SJed Brown MetisInt *metis_coarse_subdivision; 15340c7d97c5SJed Brown MetisInt options[METIS_NOPTIONS]; 15350c7d97c5SJed Brown PetscMPIInt size_coarse_comm,rank_coarse_comm; 15360c7d97c5SJed Brown PetscMPIInt procs_jumps_coarse_comm; 15370c7d97c5SJed Brown PetscMPIInt *coarse_subdivision; 15380c7d97c5SJed Brown PetscMPIInt *total_count_recv; 15390c7d97c5SJed Brown PetscMPIInt *total_ranks_recv; 15400c7d97c5SJed Brown PetscMPIInt *displacements_recv; 15410c7d97c5SJed Brown PetscMPIInt *my_faces_connectivity; 15420c7d97c5SJed Brown PetscMPIInt *petsc_faces_adjncy; 15430c7d97c5SJed Brown MetisInt *faces_adjncy; 15440c7d97c5SJed Brown MetisInt *faces_xadj; 15450c7d97c5SJed Brown PetscMPIInt *number_of_faces; 15460c7d97c5SJed Brown PetscMPIInt *faces_displacements; 15470c7d97c5SJed Brown PetscInt *array_int; 15480c7d97c5SJed Brown PetscMPIInt my_faces=0; 15490c7d97c5SJed Brown PetscMPIInt total_faces=0; 15503828260eSStefano Zampini PetscInt ranks_stretching_ratio; 15510c7d97c5SJed Brown 15520c7d97c5SJed Brown /* define some quantities */ 15530c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 15540c7d97c5SJed Brown coarse_mat_type = MATIS; 15550c7d97c5SJed Brown coarse_pc_type = PCBDDC; 1556142dfd88SStefano Zampini coarse_ksp_type = KSPRICHARDSON; 15570c7d97c5SJed Brown 15580c7d97c5SJed Brown /* details of coarse decomposition */ 1559a929c220SStefano Zampini n_subdomains = active_procs; 15600c7d97c5SJed Brown n_parts = n_subdomains/pcbddc->coarsening_ratio; 1561a929c220SStefano Zampini ranks_stretching_ratio = size_prec_comm/active_procs; 15623828260eSStefano Zampini procs_jumps_coarse_comm = pcbddc->coarsening_ratio*ranks_stretching_ratio; 15633828260eSStefano Zampini 1564a929c220SStefano Zampini #if 0 1565a929c220SStefano Zampini PetscMPIInt *old_ranks; 1566a929c220SStefano Zampini PetscInt *new_ranks,*jj,*ii; 1567a929c220SStefano Zampini MatPartitioning mat_part; 1568a929c220SStefano Zampini IS coarse_new_decomposition,is_numbering; 1569a929c220SStefano Zampini PetscViewer viewer_test; 1570a929c220SStefano Zampini MPI_Comm test_coarse_comm; 1571a929c220SStefano Zampini PetscMPIInt test_coarse_color; 1572a929c220SStefano Zampini Mat mat_adj; 1573a929c220SStefano Zampini /* Create new communicator for coarse problem splitting the old one */ 1574a929c220SStefano Zampini /* procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 1575a929c220SStefano Zampini key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator */ 1576a929c220SStefano Zampini test_coarse_color = ( im_active ? 0 : MPI_UNDEFINED ); 1577a929c220SStefano Zampini test_coarse_comm = MPI_COMM_NULL; 1578a929c220SStefano Zampini ierr = MPI_Comm_split(prec_comm,test_coarse_color,rank_prec_comm,&test_coarse_comm);CHKERRQ(ierr); 1579a929c220SStefano Zampini if (im_active) { 1580a929c220SStefano Zampini ierr = PetscMalloc(n_subdomains*sizeof(PetscMPIInt),&old_ranks); 1581a929c220SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscInt),&new_ranks); 1582a929c220SStefano Zampini ierr = MPI_Comm_rank(test_coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 1583a929c220SStefano Zampini ierr = MPI_Comm_size(test_coarse_comm,&j);CHKERRQ(ierr); 1584a929c220SStefano Zampini ierr = MPI_Allgather(&rank_prec_comm,1,MPIU_INT,old_ranks,1,MPIU_INT,test_coarse_comm);CHKERRQ(ierr); 1585674ae819SStefano Zampini for (i=0; i<size_prec_comm; i++) new_ranks[i] = -1; 1586674ae819SStefano Zampini for (i=0; i<n_subdomains; i++) new_ranks[old_ranks[i]] = i; 1587a929c220SStefano Zampini ierr = PetscViewerASCIIOpen(test_coarse_comm,"test_mat_part.out",&viewer_test);CHKERRQ(ierr); 1588a929c220SStefano Zampini k = pcis->n_neigh-1; 1589a929c220SStefano Zampini ierr = PetscMalloc(2*sizeof(PetscInt),&ii); 1590a929c220SStefano Zampini ii[0]=0; 1591a929c220SStefano Zampini ii[1]=k; 1592a929c220SStefano Zampini ierr = PetscMalloc(k*sizeof(PetscInt),&jj); 1593674ae819SStefano Zampini for (i=0; i<k; i++) jj[i]=new_ranks[pcis->neigh[i+1]]; 1594a929c220SStefano Zampini ierr = PetscSortInt(k,jj);CHKERRQ(ierr); 15950298fd71SBarry Smith ierr = MatCreateMPIAdj(test_coarse_comm,1,n_subdomains,ii,jj,NULL,&mat_adj);CHKERRQ(ierr); 1596a929c220SStefano Zampini ierr = MatView(mat_adj,viewer_test);CHKERRQ(ierr); 1597a929c220SStefano Zampini ierr = MatPartitioningCreate(test_coarse_comm,&mat_part);CHKERRQ(ierr); 1598a929c220SStefano Zampini ierr = MatPartitioningSetAdjacency(mat_part,mat_adj);CHKERRQ(ierr); 1599a929c220SStefano Zampini ierr = MatPartitioningSetFromOptions(mat_part);CHKERRQ(ierr); 1600a929c220SStefano Zampini printf("Setting Nparts %d\n",n_parts); 1601a929c220SStefano Zampini ierr = MatPartitioningSetNParts(mat_part,n_parts);CHKERRQ(ierr); 1602a929c220SStefano Zampini ierr = MatPartitioningView(mat_part,viewer_test);CHKERRQ(ierr); 1603a929c220SStefano Zampini ierr = MatPartitioningApply(mat_part,&coarse_new_decomposition);CHKERRQ(ierr); 1604a929c220SStefano Zampini ierr = ISView(coarse_new_decomposition,viewer_test);CHKERRQ(ierr); 1605a929c220SStefano Zampini ierr = ISPartitioningToNumbering(coarse_new_decomposition,&is_numbering);CHKERRQ(ierr); 1606a929c220SStefano Zampini ierr = ISView(is_numbering,viewer_test);CHKERRQ(ierr); 1607a929c220SStefano Zampini ierr = PetscViewerDestroy(&viewer_test);CHKERRQ(ierr); 1608a929c220SStefano Zampini ierr = ISDestroy(&coarse_new_decomposition);CHKERRQ(ierr); 1609a929c220SStefano Zampini ierr = ISDestroy(&is_numbering);CHKERRQ(ierr); 1610a929c220SStefano Zampini ierr = MatPartitioningDestroy(&mat_part);CHKERRQ(ierr); 1611a929c220SStefano Zampini ierr = PetscFree(old_ranks);CHKERRQ(ierr); 1612a929c220SStefano Zampini ierr = PetscFree(new_ranks);CHKERRQ(ierr); 1613a929c220SStefano Zampini ierr = MPI_Comm_free(&test_coarse_comm);CHKERRQ(ierr); 1614a929c220SStefano Zampini } 1615a929c220SStefano Zampini #endif 1616a929c220SStefano Zampini 16174fad6a16SStefano Zampini /* build CSR graph of subdomains' connectivity */ 16180c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&array_int);CHKERRQ(ierr); 16193828260eSStefano Zampini ierr = PetscMemzero(array_int,pcis->n*sizeof(PetscInt));CHKERRQ(ierr); 16200c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++){/* i=1 so I don't count myself -> faces nodes counts to 1 */ 16210c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++){ 16220c7d97c5SJed Brown array_int[ pcis->shared[i][j] ]+=1; 16230c7d97c5SJed Brown } 16240c7d97c5SJed Brown } 16250c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++){ 16260c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++){ 16277cf533a6SStefano Zampini if (array_int[ pcis->shared[i][j] ] > 0 ){ 16280c7d97c5SJed Brown my_faces++; 16290c7d97c5SJed Brown break; 16300c7d97c5SJed Brown } 16310c7d97c5SJed Brown } 16320c7d97c5SJed Brown } 16330c7d97c5SJed Brown 163453cdbc3dSStefano Zampini ierr = MPI_Reduce(&my_faces,&total_faces,1,MPIU_INT,MPI_SUM,master_proc,prec_comm);CHKERRQ(ierr); 16350c7d97c5SJed Brown ierr = PetscMalloc (my_faces*sizeof(PetscInt),&my_faces_connectivity);CHKERRQ(ierr); 16360c7d97c5SJed Brown my_faces=0; 16370c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++){ 16380c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++){ 16397cf533a6SStefano Zampini if (array_int[ pcis->shared[i][j] ] > 0 ){ 16400c7d97c5SJed Brown my_faces_connectivity[my_faces]=pcis->neigh[i]; 16410c7d97c5SJed Brown my_faces++; 16420c7d97c5SJed Brown break; 16430c7d97c5SJed Brown } 16440c7d97c5SJed Brown } 16450c7d97c5SJed Brown } 16460c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 16470c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(PetscMPIInt),&petsc_faces_adjncy);CHKERRQ(ierr); 16480c7d97c5SJed Brown ierr = PetscMalloc (size_prec_comm*sizeof(PetscMPIInt),&number_of_faces);CHKERRQ(ierr); 16490c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(MetisInt),&faces_adjncy);CHKERRQ(ierr); 16500c7d97c5SJed Brown ierr = PetscMalloc ((n_subdomains+1)*sizeof(MetisInt),&faces_xadj);CHKERRQ(ierr); 16510c7d97c5SJed Brown ierr = PetscMalloc ((size_prec_comm+1)*sizeof(PetscMPIInt),&faces_displacements);CHKERRQ(ierr); 16520c7d97c5SJed Brown } 165353cdbc3dSStefano Zampini ierr = MPI_Gather(&my_faces,1,MPIU_INT,&number_of_faces[0],1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 16540c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 16550c7d97c5SJed Brown faces_xadj[0]=0; 16560c7d97c5SJed Brown faces_displacements[0]=0; 16570c7d97c5SJed Brown j=0; 16580c7d97c5SJed Brown for (i=1;i<size_prec_comm+1;i++) { 16590c7d97c5SJed Brown faces_displacements[i]=faces_displacements[i-1]+number_of_faces[i-1]; 16600c7d97c5SJed Brown if (number_of_faces[i-1]) { 16610c7d97c5SJed Brown j++; 16620c7d97c5SJed Brown faces_xadj[j]=faces_xadj[j-1]+number_of_faces[i-1]; 16630c7d97c5SJed Brown } 16640c7d97c5SJed Brown } 16650c7d97c5SJed Brown } 166653cdbc3dSStefano Zampini ierr = MPI_Gatherv(&my_faces_connectivity[0],my_faces,MPIU_INT,&petsc_faces_adjncy[0],number_of_faces,faces_displacements,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 16670c7d97c5SJed Brown ierr = PetscFree(my_faces_connectivity);CHKERRQ(ierr); 16680c7d97c5SJed Brown ierr = PetscFree(array_int);CHKERRQ(ierr); 16690c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 16703828260eSStefano Zampini for (i=0;i<total_faces;i++) faces_adjncy[i]=(MetisInt)(petsc_faces_adjncy[i]/ranks_stretching_ratio); /* cast to MetisInt */ 16710c7d97c5SJed Brown ierr = PetscFree(faces_displacements);CHKERRQ(ierr); 16720c7d97c5SJed Brown ierr = PetscFree(number_of_faces);CHKERRQ(ierr); 16730c7d97c5SJed Brown ierr = PetscFree(petsc_faces_adjncy);CHKERRQ(ierr); 16740c7d97c5SJed Brown } 16750c7d97c5SJed Brown 16760c7d97c5SJed Brown if ( rank_prec_comm == master_proc ) { 1677674ae819SStefano Zampini 16783828260eSStefano Zampini PetscInt heuristic_for_metis=3; 1679674ae819SStefano Zampini 16800c7d97c5SJed Brown ncon=1; 16810c7d97c5SJed Brown faces_nvtxs=n_subdomains; 16820c7d97c5SJed Brown /* partition graoh induced by face connectivity */ 16830c7d97c5SJed Brown ierr = PetscMalloc (n_subdomains*sizeof(MetisInt),&metis_coarse_subdivision);CHKERRQ(ierr); 16840c7d97c5SJed Brown ierr = METIS_SetDefaultOptions(options); 16850c7d97c5SJed Brown /* we need a contiguous partition of the coarse mesh */ 16860c7d97c5SJed Brown options[METIS_OPTION_CONTIG]=1; 16870c7d97c5SJed Brown options[METIS_OPTION_NITER]=30; 16884fad6a16SStefano Zampini if (pcbddc->coarsening_ratio > 1) { 16893828260eSStefano Zampini if (n_subdomains>n_parts*heuristic_for_metis) { 16903828260eSStefano Zampini options[METIS_OPTION_IPTYPE]=METIS_IPTYPE_EDGE; 16913828260eSStefano Zampini options[METIS_OPTION_OBJTYPE]=METIS_OBJTYPE_CUT; 16920c7d97c5SJed Brown ierr = METIS_PartGraphKway(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 1693674ae819SStefano Zampini if (ierr != METIS_OK) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in METIS_PartGraphKway (metis error code %D) called from PCBDDCSetUpCoarseEnvironment\n",ierr); 16943828260eSStefano Zampini } else { 16953828260eSStefano Zampini ierr = METIS_PartGraphRecursive(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 1696674ae819SStefano Zampini if (ierr != METIS_OK) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in METIS_PartGraphRecursive (metis error code %D) called from PCBDDCSetUpCoarseEnvironment\n",ierr); 16973828260eSStefano Zampini } 16984fad6a16SStefano Zampini } else { 16992fa5cd67SKarl Rupp for (i=0;i<n_subdomains;i++) metis_coarse_subdivision[i]=i; 17004fad6a16SStefano Zampini } 17010c7d97c5SJed Brown ierr = PetscFree(faces_xadj);CHKERRQ(ierr); 17020c7d97c5SJed Brown ierr = PetscFree(faces_adjncy);CHKERRQ(ierr); 17030bdf917eSStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&coarse_subdivision);CHKERRQ(ierr); 17042fa5cd67SKarl Rupp 17050c7d97c5SJed Brown /* copy/cast values avoiding possible type conflicts between PETSc, MPI and METIS */ 17062fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) coarse_subdivision[i]=MPI_PROC_NULL; 17072fa5cd67SKarl Rupp for (i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=(PetscInt)(metis_coarse_subdivision[i]); 17080c7d97c5SJed Brown ierr = PetscFree(metis_coarse_subdivision);CHKERRQ(ierr); 17090c7d97c5SJed Brown } 17100c7d97c5SJed Brown 17110c7d97c5SJed Brown /* Create new communicator for coarse problem splitting the old one */ 17120c7d97c5SJed Brown if ( !(rank_prec_comm%procs_jumps_coarse_comm) && rank_prec_comm < procs_jumps_coarse_comm*n_parts ){ 1713da1bb401SStefano Zampini coarse_color=0; /* for communicator splitting */ 1714da1bb401SStefano Zampini active_rank=rank_prec_comm; /* for insertion of matrix values */ 17150c7d97c5SJed Brown } 1716da1bb401SStefano Zampini /* procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 1717da1bb401SStefano Zampini key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator */ 171853cdbc3dSStefano Zampini ierr = MPI_Comm_split(prec_comm,coarse_color,rank_prec_comm,&coarse_comm);CHKERRQ(ierr); 17190c7d97c5SJed Brown 17200c7d97c5SJed Brown if ( coarse_color == 0 ) { 172153cdbc3dSStefano Zampini ierr = MPI_Comm_size(coarse_comm,&size_coarse_comm);CHKERRQ(ierr); 172253cdbc3dSStefano Zampini ierr = MPI_Comm_rank(coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 17230c7d97c5SJed Brown } else { 17240c7d97c5SJed Brown rank_coarse_comm = MPI_PROC_NULL; 17250c7d97c5SJed Brown } 17260c7d97c5SJed Brown 17277cf533a6SStefano Zampini /* master proc take care of arranging and distributing coarse information */ 17280c7d97c5SJed Brown if (rank_coarse_comm == master_proc) { 17290c7d97c5SJed Brown ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&displacements_recv);CHKERRQ(ierr); 17300bdf917eSStefano Zampini ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&total_count_recv);CHKERRQ(ierr); 17310bdf917eSStefano Zampini ierr = PetscMalloc (n_subdomains*sizeof(PetscMPIInt),&total_ranks_recv);CHKERRQ(ierr); 17320c7d97c5SJed Brown /* some initializations */ 17330c7d97c5SJed Brown displacements_recv[0]=0; 17340bdf917eSStefano Zampini ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 17350c7d97c5SJed Brown /* count from how many processes the j-th process of the coarse decomposition will receive data */ 17360bdf917eSStefano Zampini for (j=0;j<size_coarse_comm;j++) { 17370bdf917eSStefano Zampini for (i=0;i<size_prec_comm;i++) { 17382fa5cd67SKarl Rupp if (coarse_subdivision[i]==j) total_count_recv[j]++; 17390bdf917eSStefano Zampini } 17400bdf917eSStefano Zampini } 17410c7d97c5SJed Brown /* displacements needed for scatterv of total_ranks_recv */ 17422fa5cd67SKarl Rupp for (i=1; i<size_coarse_comm; i++) displacements_recv[i]=displacements_recv[i-1]+total_count_recv[i-1]; 17432fa5cd67SKarl Rupp 17440c7d97c5SJed Brown /* Now fill properly total_ranks_recv -> each coarse process will receive the ranks (in prec_comm communicator) of its friend (sending) processes */ 17450c7d97c5SJed Brown ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 17460c7d97c5SJed Brown for (j=0;j<size_coarse_comm;j++) { 17473828260eSStefano Zampini for (i=0;i<size_prec_comm;i++) { 17480c7d97c5SJed Brown if (coarse_subdivision[i]==j) { 17490c7d97c5SJed Brown total_ranks_recv[displacements_recv[j]+total_count_recv[j]]=i; 17503828260eSStefano Zampini total_count_recv[j]+=1; 17510c7d97c5SJed Brown } 17520c7d97c5SJed Brown } 17530c7d97c5SJed Brown } 1754da1bb401SStefano Zampini /*for (j=0;j<size_coarse_comm;j++) { 17553828260eSStefano Zampini printf("process %d in new rank will receive from %d processes (original ranks follows)\n",j,total_count_recv[j]); 17563828260eSStefano Zampini for (i=0;i<total_count_recv[j];i++) { 17573828260eSStefano Zampini printf("%d ",total_ranks_recv[displacements_recv[j]+i]); 17583828260eSStefano Zampini } 17593828260eSStefano Zampini printf("\n"); 1760da1bb401SStefano Zampini }*/ 17610c7d97c5SJed Brown 17620c7d97c5SJed Brown /* identify new decomposition in terms of ranks in the old communicator */ 17630bdf917eSStefano Zampini for (i=0;i<n_subdomains;i++) { 17640bdf917eSStefano Zampini coarse_subdivision[ranks_stretching_ratio*i]=coarse_subdivision[ranks_stretching_ratio*i]*procs_jumps_coarse_comm; 17650bdf917eSStefano Zampini } 1766da1bb401SStefano Zampini /*printf("coarse_subdivision in old end new ranks\n"); 1767674ae819SStefano Zampini for (i=0;i<size_prec_comm;i++) 17683828260eSStefano Zampini if (coarse_subdivision[i]!=MPI_PROC_NULL) { 17693828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]/procs_jumps_coarse_comm); 17703828260eSStefano Zampini } else { 17713828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]); 17723828260eSStefano Zampini } 1773da1bb401SStefano Zampini printf("\n");*/ 17740c7d97c5SJed Brown } 17750c7d97c5SJed Brown 17760c7d97c5SJed Brown /* Scatter new decomposition for send details */ 177753cdbc3dSStefano Zampini ierr = MPI_Scatter(&coarse_subdivision[0],1,MPIU_INT,&rank_coarse_proc_send_to,1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 17780c7d97c5SJed Brown /* Scatter receiving details to members of coarse decomposition */ 17790c7d97c5SJed Brown if ( coarse_color == 0) { 178053cdbc3dSStefano Zampini ierr = MPI_Scatter(&total_count_recv[0],1,MPIU_INT,&count_recv,1,MPIU_INT,master_proc,coarse_comm);CHKERRQ(ierr); 17810c7d97c5SJed Brown ierr = PetscMalloc (count_recv*sizeof(PetscMPIInt),&ranks_recv);CHKERRQ(ierr); 178253cdbc3dSStefano Zampini ierr = MPI_Scatterv(&total_ranks_recv[0],total_count_recv,displacements_recv,MPIU_INT,&ranks_recv[0],count_recv,MPIU_INT,master_proc,coarse_comm);CHKERRQ(ierr); 17830c7d97c5SJed Brown } 17840c7d97c5SJed Brown 1785da1bb401SStefano Zampini /*printf("I will send my matrix data to proc %d\n",rank_coarse_proc_send_to); 1786da1bb401SStefano Zampini if (coarse_color == 0) { 1787da1bb401SStefano Zampini printf("I will receive some matrix data from %d processes (ranks follows)\n",count_recv); 1788da1bb401SStefano Zampini for (i=0;i<count_recv;i++) 1789da1bb401SStefano Zampini printf("%d ",ranks_recv[i]); 1790da1bb401SStefano Zampini printf("\n"); 1791da1bb401SStefano Zampini }*/ 17920c7d97c5SJed Brown 17930c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 17940bdf917eSStefano Zampini ierr = PetscFree(coarse_subdivision);CHKERRQ(ierr); 1795da1bb401SStefano Zampini ierr = PetscFree(total_count_recv);CHKERRQ(ierr); 17960bdf917eSStefano Zampini ierr = PetscFree(total_ranks_recv);CHKERRQ(ierr); 17970c7d97c5SJed Brown ierr = PetscFree(displacements_recv);CHKERRQ(ierr); 17980c7d97c5SJed Brown } 17997cbb387bSStefano Zampini #endif 18000c7d97c5SJed Brown break; 18010c7d97c5SJed Brown } 18020c7d97c5SJed Brown 18030c7d97c5SJed Brown case(REPLICATED_BDDC): 18040c7d97c5SJed Brown 18050c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 18060c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 18070c7d97c5SJed Brown coarse_pc_type = PCLU; 180853cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 18090c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 18100c7d97c5SJed Brown active_rank = rank_prec_comm; 18110c7d97c5SJed Brown break; 18120c7d97c5SJed Brown 18130c7d97c5SJed Brown case(PARALLEL_BDDC): 18140c7d97c5SJed Brown 18150c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 1816674ae819SStefano Zampini coarse_mat_type = MATAIJ; 18170c7d97c5SJed Brown coarse_pc_type = PCREDUNDANT; 181853cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 18190c7d97c5SJed Brown coarse_comm = prec_comm; 18200c7d97c5SJed Brown active_rank = rank_prec_comm; 18210c7d97c5SJed Brown break; 18220c7d97c5SJed Brown 18230c7d97c5SJed Brown case(SEQUENTIAL_BDDC): 18240c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 1825674ae819SStefano Zampini coarse_mat_type = MATAIJ; 18260c7d97c5SJed Brown coarse_pc_type = PCLU; 182753cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 18280c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 18290c7d97c5SJed Brown active_rank = master_proc; 18300c7d97c5SJed Brown break; 18310c7d97c5SJed Brown } 18320c7d97c5SJed Brown 18330c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 18340c7d97c5SJed Brown 18350c7d97c5SJed Brown case(SCATTERS_BDDC): 18360c7d97c5SJed Brown { 18370c7d97c5SJed Brown if (pcbddc->coarse_problem_type==MULTILEVEL_BDDC) { 18380c7d97c5SJed Brown 18392e8d2280SStefano Zampini IS coarse_IS; 18402e8d2280SStefano Zampini 1841523858cfSStefano Zampini if(pcbddc->coarsening_ratio == 1) { 1842523858cfSStefano Zampini ins_local_primal_size = pcbddc->local_primal_size; 1843523858cfSStefano Zampini ins_local_primal_indices = pcbddc->local_primal_indices; 1844523858cfSStefano Zampini if (coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 1845523858cfSStefano Zampini /* nonzeros */ 1846523858cfSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&dnz);CHKERRQ(ierr); 1847523858cfSStefano Zampini ierr = PetscMemzero(dnz,ins_local_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 1848523858cfSStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 1849523858cfSStefano Zampini dnz[i] = ins_local_primal_size; 1850523858cfSStefano Zampini } 1851523858cfSStefano Zampini } else { 18520c7d97c5SJed Brown PetscMPIInt send_size; 1853ef028eecSStefano Zampini PetscMPIInt *send_buffer; 18540c7d97c5SJed Brown PetscInt *aux_ins_indices; 18550c7d97c5SJed Brown PetscInt ii,jj; 18560c7d97c5SJed Brown MPI_Request *requests; 1857ef028eecSStefano Zampini 1858523858cfSStefano Zampini ierr = PetscMalloc(count_recv*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 1859523858cfSStefano Zampini /* reusing pcbddc->local_primal_displacements and pcbddc->replicated_primal_size */ 1860523858cfSStefano Zampini ierr = PetscFree(pcbddc->local_primal_displacements);CHKERRQ(ierr); 1861523858cfSStefano Zampini ierr = PetscMalloc((count_recv+1)*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 1862523858cfSStefano Zampini pcbddc->replicated_primal_size = count_recv; 1863523858cfSStefano Zampini j = 0; 1864523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 1865523858cfSStefano Zampini pcbddc->local_primal_displacements[i] = j; 1866523858cfSStefano Zampini j += pcbddc->local_primal_sizes[ranks_recv[i]]; 1867523858cfSStefano Zampini } 1868523858cfSStefano Zampini pcbddc->local_primal_displacements[count_recv] = j; 1869523858cfSStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 18700c7d97c5SJed Brown /* allocate auxiliary space */ 1871523858cfSStefano Zampini ierr = PetscMalloc(count_recv*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 18720c7d97c5SJed Brown ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscInt),&aux_ins_indices);CHKERRQ(ierr); 18730c7d97c5SJed Brown ierr = PetscMemzero(aux_ins_indices,pcbddc->coarse_size*sizeof(PetscInt));CHKERRQ(ierr); 18740c7d97c5SJed Brown /* allocate stuffs for message massing */ 18750c7d97c5SJed Brown ierr = PetscMalloc((count_recv+1)*sizeof(MPI_Request),&requests);CHKERRQ(ierr); 1876523858cfSStefano Zampini for (i=0;i<count_recv+1;i++) { requests[i]=MPI_REQUEST_NULL; } 1877523858cfSStefano Zampini /* send indices to be inserted */ 1878523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 1879523858cfSStefano Zampini send_size = pcbddc->local_primal_sizes[ranks_recv[i]]; 1880523858cfSStefano Zampini ierr = MPI_Irecv(&pcbddc->replicated_local_primal_indices[pcbddc->local_primal_displacements[i]],send_size,MPIU_INT,ranks_recv[i],999,prec_comm,&requests[i]);CHKERRQ(ierr); 1881523858cfSStefano Zampini } 1882523858cfSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 1883523858cfSStefano Zampini send_size = pcbddc->local_primal_size; 1884ef028eecSStefano Zampini ierr = PetscMalloc(send_size*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 1885ef028eecSStefano Zampini for (i=0;i<send_size;i++) { 1886ef028eecSStefano Zampini send_buffer[i]=(PetscMPIInt)pcbddc->local_primal_indices[i]; 1887ef028eecSStefano Zampini } 1888ef028eecSStefano Zampini ierr = MPI_Isend(send_buffer,send_size,MPIU_INT,rank_coarse_proc_send_to,999,prec_comm,&requests[count_recv]);CHKERRQ(ierr); 1889523858cfSStefano Zampini } 1890523858cfSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 1891ef028eecSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 1892ef028eecSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 1893ef028eecSStefano Zampini } 18940c7d97c5SJed Brown j = 0; 18950c7d97c5SJed Brown for (i=0;i<count_recv;i++) { 18962e8d2280SStefano Zampini ii = pcbddc->local_primal_displacements[i+1]-pcbddc->local_primal_displacements[i]; 18972e8d2280SStefano Zampini localsizes2[i] = ii*ii; 18980c7d97c5SJed Brown localdispl2[i] = j; 18990c7d97c5SJed Brown j += localsizes2[i]; 1900523858cfSStefano Zampini jj = pcbddc->local_primal_displacements[i]; 19014fad6a16SStefano Zampini /* it counts the coarse subdomains sharing the coarse node */ 19022e8d2280SStefano Zampini for (k=0;k<ii;k++) { 19034fad6a16SStefano Zampini aux_ins_indices[pcbddc->replicated_local_primal_indices[jj+k]] += 1; 19040c7d97c5SJed Brown } 19054fad6a16SStefano Zampini } 1906523858cfSStefano Zampini /* temp_coarse_mat_vals used to store matrix values to be received */ 19070c7d97c5SJed Brown ierr = PetscMalloc(j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 19080c7d97c5SJed Brown /* evaluate how many values I will insert in coarse mat */ 19090c7d97c5SJed Brown ins_local_primal_size = 0; 1910ea7e1babSStefano Zampini for (i=0;i<pcbddc->coarse_size;i++) { 1911ea7e1babSStefano Zampini if (aux_ins_indices[i]) { 19120c7d97c5SJed Brown ins_local_primal_size++; 1913ea7e1babSStefano Zampini } 1914ea7e1babSStefano Zampini } 19150c7d97c5SJed Brown /* evaluate indices I will insert in coarse mat */ 19160c7d97c5SJed Brown ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 19170c7d97c5SJed Brown j = 0; 1918ea7e1babSStefano Zampini for(i=0;i<pcbddc->coarse_size;i++) { 1919ea7e1babSStefano Zampini if(aux_ins_indices[i]) { 19202e8d2280SStefano Zampini ins_local_primal_indices[j] = i; 19212e8d2280SStefano Zampini j++; 1922ea7e1babSStefano Zampini } 1923ea7e1babSStefano Zampini } 1924523858cfSStefano Zampini /* processes partecipating in coarse problem receive matrix data from their friends */ 1925523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 1926523858cfSStefano Zampini ierr = MPI_Irecv(&temp_coarse_mat_vals[localdispl2[i]],localsizes2[i],MPIU_SCALAR,ranks_recv[i],666,prec_comm,&requests[i]);CHKERRQ(ierr); 1927523858cfSStefano Zampini } 1928523858cfSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 1929523858cfSStefano Zampini send_size = pcbddc->local_primal_size*pcbddc->local_primal_size; 1930523858cfSStefano Zampini ierr = MPI_Isend(&coarse_submat_vals[0],send_size,MPIU_SCALAR,rank_coarse_proc_send_to,666,prec_comm,&requests[count_recv]);CHKERRQ(ierr); 1931523858cfSStefano Zampini } 1932523858cfSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 1933523858cfSStefano Zampini /* nonzeros */ 1934523858cfSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&dnz);CHKERRQ(ierr); 1935523858cfSStefano Zampini ierr = PetscMemzero(dnz,ins_local_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 19360c7d97c5SJed Brown /* use aux_ins_indices to realize a global to local mapping */ 19370c7d97c5SJed Brown j=0; 19380c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++){ 19390c7d97c5SJed Brown if(aux_ins_indices[i]==0){ 19400c7d97c5SJed Brown aux_ins_indices[i]=-1; 19410c7d97c5SJed Brown } else { 19420c7d97c5SJed Brown aux_ins_indices[i]=j; 19430c7d97c5SJed Brown j++; 19440c7d97c5SJed Brown } 19450c7d97c5SJed Brown } 19464fad6a16SStefano Zampini for (i=0;i<count_recv;i++) { 1947523858cfSStefano Zampini j = pcbddc->local_primal_sizes[ranks_recv[i]]; 1948523858cfSStefano Zampini for (k=0;k<j;k++) { 1949523858cfSStefano Zampini dnz[aux_ins_indices[pcbddc->replicated_local_primal_indices[pcbddc->local_primal_displacements[i]+k]]] += j; 19500c7d97c5SJed Brown } 19510c7d97c5SJed Brown } 1952523858cfSStefano Zampini /* check */ 1953523858cfSStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 1954523858cfSStefano Zampini if (dnz[i] > ins_local_primal_size) { 1955523858cfSStefano Zampini dnz[i] = ins_local_primal_size; 19560c7d97c5SJed Brown } 19570c7d97c5SJed Brown } 19580c7d97c5SJed Brown ierr = PetscFree(requests);CHKERRQ(ierr); 19590c7d97c5SJed Brown ierr = PetscFree(aux_ins_indices);CHKERRQ(ierr); 19600c7d97c5SJed Brown if (coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 19614fad6a16SStefano Zampini } 19620c7d97c5SJed Brown /* create local to global mapping needed by coarse MATIS */ 1963142dfd88SStefano Zampini if (coarse_comm != MPI_COMM_NULL ) {ierr = MPI_Comm_free(&coarse_comm);CHKERRQ(ierr);} 19640c7d97c5SJed Brown coarse_comm = prec_comm; 19650c7d97c5SJed Brown active_rank = rank_prec_comm; 19660c7d97c5SJed Brown ierr = ISCreateGeneral(coarse_comm,ins_local_primal_size,ins_local_primal_indices,PETSC_COPY_VALUES,&coarse_IS);CHKERRQ(ierr); 19670c7d97c5SJed Brown ierr = ISLocalToGlobalMappingCreateIS(coarse_IS,&coarse_ISLG);CHKERRQ(ierr); 19680c7d97c5SJed Brown ierr = ISDestroy(&coarse_IS);CHKERRQ(ierr); 19692e8d2280SStefano Zampini } else if (pcbddc->coarse_problem_type==PARALLEL_BDDC) { 19700c7d97c5SJed Brown /* arrays for values insertion */ 19710c7d97c5SJed Brown ins_local_primal_size = pcbddc->local_primal_size; 19722e8d2280SStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 19730c7d97c5SJed Brown ierr = PetscMalloc(ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 19740c7d97c5SJed Brown for (j=0;j<ins_local_primal_size;j++){ 19750c7d97c5SJed Brown ins_local_primal_indices[j]=pcbddc->local_primal_indices[j]; 19764fad6a16SStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 19774fad6a16SStefano Zampini ins_coarse_mat_vals[j*ins_local_primal_size+i]=coarse_submat_vals[j*ins_local_primal_size+i]; 19784fad6a16SStefano Zampini } 19790c7d97c5SJed Brown } 19800c7d97c5SJed Brown } 19810c7d97c5SJed Brown break; 1982674ae819SStefano Zampini 19830c7d97c5SJed Brown } 19840c7d97c5SJed Brown 19850c7d97c5SJed Brown case(GATHERS_BDDC): 19860c7d97c5SJed Brown { 1987674ae819SStefano Zampini 19880c7d97c5SJed Brown PetscMPIInt mysize,mysize2; 1989ef028eecSStefano Zampini PetscMPIInt *send_buffer; 19900c7d97c5SJed Brown 19910c7d97c5SJed Brown if (rank_prec_comm==active_rank) { 19920c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 19930bdf917eSStefano Zampini ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscScalar),&pcbddc->replicated_local_primal_values);CHKERRQ(ierr); 19940c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 19950c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 19960c7d97c5SJed Brown /* arrays for values insertion */ 19972fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) localsizes2[i]=pcbddc->local_primal_sizes[i]*pcbddc->local_primal_sizes[i]; 19980c7d97c5SJed Brown localdispl2[0]=0; 19992fa5cd67SKarl Rupp for (i=1;i<size_prec_comm;i++) localdispl2[i]=localsizes2[i-1]+localdispl2[i-1]; 20000c7d97c5SJed Brown j=0; 20012fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) j+=localsizes2[i]; 20020c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 20030c7d97c5SJed Brown } 20040c7d97c5SJed Brown 20050c7d97c5SJed Brown mysize=pcbddc->local_primal_size; 20060c7d97c5SJed Brown mysize2=pcbddc->local_primal_size*pcbddc->local_primal_size; 2007ef028eecSStefano Zampini ierr = PetscMalloc(mysize*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 20082fa5cd67SKarl Rupp for (i=0; i<mysize; i++) send_buffer[i]=(PetscMPIInt)pcbddc->local_primal_indices[i]; 20092fa5cd67SKarl Rupp 20100c7d97c5SJed Brown if (pcbddc->coarse_problem_type == SEQUENTIAL_BDDC){ 2011ef028eecSStefano Zampini ierr = MPI_Gatherv(send_buffer,mysize,MPIU_INT,&pcbddc->replicated_local_primal_indices[0],pcbddc->local_primal_sizes,pcbddc->local_primal_displacements,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 201253cdbc3dSStefano Zampini ierr = MPI_Gatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,master_proc,prec_comm);CHKERRQ(ierr); 20130c7d97c5SJed Brown } else { 2014ef028eecSStefano Zampini ierr = MPI_Allgatherv(send_buffer,mysize,MPIU_INT,&pcbddc->replicated_local_primal_indices[0],pcbddc->local_primal_sizes,pcbddc->local_primal_displacements,MPIU_INT,prec_comm);CHKERRQ(ierr); 201553cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,prec_comm);CHKERRQ(ierr); 20160c7d97c5SJed Brown } 2017ef028eecSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 20180c7d97c5SJed Brown break; 2019da1bb401SStefano Zampini }/* switch on coarse problem and communications associated with finished */ 20200c7d97c5SJed Brown } 20210c7d97c5SJed Brown 20220c7d97c5SJed Brown /* Now create and fill up coarse matrix */ 20230c7d97c5SJed Brown if ( rank_prec_comm == active_rank ) { 2024142dfd88SStefano Zampini 2025142dfd88SStefano Zampini Mat matis_coarse_local_mat; 2026142dfd88SStefano Zampini 20270c7d97c5SJed Brown if (pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 20280c7d97c5SJed Brown ierr = MatCreate(coarse_comm,&pcbddc->coarse_mat);CHKERRQ(ierr); 20290c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_mat,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size);CHKERRQ(ierr); 20300c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_mat,coarse_mat_type);CHKERRQ(ierr); 2031674ae819SStefano Zampini ierr = MatSetOptionsPrefix(pcbddc->coarse_mat,"coarse_");CHKERRQ(ierr); 2032674ae819SStefano Zampini ierr = MatSetFromOptions(pcbddc->coarse_mat);CHKERRQ(ierr); 20333b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 2034da1bb401SStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 20353b03a366Sstefano_zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 20360c7d97c5SJed Brown } else { 20374fad6a16SStefano Zampini ierr = MatCreateIS(coarse_comm,1,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_ISLG,&pcbddc->coarse_mat);CHKERRQ(ierr); 20383b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 20390c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 2040674ae819SStefano Zampini ierr = MatSetOptionsPrefix(pcbddc->coarse_mat,"coarse_");CHKERRQ(ierr); 2041674ae819SStefano Zampini ierr = MatSetFromOptions(pcbddc->coarse_mat);CHKERRQ(ierr); 20423b03a366Sstefano_zampini ierr = MatSetUp(matis_coarse_local_mat);CHKERRQ(ierr); 2043da1bb401SStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 2044a0ba757dSStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 20450c7d97c5SJed Brown } 2046142dfd88SStefano Zampini /* preallocation */ 2047142dfd88SStefano Zampini if (pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 2048ef028eecSStefano Zampini 2049674ae819SStefano Zampini PetscInt lrows,lcols,bs; 2050ef028eecSStefano Zampini 2051142dfd88SStefano Zampini ierr = MatGetLocalSize(pcbddc->coarse_mat,&lrows,&lcols);CHKERRQ(ierr); 2052142dfd88SStefano Zampini ierr = MatPreallocateInitialize(coarse_comm,lrows,lcols,dnz,onz);CHKERRQ(ierr); 2053674ae819SStefano Zampini ierr = MatGetBlockSize(pcbddc->coarse_mat,&bs);CHKERRQ(ierr); 2054ef028eecSStefano Zampini 2055142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == PARALLEL_BDDC) { 2056ef028eecSStefano Zampini 2057ef028eecSStefano Zampini Vec vec_dnz,vec_onz; 2058ef028eecSStefano Zampini PetscScalar *my_dnz,*my_onz,*array; 2059ef028eecSStefano Zampini PetscInt *mat_ranges,*row_ownership; 2060ef028eecSStefano Zampini PetscInt coarse_index_row,coarse_index_col,owner; 2061ef028eecSStefano Zampini 2062ef028eecSStefano Zampini ierr = VecCreate(prec_comm,&vec_dnz);CHKERRQ(ierr); 2063674ae819SStefano Zampini ierr = VecSetBlockSize(vec_dnz,bs);CHKERRQ(ierr); 2064ef028eecSStefano Zampini ierr = VecSetSizes(vec_dnz,PETSC_DECIDE,pcbddc->coarse_size);CHKERRQ(ierr); 2065ef028eecSStefano Zampini ierr = VecSetType(vec_dnz,VECMPI);CHKERRQ(ierr); 2066ef028eecSStefano Zampini ierr = VecDuplicate(vec_dnz,&vec_onz);CHKERRQ(ierr); 2067ef028eecSStefano Zampini 2068ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscScalar),&my_dnz);CHKERRQ(ierr); 2069ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscScalar),&my_onz);CHKERRQ(ierr); 2070ef028eecSStefano Zampini ierr = PetscMemzero(my_dnz,pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 2071ef028eecSStefano Zampini ierr = PetscMemzero(my_onz,pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 2072ef028eecSStefano Zampini 2073ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscInt),&row_ownership);CHKERRQ(ierr); 2074ef028eecSStefano Zampini ierr = MatGetOwnershipRanges(pcbddc->coarse_mat,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 2075142dfd88SStefano Zampini for (i=0;i<size_prec_comm;i++) { 2076ef028eecSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 2077ef028eecSStefano Zampini row_ownership[j]=i; 2078142dfd88SStefano Zampini } 2079142dfd88SStefano Zampini } 2080ef028eecSStefano Zampini 2081ef028eecSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 2082ef028eecSStefano Zampini coarse_index_row = pcbddc->local_primal_indices[i]; 2083ef028eecSStefano Zampini owner = row_ownership[coarse_index_row]; 2084ef028eecSStefano Zampini for (j=i;j<pcbddc->local_primal_size;j++) { 2085ef028eecSStefano Zampini owner = row_ownership[coarse_index_row]; 2086ef028eecSStefano Zampini coarse_index_col = pcbddc->local_primal_indices[j]; 2087ef028eecSStefano Zampini if (coarse_index_col > mat_ranges[owner]-1 && coarse_index_col < mat_ranges[owner+1] ) { 2088ef028eecSStefano Zampini my_dnz[i] += 1.0; 2089142dfd88SStefano Zampini } else { 2090ef028eecSStefano Zampini my_onz[i] += 1.0; 2091142dfd88SStefano Zampini } 2092ef028eecSStefano Zampini if (i != j) { 2093ef028eecSStefano Zampini owner = row_ownership[coarse_index_col]; 2094ef028eecSStefano Zampini if (coarse_index_row > mat_ranges[owner]-1 && coarse_index_row < mat_ranges[owner+1] ) { 2095ef028eecSStefano Zampini my_dnz[j] += 1.0; 2096142dfd88SStefano Zampini } else { 2097ef028eecSStefano Zampini my_onz[j] += 1.0; 2098142dfd88SStefano Zampini } 2099142dfd88SStefano Zampini } 2100142dfd88SStefano Zampini } 2101142dfd88SStefano Zampini } 2102ef028eecSStefano Zampini ierr = VecSet(vec_dnz,0.0);CHKERRQ(ierr); 2103ef028eecSStefano Zampini ierr = VecSet(vec_onz,0.0);CHKERRQ(ierr); 2104a929c220SStefano Zampini if (pcbddc->local_primal_size) { 2105ef028eecSStefano Zampini ierr = VecSetValues(vec_dnz,pcbddc->local_primal_size,pcbddc->local_primal_indices,my_dnz,ADD_VALUES);CHKERRQ(ierr); 2106ef028eecSStefano Zampini ierr = VecSetValues(vec_onz,pcbddc->local_primal_size,pcbddc->local_primal_indices,my_onz,ADD_VALUES);CHKERRQ(ierr); 2107a929c220SStefano Zampini } 2108ef028eecSStefano Zampini ierr = VecAssemblyBegin(vec_dnz);CHKERRQ(ierr); 2109ef028eecSStefano Zampini ierr = VecAssemblyBegin(vec_onz);CHKERRQ(ierr); 2110ef028eecSStefano Zampini ierr = VecAssemblyEnd(vec_dnz);CHKERRQ(ierr); 2111ef028eecSStefano Zampini ierr = VecAssemblyEnd(vec_onz);CHKERRQ(ierr); 2112ef028eecSStefano Zampini j = mat_ranges[rank_prec_comm+1]-mat_ranges[rank_prec_comm]; 2113ef028eecSStefano Zampini ierr = VecGetArray(vec_dnz,&array);CHKERRQ(ierr); 21145b08dc53SStefano Zampini for (i=0; i<j; i++) dnz[i] = (PetscInt)PetscRealPart(array[i]); 21152fa5cd67SKarl Rupp 2116ef028eecSStefano Zampini ierr = VecRestoreArray(vec_dnz,&array);CHKERRQ(ierr); 2117ef028eecSStefano Zampini ierr = VecGetArray(vec_onz,&array);CHKERRQ(ierr); 21185b08dc53SStefano Zampini for (i=0;i<j;i++) onz[i] = (PetscInt)PetscRealPart(array[i]); 21192fa5cd67SKarl Rupp 2120ef028eecSStefano Zampini ierr = VecRestoreArray(vec_onz,&array);CHKERRQ(ierr); 2121ef028eecSStefano Zampini ierr = PetscFree(my_dnz);CHKERRQ(ierr); 2122ef028eecSStefano Zampini ierr = PetscFree(my_onz);CHKERRQ(ierr); 2123ef028eecSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 2124ef028eecSStefano Zampini ierr = VecDestroy(&vec_dnz);CHKERRQ(ierr); 2125ef028eecSStefano Zampini ierr = VecDestroy(&vec_onz);CHKERRQ(ierr); 2126142dfd88SStefano Zampini } else { 2127142dfd88SStefano Zampini for (k=0;k<size_prec_comm;k++){ 2128142dfd88SStefano Zampini offset=pcbddc->local_primal_displacements[k]; 2129142dfd88SStefano Zampini offset2=localdispl2[k]; 2130142dfd88SStefano Zampini ins_local_primal_size = pcbddc->local_primal_sizes[k]; 2131ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2132ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2133ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2134ef028eecSStefano Zampini } 2135142dfd88SStefano Zampini for (j=0;j<ins_local_primal_size;j++) { 2136142dfd88SStefano Zampini ierr = MatPreallocateSet(ins_local_primal_indices[j],ins_local_primal_size,ins_local_primal_indices,dnz,onz);CHKERRQ(ierr); 2137142dfd88SStefano Zampini } 2138ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2139142dfd88SStefano Zampini } 2140142dfd88SStefano Zampini } 21412fa5cd67SKarl Rupp 2142142dfd88SStefano Zampini /* check */ 2143142dfd88SStefano Zampini for (i=0;i<lrows;i++) { 21442fa5cd67SKarl Rupp if (dnz[i]>lcols) dnz[i]=lcols; 21452fa5cd67SKarl Rupp if (onz[i]>pcbddc->coarse_size-lcols) onz[i]=pcbddc->coarse_size-lcols; 2146142dfd88SStefano Zampini } 2147d9a4edebSJed Brown ierr = MatSeqAIJSetPreallocation(pcbddc->coarse_mat,0,dnz);CHKERRQ(ierr); 2148d9a4edebSJed Brown ierr = MatMPIAIJSetPreallocation(pcbddc->coarse_mat,0,dnz,0,onz);CHKERRQ(ierr); 2149142dfd88SStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 2150142dfd88SStefano Zampini } else { 2151523858cfSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis_coarse_local_mat,0,dnz);CHKERRQ(ierr); 2152523858cfSStefano Zampini ierr = PetscFree(dnz);CHKERRQ(ierr); 2153142dfd88SStefano Zampini } 2154142dfd88SStefano Zampini /* insert values */ 2155523858cfSStefano Zampini if (pcbddc->coarse_problem_type == PARALLEL_BDDC) { 21560c7d97c5SJed Brown ierr = MatSetValues(pcbddc->coarse_mat,ins_local_primal_size,ins_local_primal_indices,ins_local_primal_size,ins_local_primal_indices,ins_coarse_mat_vals,ADD_VALUES);CHKERRQ(ierr); 2157523858cfSStefano Zampini } else if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2158523858cfSStefano Zampini if (pcbddc->coarsening_ratio == 1) { 2159523858cfSStefano Zampini ins_coarse_mat_vals = coarse_submat_vals; 2160523858cfSStefano Zampini ierr = MatSetValues(pcbddc->coarse_mat,ins_local_primal_size,ins_local_primal_indices,ins_local_primal_size,ins_local_primal_indices,ins_coarse_mat_vals,INSERT_VALUES);CHKERRQ(ierr); 2161523858cfSStefano Zampini } else { 2162523858cfSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2163523858cfSStefano Zampini for (k=0;k<pcbddc->replicated_primal_size;k++) { 2164523858cfSStefano Zampini offset = pcbddc->local_primal_displacements[k]; 2165523858cfSStefano Zampini offset2 = localdispl2[k]; 2166523858cfSStefano Zampini ins_local_primal_size = pcbddc->local_primal_displacements[k+1]-pcbddc->local_primal_displacements[k]; 2167ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2168ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2169ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2170ef028eecSStefano Zampini } 2171523858cfSStefano Zampini ins_coarse_mat_vals = &temp_coarse_mat_vals[offset2]; 2172523858cfSStefano Zampini ierr = MatSetValues(pcbddc->coarse_mat,ins_local_primal_size,ins_local_primal_indices,ins_local_primal_size,ins_local_primal_indices,ins_coarse_mat_vals,ADD_VALUES);CHKERRQ(ierr); 2173ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2174523858cfSStefano Zampini } 2175523858cfSStefano Zampini } 2176523858cfSStefano Zampini ins_local_primal_indices = 0; 2177523858cfSStefano Zampini ins_coarse_mat_vals = 0; 2178ea7e1babSStefano Zampini } else { 2179ea7e1babSStefano Zampini for (k=0;k<size_prec_comm;k++){ 2180ea7e1babSStefano Zampini offset=pcbddc->local_primal_displacements[k]; 2181ea7e1babSStefano Zampini offset2=localdispl2[k]; 2182ea7e1babSStefano Zampini ins_local_primal_size = pcbddc->local_primal_sizes[k]; 2183ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2184ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2185ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2186ef028eecSStefano Zampini } 2187ea7e1babSStefano Zampini ins_coarse_mat_vals = &temp_coarse_mat_vals[offset2]; 2188ea7e1babSStefano Zampini ierr = MatSetValues(pcbddc->coarse_mat,ins_local_primal_size,ins_local_primal_indices,ins_local_primal_size,ins_local_primal_indices,ins_coarse_mat_vals,ADD_VALUES);CHKERRQ(ierr); 2189ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2190ea7e1babSStefano Zampini } 2191ea7e1babSStefano Zampini ins_local_primal_indices = 0; 2192ea7e1babSStefano Zampini ins_coarse_mat_vals = 0; 2193ea7e1babSStefano Zampini } 21940c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 21950c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2196142dfd88SStefano Zampini /* symmetry of coarse matrix */ 2197142dfd88SStefano Zampini if (issym) { 2198142dfd88SStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 2199142dfd88SStefano Zampini } 22000c7d97c5SJed Brown ierr = MatGetVecs(pcbddc->coarse_mat,&pcbddc->coarse_vec,&pcbddc->coarse_rhs);CHKERRQ(ierr); 22010bdf917eSStefano Zampini } 22020bdf917eSStefano Zampini 22030bdf917eSStefano Zampini /* create loc to glob scatters if needed */ 22040bdf917eSStefano Zampini if (pcbddc->coarse_communications_type == SCATTERS_BDDC) { 22050bdf917eSStefano Zampini IS local_IS,global_IS; 22060bdf917eSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&local_IS);CHKERRQ(ierr); 22070bdf917eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_indices,PETSC_COPY_VALUES,&global_IS);CHKERRQ(ierr); 22080bdf917eSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,local_IS,pcbddc->coarse_vec,global_IS,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 22090bdf917eSStefano Zampini ierr = ISDestroy(&local_IS);CHKERRQ(ierr); 22100bdf917eSStefano Zampini ierr = ISDestroy(&global_IS);CHKERRQ(ierr); 22110bdf917eSStefano Zampini } 22120bdf917eSStefano Zampini 2213a929c220SStefano Zampini /* free memory no longer needed */ 2214a929c220SStefano Zampini if (coarse_ISLG) { ierr = ISLocalToGlobalMappingDestroy(&coarse_ISLG);CHKERRQ(ierr); } 2215a929c220SStefano Zampini if (ins_local_primal_indices) { ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); } 2216a929c220SStefano Zampini if (ins_coarse_mat_vals) { ierr = PetscFree(ins_coarse_mat_vals);CHKERRQ(ierr); } 2217a929c220SStefano Zampini if (localsizes2) { ierr = PetscFree(localsizes2);CHKERRQ(ierr); } 2218a929c220SStefano Zampini if (localdispl2) { ierr = PetscFree(localdispl2);CHKERRQ(ierr); } 2219a929c220SStefano Zampini if (temp_coarse_mat_vals) { ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr); } 2220a929c220SStefano Zampini 2221674ae819SStefano Zampini /* Compute coarse null space */ 2222674ae819SStefano Zampini CoarseNullSpace = 0; 22230bdf917eSStefano Zampini if (pcbddc->NullSpace) { 2224674ae819SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,&CoarseNullSpace);CHKERRQ(ierr); 22250bdf917eSStefano Zampini } 22260bdf917eSStefano Zampini 22270bdf917eSStefano Zampini /* KSP for coarse problem */ 22280bdf917eSStefano Zampini if (rank_prec_comm == active_rank) { 22292e8d2280SStefano Zampini PetscBool isbddc=PETSC_FALSE; 22300bdf917eSStefano Zampini 223153cdbc3dSStefano Zampini ierr = KSPCreate(coarse_comm,&pcbddc->coarse_ksp);CHKERRQ(ierr); 223253cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 223353cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 22343b03a366Sstefano_zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,max_it_coarse_ksp);CHKERRQ(ierr); 223553cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 223653cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 223753cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 22380c7d97c5SJed Brown /* Allow user's customization */ 2239da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,"coarse_");CHKERRQ(ierr); 22400c7d97c5SJed Brown /* Set Up PC for coarse problem BDDC */ 224153cdbc3dSStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 22424fad6a16SStefano Zampini i = pcbddc->current_level+1; 22434fad6a16SStefano Zampini ierr = PCBDDCSetLevel(pc_temp,i);CHKERRQ(ierr); 22444fad6a16SStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 22454fad6a16SStefano Zampini ierr = PCBDDCSetMaxLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 224653cdbc3dSStefano Zampini ierr = PCBDDCSetCoarseProblemType(pc_temp,MULTILEVEL_BDDC);CHKERRQ(ierr); 2247674ae819SStefano Zampini if (CoarseNullSpace) { 2248674ae819SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 2249674ae819SStefano Zampini } 22504fad6a16SStefano Zampini if (dbg_flag) { 22514fad6a16SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------Level %d: Setting up level %d---------------\n",pcbddc->current_level,i);CHKERRQ(ierr); 22524fad6a16SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 225353cdbc3dSStefano Zampini } 2254674ae819SStefano Zampini } else { 2255674ae819SStefano Zampini if (CoarseNullSpace) { 2256674ae819SStefano Zampini ierr = KSPSetNullSpace(pcbddc->coarse_ksp,CoarseNullSpace);CHKERRQ(ierr); 2257674ae819SStefano Zampini } 22584fad6a16SStefano Zampini } 22594fad6a16SStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 226053cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 2261142dfd88SStefano Zampini 22620298fd71SBarry Smith ierr = KSPGetTolerances(pcbddc->coarse_ksp,NULL,NULL,NULL,&j);CHKERRQ(ierr); 22632e8d2280SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 22642e8d2280SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 22652e8d2280SStefano Zampini if (j == 1) { 22662e8d2280SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 22672e8d2280SStefano Zampini if (isbddc) { 22682e8d2280SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc_temp,PETSC_FALSE);CHKERRQ(ierr); 22695619798eSStefano Zampini } 22705619798eSStefano Zampini } 22710c7d97c5SJed Brown } 2272a929c220SStefano Zampini /* Check coarse problem if requested */ 2273142dfd88SStefano Zampini if ( dbg_flag && rank_prec_comm == active_rank ) { 2274142dfd88SStefano Zampini KSP check_ksp; 2275142dfd88SStefano Zampini PC check_pc; 2276142dfd88SStefano Zampini Vec check_vec; 2277142dfd88SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min,lambda_max; 227819fd82e9SBarry Smith KSPType check_ksp_type; 22790c7d97c5SJed Brown 2280142dfd88SStefano Zampini /* Create ksp object suitable for extreme eigenvalues' estimation */ 2281142dfd88SStefano Zampini ierr = KSPCreate(coarse_comm,&check_ksp);CHKERRQ(ierr); 2282142dfd88SStefano Zampini ierr = KSPSetOperators(check_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 22830bdf917eSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 2284142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 22852fa5cd67SKarl Rupp if (issym) check_ksp_type = KSPCG; 22862fa5cd67SKarl Rupp else check_ksp_type = KSPGMRES; 2287142dfd88SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,PETSC_TRUE);CHKERRQ(ierr); 2288142dfd88SStefano Zampini } else { 2289142dfd88SStefano Zampini check_ksp_type = KSPPREONLY; 2290142dfd88SStefano Zampini } 2291142dfd88SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 2292142dfd88SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 2293142dfd88SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 2294142dfd88SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 2295142dfd88SStefano Zampini /* create random vec */ 2296142dfd88SStefano Zampini ierr = VecDuplicate(pcbddc->coarse_vec,&check_vec);CHKERRQ(ierr); 22970298fd71SBarry Smith ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 2298674ae819SStefano Zampini if (CoarseNullSpace) { 22991cb54aadSJed Brown ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 2300674ae819SStefano Zampini } 2301142dfd88SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,check_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 2302142dfd88SStefano Zampini /* solve coarse problem */ 2303142dfd88SStefano Zampini ierr = KSPSolve(check_ksp,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 2304674ae819SStefano Zampini if (CoarseNullSpace) { 23051cb54aadSJed Brown ierr = MatNullSpaceRemove(CoarseNullSpace,pcbddc->coarse_vec);CHKERRQ(ierr); 2306674ae819SStefano Zampini } 2307142dfd88SStefano Zampini /* check coarse problem residual error */ 2308142dfd88SStefano Zampini ierr = VecAXPY(check_vec,-1.0,pcbddc->coarse_vec);CHKERRQ(ierr); 2309142dfd88SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 2310142dfd88SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,check_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 2311142dfd88SStefano Zampini ierr = VecNorm(pcbddc->coarse_rhs,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 2312142dfd88SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 2313142dfd88SStefano Zampini /* get eigenvalue estimation if inexact */ 2314142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2315142dfd88SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); 2316142dfd88SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&k);CHKERRQ(ierr); 2317142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues estimated with %d iterations of %s.\n",k,check_ksp_type);CHKERRQ(ierr); 2318e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues: % 1.14e %1.14e\n",lambda_min,lambda_max);CHKERRQ(ierr); 23193b03a366Sstefano_zampini } 2320142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem exact infty_error : %1.14e\n",infty_error);CHKERRQ(ierr); 2321142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem residual infty_error: %1.14e\n",abs_infty_error);CHKERRQ(ierr); 2322142dfd88SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 232353cdbc3dSStefano Zampini } 2324674ae819SStefano Zampini if (dbg_flag) { 2325da1bb401SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2326da1bb401SStefano Zampini } 2327674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 2328a0ba757dSStefano Zampini 23290c7d97c5SJed Brown PetscFunctionReturn(0); 23300c7d97c5SJed Brown } 23310c7d97c5SJed Brown 2332