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 */ 27*99cc7994SStefano Zampini static PetscErrorCode PCBDDCSetUpSolvers(PC); 28674ae819SStefano Zampini 290c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 300c7d97c5SJed Brown #undef __FUNCT__ 310c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC" 320c7d97c5SJed Brown PetscErrorCode PCSetFromOptions_BDDC(PC pc) 330c7d97c5SJed Brown { 340c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 350c7d97c5SJed Brown PetscErrorCode ierr; 360c7d97c5SJed Brown 370c7d97c5SJed Brown PetscFunctionBegin; 380c7d97c5SJed Brown ierr = PetscOptionsHead("BDDC options");CHKERRQ(ierr); 390c7d97c5SJed Brown /* Verbose debugging of main data structures */ 409d9e44b6SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_check_level" ,"Verbose (debugging) output for PCBDDC" ,"none",pcbddc->dbg_flag ,&pcbddc->dbg_flag ,NULL);CHKERRQ(ierr); 410c7d97c5SJed Brown /* Some customization for default primal space */ 420298fd71SBarry 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); 430298fd71SBarry 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); 440298fd71SBarry 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); 450298fd71SBarry 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); 460c7d97c5SJed Brown /* Coarse solver context */ 476c667b0aSStefano 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 */ 480298fd71SBarry 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); 490c7d97c5SJed Brown /* Two different application of BDDC to the whole set of dofs, internal and interface */ 500298fd71SBarry 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); 51674ae819SStefano 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); 52674ae819SStefano 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); 53674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 54674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 55674ae819SStefano Zampini } 560298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr); 570298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_max_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr); 58674ae819SStefano 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); 590c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 600c7d97c5SJed Brown PetscFunctionReturn(0); 610c7d97c5SJed Brown } 620c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 63674ae819SStefano Zampini #undef __FUNCT__ 64674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS_BDDC" 65674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 66674ae819SStefano Zampini { 67674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 68674ae819SStefano Zampini PetscErrorCode ierr; 691e6b0712SBarry Smith 70674ae819SStefano Zampini PetscFunctionBegin; 71674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 72674ae819SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 73674ae819SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 74674ae819SStefano Zampini PetscFunctionReturn(0); 75674ae819SStefano Zampini } 76674ae819SStefano Zampini #undef __FUNCT__ 77674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS" 78674ae819SStefano Zampini /*@ 79674ae819SStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set user defined primal vertices in PCBDDC. 80674ae819SStefano Zampini 81674ae819SStefano Zampini Not collective 82674ae819SStefano Zampini 83674ae819SStefano Zampini Input Parameters: 84674ae819SStefano Zampini + pc - the preconditioning context 85674ae819SStefano Zampini - PrimalVertices - index sets of primal vertices in local numbering 86674ae819SStefano Zampini 87674ae819SStefano Zampini Level: intermediate 88674ae819SStefano Zampini 89674ae819SStefano Zampini Notes: 90674ae819SStefano Zampini 91674ae819SStefano Zampini .seealso: PCBDDC 92674ae819SStefano Zampini @*/ 93674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 94674ae819SStefano Zampini { 95674ae819SStefano Zampini PetscErrorCode ierr; 96674ae819SStefano Zampini 97674ae819SStefano Zampini PetscFunctionBegin; 98674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 99674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 100674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 101674ae819SStefano Zampini PetscFunctionReturn(0); 102674ae819SStefano Zampini } 103674ae819SStefano Zampini /* -------------------------------------------------------------------------- */ 1040c7d97c5SJed Brown #undef __FUNCT__ 1050c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType_BDDC" 10653cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetCoarseProblemType_BDDC(PC pc, CoarseProblemType CPT) 1070c7d97c5SJed Brown { 1080c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1090c7d97c5SJed Brown 1100c7d97c5SJed Brown PetscFunctionBegin; 1110c7d97c5SJed Brown pcbddc->coarse_problem_type = CPT; 1120c7d97c5SJed Brown PetscFunctionReturn(0); 1130c7d97c5SJed Brown } 1141e6b0712SBarry Smith 1150c7d97c5SJed Brown #undef __FUNCT__ 1160c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType" 11753cdbc3dSStefano Zampini /*@ 1189c0446d6SStefano Zampini PCBDDCSetCoarseProblemType - Set coarse problem type in PCBDDC. 11953cdbc3dSStefano Zampini 1209c0446d6SStefano Zampini Not collective 12153cdbc3dSStefano Zampini 12253cdbc3dSStefano Zampini Input Parameters: 12353cdbc3dSStefano Zampini + pc - the preconditioning context 12453cdbc3dSStefano Zampini - CoarseProblemType - pick a better name and explain what this is 12553cdbc3dSStefano Zampini 12653cdbc3dSStefano Zampini Level: intermediate 12753cdbc3dSStefano Zampini 12853cdbc3dSStefano Zampini Notes: 129da1bb401SStefano Zampini Not collective but all procs must call with same arguments. 13053cdbc3dSStefano Zampini 13153cdbc3dSStefano Zampini .seealso: PCBDDC 13253cdbc3dSStefano Zampini @*/ 1330c7d97c5SJed Brown PetscErrorCode PCBDDCSetCoarseProblemType(PC pc, CoarseProblemType CPT) 1340c7d97c5SJed Brown { 1350c7d97c5SJed Brown PetscErrorCode ierr; 1360c7d97c5SJed Brown 1370c7d97c5SJed Brown PetscFunctionBegin; 1380c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1390c7d97c5SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetCoarseProblemType_C",(PC,CoarseProblemType),(pc,CPT));CHKERRQ(ierr); 1400c7d97c5SJed Brown PetscFunctionReturn(0); 1410c7d97c5SJed Brown } 1420c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1430c7d97c5SJed Brown #undef __FUNCT__ 1444fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio_BDDC" 1454fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 1464fad6a16SStefano Zampini { 1474fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1484fad6a16SStefano Zampini 1494fad6a16SStefano Zampini PetscFunctionBegin; 1504fad6a16SStefano Zampini pcbddc->coarsening_ratio=k; 1514fad6a16SStefano Zampini PetscFunctionReturn(0); 1524fad6a16SStefano Zampini } 1531e6b0712SBarry Smith 1544fad6a16SStefano Zampini #undef __FUNCT__ 1554fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio" 1564fad6a16SStefano Zampini /*@ 1574fad6a16SStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel coarsening 1584fad6a16SStefano Zampini 1594fad6a16SStefano Zampini Logically collective on PC 1604fad6a16SStefano Zampini 1614fad6a16SStefano Zampini Input Parameters: 1624fad6a16SStefano Zampini + pc - the preconditioning context 1634fad6a16SStefano Zampini - k - coarsening ratio 1644fad6a16SStefano Zampini 1654fad6a16SStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level. 1664fad6a16SStefano Zampini 1674fad6a16SStefano Zampini Level: intermediate 1684fad6a16SStefano Zampini 1694fad6a16SStefano Zampini Notes: 1704fad6a16SStefano Zampini 1714fad6a16SStefano Zampini .seealso: PCBDDC 1724fad6a16SStefano Zampini @*/ 1734fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 1744fad6a16SStefano Zampini { 1754fad6a16SStefano Zampini PetscErrorCode ierr; 1764fad6a16SStefano Zampini 1774fad6a16SStefano Zampini PetscFunctionBegin; 1784fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1794fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 1804fad6a16SStefano Zampini PetscFunctionReturn(0); 1814fad6a16SStefano Zampini } 1824fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 1831e6b0712SBarry Smith 1844fad6a16SStefano Zampini #undef __FUNCT__ 1854fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetMaxLevels_BDDC" 1864fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetMaxLevels_BDDC(PC pc,PetscInt max_levels) 1874fad6a16SStefano Zampini { 1884fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1894fad6a16SStefano Zampini 1904fad6a16SStefano Zampini PetscFunctionBegin; 1914fad6a16SStefano Zampini pcbddc->max_levels=max_levels; 1924fad6a16SStefano Zampini PetscFunctionReturn(0); 1934fad6a16SStefano Zampini } 1941e6b0712SBarry Smith 1954fad6a16SStefano Zampini #undef __FUNCT__ 1964fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetMaxLevels" 1974fad6a16SStefano Zampini /*@ 1984fad6a16SStefano Zampini PCBDDCSetMaxLevels - Sets the maximum number of levels within the multilevel approach. 1994fad6a16SStefano Zampini 2004fad6a16SStefano Zampini Logically collective on PC 2014fad6a16SStefano Zampini 2024fad6a16SStefano Zampini Input Parameters: 2034fad6a16SStefano Zampini + pc - the preconditioning context 2044fad6a16SStefano Zampini - max_levels - the maximum number of levels 2054fad6a16SStefano Zampini 2064fad6a16SStefano Zampini Default value is 1, i.e. coarse problem will be solved inexactly with one application 2074fad6a16SStefano Zampini of PCBDDC preconditioner if the multilevel approach is requested. 2084fad6a16SStefano Zampini 2094fad6a16SStefano Zampini Level: intermediate 2104fad6a16SStefano Zampini 2114fad6a16SStefano Zampini Notes: 2124fad6a16SStefano Zampini 2134fad6a16SStefano Zampini .seealso: PCBDDC 2144fad6a16SStefano Zampini @*/ 2154fad6a16SStefano Zampini PetscErrorCode PCBDDCSetMaxLevels(PC pc,PetscInt max_levels) 2164fad6a16SStefano Zampini { 2174fad6a16SStefano Zampini PetscErrorCode ierr; 2184fad6a16SStefano Zampini 2194fad6a16SStefano Zampini PetscFunctionBegin; 2204fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2214fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetMaxLevels_C",(PC,PetscInt),(pc,max_levels));CHKERRQ(ierr); 2224fad6a16SStefano Zampini PetscFunctionReturn(0); 2234fad6a16SStefano Zampini } 2244fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 2251e6b0712SBarry Smith 2264fad6a16SStefano Zampini #undef __FUNCT__ 2270bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace_BDDC" 2280bdf917eSStefano Zampini static PetscErrorCode PCBDDCSetNullSpace_BDDC(PC pc,MatNullSpace NullSpace) 2290bdf917eSStefano Zampini { 2300bdf917eSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2310bdf917eSStefano Zampini PetscErrorCode ierr; 2320bdf917eSStefano Zampini 2330bdf917eSStefano Zampini PetscFunctionBegin; 2340bdf917eSStefano Zampini ierr = PetscObjectReference((PetscObject)NullSpace);CHKERRQ(ierr); 2350bdf917eSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 2360bdf917eSStefano Zampini pcbddc->NullSpace=NullSpace; 2370bdf917eSStefano Zampini PetscFunctionReturn(0); 2380bdf917eSStefano Zampini } 2391e6b0712SBarry Smith 2400bdf917eSStefano Zampini #undef __FUNCT__ 2410bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace" 2420bdf917eSStefano Zampini /*@ 2430bdf917eSStefano Zampini PCBDDCSetNullSpace - Set NullSpace of global operator of BDDC preconditioned mat. 2440bdf917eSStefano Zampini 2450bdf917eSStefano Zampini Logically collective on PC and MatNullSpace 2460bdf917eSStefano Zampini 2470bdf917eSStefano Zampini Input Parameters: 2480bdf917eSStefano Zampini + pc - the preconditioning context 2490bdf917eSStefano Zampini - NullSpace - Null space of the linear operator to be preconditioned. 2500bdf917eSStefano Zampini 2510bdf917eSStefano Zampini Level: intermediate 2520bdf917eSStefano Zampini 2530bdf917eSStefano Zampini Notes: 2540bdf917eSStefano Zampini 2550bdf917eSStefano Zampini .seealso: PCBDDC 2560bdf917eSStefano Zampini @*/ 2570bdf917eSStefano Zampini PetscErrorCode PCBDDCSetNullSpace(PC pc,MatNullSpace NullSpace) 2580bdf917eSStefano Zampini { 2590bdf917eSStefano Zampini PetscErrorCode ierr; 2600bdf917eSStefano Zampini 2610bdf917eSStefano Zampini PetscFunctionBegin; 2620bdf917eSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 263674ae819SStefano Zampini PetscValidHeaderSpecific(NullSpace,MAT_NULLSPACE_CLASSID,2); 2640bdf917eSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNullSpace_C",(PC,MatNullSpace),(pc,NullSpace));CHKERRQ(ierr); 2650bdf917eSStefano Zampini PetscFunctionReturn(0); 2660bdf917eSStefano Zampini } 2670bdf917eSStefano Zampini /* -------------------------------------------------------------------------- */ 2681e6b0712SBarry Smith 2690bdf917eSStefano Zampini #undef __FUNCT__ 2703b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC" 2713b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 2723b03a366Sstefano_zampini { 2733b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2743b03a366Sstefano_zampini PetscErrorCode ierr; 2753b03a366Sstefano_zampini 2763b03a366Sstefano_zampini PetscFunctionBegin; 2773b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 27836e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 27936e030ebSStefano Zampini pcbddc->DirichletBoundaries=DirichletBoundaries; 2803b03a366Sstefano_zampini PetscFunctionReturn(0); 2813b03a366Sstefano_zampini } 2821e6b0712SBarry Smith 2833b03a366Sstefano_zampini #undef __FUNCT__ 2843b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries" 2853b03a366Sstefano_zampini /*@ 286da1bb401SStefano Zampini PCBDDCSetDirichletBoundaries - Set index set defining subdomain part (in local ordering) 287da1bb401SStefano Zampini of Dirichlet boundaries for the global problem. 2883b03a366Sstefano_zampini 2893b03a366Sstefano_zampini Not collective 2903b03a366Sstefano_zampini 2913b03a366Sstefano_zampini Input Parameters: 2923b03a366Sstefano_zampini + pc - the preconditioning context 2930298fd71SBarry Smith - DirichletBoundaries - sequential index set defining the subdomain part of Dirichlet boundaries (can be NULL) 2943b03a366Sstefano_zampini 2953b03a366Sstefano_zampini Level: intermediate 2963b03a366Sstefano_zampini 2973b03a366Sstefano_zampini Notes: 2983b03a366Sstefano_zampini 2993b03a366Sstefano_zampini .seealso: PCBDDC 3003b03a366Sstefano_zampini @*/ 3013b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 3023b03a366Sstefano_zampini { 3033b03a366Sstefano_zampini PetscErrorCode ierr; 3043b03a366Sstefano_zampini 3053b03a366Sstefano_zampini PetscFunctionBegin; 3063b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 307674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 3083b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 3093b03a366Sstefano_zampini PetscFunctionReturn(0); 3103b03a366Sstefano_zampini } 3113b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 3121e6b0712SBarry Smith 3133b03a366Sstefano_zampini #undef __FUNCT__ 3140c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 31553cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 3160c7d97c5SJed Brown { 3170c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 31853cdbc3dSStefano Zampini PetscErrorCode ierr; 3190c7d97c5SJed Brown 3200c7d97c5SJed Brown PetscFunctionBegin; 32153cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 32236e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 32336e030ebSStefano Zampini pcbddc->NeumannBoundaries=NeumannBoundaries; 3240c7d97c5SJed Brown PetscFunctionReturn(0); 3250c7d97c5SJed Brown } 3261e6b0712SBarry Smith 3270c7d97c5SJed Brown #undef __FUNCT__ 3280c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 32957527edcSJed Brown /*@ 330da1bb401SStefano Zampini PCBDDCSetNeumannBoundaries - Set index set defining subdomain part (in local ordering) 331da1bb401SStefano Zampini of Neumann boundaries for the global problem. 33257527edcSJed Brown 3339c0446d6SStefano Zampini Not collective 33457527edcSJed Brown 33557527edcSJed Brown Input Parameters: 33657527edcSJed Brown + pc - the preconditioning context 3370298fd71SBarry Smith - NeumannBoundaries - sequential index set defining the subdomain part of Neumann boundaries (can be NULL) 33857527edcSJed Brown 33957527edcSJed Brown Level: intermediate 34057527edcSJed Brown 34157527edcSJed Brown Notes: 34257527edcSJed Brown 34357527edcSJed Brown .seealso: PCBDDC 34457527edcSJed Brown @*/ 34553cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 3460c7d97c5SJed Brown { 3470c7d97c5SJed Brown PetscErrorCode ierr; 3480c7d97c5SJed Brown 3490c7d97c5SJed Brown PetscFunctionBegin; 3500c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 351674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 35253cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 35353cdbc3dSStefano Zampini PetscFunctionReturn(0); 35453cdbc3dSStefano Zampini } 35553cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 3561e6b0712SBarry Smith 35753cdbc3dSStefano Zampini #undef __FUNCT__ 358da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC" 359da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 360da1bb401SStefano Zampini { 361da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 362da1bb401SStefano Zampini 363da1bb401SStefano Zampini PetscFunctionBegin; 364da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 365da1bb401SStefano Zampini PetscFunctionReturn(0); 366da1bb401SStefano Zampini } 3671e6b0712SBarry Smith 368da1bb401SStefano Zampini #undef __FUNCT__ 369da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries" 370da1bb401SStefano Zampini /*@ 371da1bb401SStefano Zampini PCBDDCGetDirichletBoundaries - Get index set defining subdomain part (in local ordering) 372da1bb401SStefano Zampini of Dirichlet boundaries for the global problem. 373da1bb401SStefano Zampini 374da1bb401SStefano Zampini Not collective 375da1bb401SStefano Zampini 376da1bb401SStefano Zampini Input Parameters: 377da1bb401SStefano Zampini + pc - the preconditioning context 378da1bb401SStefano Zampini 379da1bb401SStefano Zampini Output Parameters: 380da1bb401SStefano Zampini + DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 381da1bb401SStefano Zampini 382da1bb401SStefano Zampini Level: intermediate 383da1bb401SStefano Zampini 384da1bb401SStefano Zampini Notes: 385da1bb401SStefano Zampini 386da1bb401SStefano Zampini .seealso: PCBDDC 387da1bb401SStefano Zampini @*/ 388da1bb401SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 389da1bb401SStefano Zampini { 390da1bb401SStefano Zampini PetscErrorCode ierr; 391da1bb401SStefano Zampini 392da1bb401SStefano Zampini PetscFunctionBegin; 393da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 394da1bb401SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 395da1bb401SStefano Zampini PetscFunctionReturn(0); 396da1bb401SStefano Zampini } 397da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 3981e6b0712SBarry Smith 399da1bb401SStefano Zampini #undef __FUNCT__ 40053cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 40153cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 40253cdbc3dSStefano Zampini { 40353cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 40453cdbc3dSStefano Zampini 40553cdbc3dSStefano Zampini PetscFunctionBegin; 40653cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 40753cdbc3dSStefano Zampini PetscFunctionReturn(0); 40853cdbc3dSStefano Zampini } 4091e6b0712SBarry Smith 41053cdbc3dSStefano Zampini #undef __FUNCT__ 41153cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 41253cdbc3dSStefano Zampini /*@ 413da1bb401SStefano Zampini PCBDDCGetNeumannBoundaries - Get index set defining subdomain part (in local ordering) 414da1bb401SStefano Zampini of Neumann boundaries for the global problem. 41553cdbc3dSStefano Zampini 4169c0446d6SStefano Zampini Not collective 41753cdbc3dSStefano Zampini 41853cdbc3dSStefano Zampini Input Parameters: 41953cdbc3dSStefano Zampini + pc - the preconditioning context 42053cdbc3dSStefano Zampini 42153cdbc3dSStefano Zampini Output Parameters: 42253cdbc3dSStefano Zampini + NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 42353cdbc3dSStefano Zampini 42453cdbc3dSStefano Zampini Level: intermediate 42553cdbc3dSStefano Zampini 42653cdbc3dSStefano Zampini Notes: 42753cdbc3dSStefano Zampini 42853cdbc3dSStefano Zampini .seealso: PCBDDC 42953cdbc3dSStefano Zampini @*/ 43053cdbc3dSStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 43153cdbc3dSStefano Zampini { 43253cdbc3dSStefano Zampini PetscErrorCode ierr; 43353cdbc3dSStefano Zampini 43453cdbc3dSStefano Zampini PetscFunctionBegin; 43553cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 43653cdbc3dSStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 4370c7d97c5SJed Brown PetscFunctionReturn(0); 4380c7d97c5SJed Brown } 43936e030ebSStefano Zampini /* -------------------------------------------------------------------------- */ 4401e6b0712SBarry Smith 44136e030ebSStefano Zampini #undef __FUNCT__ 442da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC" 4431a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 44436e030ebSStefano Zampini { 44536e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 446da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 447da1bb401SStefano Zampini PetscErrorCode ierr; 44836e030ebSStefano Zampini 44936e030ebSStefano Zampini PetscFunctionBegin; 450674ae819SStefano Zampini /* free old CSR */ 451674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 452fb223d50SStefano Zampini /* TODO: PCBDDCGraphSetAdjacency */ 453674ae819SStefano Zampini /* get CSR into graph structure */ 454da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 455674ae819SStefano Zampini ierr = PetscMalloc((nvtxs+1)*sizeof(PetscInt),&mat_graph->xadj);CHKERRQ(ierr); 456674ae819SStefano Zampini ierr = PetscMalloc(xadj[nvtxs]*sizeof(PetscInt),&mat_graph->adjncy);CHKERRQ(ierr); 457674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 458674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 459da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 4601a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 4611a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 462674ae819SStefano Zampini } 463575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 46436e030ebSStefano Zampini PetscFunctionReturn(0); 46536e030ebSStefano Zampini } 4661e6b0712SBarry Smith 46736e030ebSStefano Zampini #undef __FUNCT__ 468da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph" 46936e030ebSStefano Zampini /*@ 470da1bb401SStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set CSR graph of local matrix for use of PCBDDC. 47136e030ebSStefano Zampini 47236e030ebSStefano Zampini Not collective 47336e030ebSStefano Zampini 47436e030ebSStefano Zampini Input Parameters: 47536e030ebSStefano Zampini + pc - the preconditioning context 476da1bb401SStefano Zampini - nvtxs - number of local vertices of the graph 477da1bb401SStefano Zampini - xadj, adjncy - the CSR graph 478da1bb401SStefano Zampini - copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER. In the former case the user must free the array passed in; 479da1bb401SStefano Zampini in the latter case, memory must be obtained with PetscMalloc. 48036e030ebSStefano Zampini 48136e030ebSStefano Zampini Level: intermediate 48236e030ebSStefano Zampini 48336e030ebSStefano Zampini Notes: 48436e030ebSStefano Zampini 48536e030ebSStefano Zampini .seealso: PCBDDC 48636e030ebSStefano Zampini @*/ 4871a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 48836e030ebSStefano Zampini { 489575ad6abSStefano Zampini void (*f)(void) = 0; 49036e030ebSStefano Zampini PetscErrorCode ierr; 49136e030ebSStefano Zampini 49236e030ebSStefano Zampini PetscFunctionBegin; 49336e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 494674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 495674ae819SStefano Zampini PetscValidIntPointer(xadj,4); 496674ae819SStefano Zampini if (copymode != PETSC_COPY_VALUES && copymode != PETSC_OWN_POINTER) { 497674ae819SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d in %s\n",copymode,__FUNCT__); 498da1bb401SStefano Zampini } 49936e030ebSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 500575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 501575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 502575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 503575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 504575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 50536e030ebSStefano Zampini } 50636e030ebSStefano Zampini PetscFunctionReturn(0); 50736e030ebSStefano Zampini } 5089c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 5091e6b0712SBarry Smith 5109c0446d6SStefano Zampini #undef __FUNCT__ 5119c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 5129c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 5139c0446d6SStefano Zampini { 5149c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5159c0446d6SStefano Zampini PetscInt i; 5169c0446d6SStefano Zampini PetscErrorCode ierr; 5179c0446d6SStefano Zampini 5189c0446d6SStefano Zampini PetscFunctionBegin; 519da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 5209c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 5219c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 5229c0446d6SStefano Zampini } 523d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 524da1bb401SStefano Zampini /* allocate space then set */ 5259c0446d6SStefano Zampini ierr = PetscMalloc(n_is*sizeof(IS),&pcbddc->ISForDofs);CHKERRQ(ierr); 5269c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 527da1bb401SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 528da1bb401SStefano Zampini pcbddc->ISForDofs[i]=ISForDofs[i]; 5299c0446d6SStefano Zampini } 5309c0446d6SStefano Zampini pcbddc->n_ISForDofs=n_is; 5319c0446d6SStefano Zampini PetscFunctionReturn(0); 5329c0446d6SStefano Zampini } 5331e6b0712SBarry Smith 5349c0446d6SStefano Zampini #undef __FUNCT__ 5359c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 5369c0446d6SStefano Zampini /*@ 537da1bb401SStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of local mat. 5389c0446d6SStefano Zampini 5399c0446d6SStefano Zampini Not collective 5409c0446d6SStefano Zampini 5419c0446d6SStefano Zampini Input Parameters: 5429c0446d6SStefano Zampini + pc - the preconditioning context 543da1bb401SStefano Zampini - n - number of index sets defining the fields 544da1bb401SStefano Zampini - IS[] - array of IS describing the fields 5459c0446d6SStefano Zampini 5469c0446d6SStefano Zampini Level: intermediate 5479c0446d6SStefano Zampini 5489c0446d6SStefano Zampini Notes: 5499c0446d6SStefano Zampini 5509c0446d6SStefano Zampini .seealso: PCBDDC 5519c0446d6SStefano Zampini @*/ 5529c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 5539c0446d6SStefano Zampini { 5549c0446d6SStefano Zampini PetscErrorCode ierr; 5559c0446d6SStefano Zampini 5569c0446d6SStefano Zampini PetscFunctionBegin; 5579c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5589c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 5599c0446d6SStefano Zampini PetscFunctionReturn(0); 5609c0446d6SStefano Zampini } 561da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 562534831adSStefano Zampini #undef __FUNCT__ 563534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC" 564534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 565534831adSStefano Zampini /* 566534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 567534831adSStefano Zampini guess if a transformation of basis approach has been selected. 5689c0446d6SStefano Zampini 569534831adSStefano Zampini Input Parameter: 570534831adSStefano Zampini + pc - the preconditioner contex 571534831adSStefano Zampini 572534831adSStefano Zampini Application Interface Routine: PCPreSolve() 573534831adSStefano Zampini 574534831adSStefano Zampini Notes: 575534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 576534831adSStefano Zampini the user, but instead is called by KSPSolve(). 577534831adSStefano Zampini */ 578534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 579534831adSStefano Zampini { 580534831adSStefano Zampini PetscErrorCode ierr; 581534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 582534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 583534831adSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 584534831adSStefano Zampini Mat temp_mat; 5853972b0daSStefano Zampini IS dirIS; 5863972b0daSStefano Zampini PetscInt dirsize,i,*is_indices; 5873972b0daSStefano Zampini PetscScalar *array_x,*array_diagonal; 5883972b0daSStefano Zampini Vec used_vec; 5893972b0daSStefano Zampini PetscBool guess_nonzero; 590534831adSStefano Zampini 591534831adSStefano Zampini PetscFunctionBegin; 59262a6ff1dSStefano Zampini /* Creates parallel work vectors used in presolve. */ 59362a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 59462a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 59562a6ff1dSStefano Zampini } 59662a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 59762a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 59862a6ff1dSStefano Zampini } 5993972b0daSStefano Zampini if (x) { 6003972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 6013972b0daSStefano Zampini used_vec = x; 6023972b0daSStefano Zampini } else { 6033972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 6043972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 6053972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 6063972b0daSStefano Zampini } 6073972b0daSStefano Zampini /* hack into ksp data structure PCPreSolve comes earlier in src/ksp/ksp/interface/itfunc.c */ 6083972b0daSStefano Zampini if (ksp) { 6093972b0daSStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&guess_nonzero);CHKERRQ(ierr); 6103972b0daSStefano Zampini if ( !guess_nonzero ) { 6113972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 6123972b0daSStefano Zampini } 6133972b0daSStefano Zampini } 6143308cffdSStefano Zampini 61562a6ff1dSStefano Zampini if (rhs) { /* TODO: wiser handling of rhs removal, which is only needed in case of zeroed rows */ 6163972b0daSStefano Zampini /* store the original rhs */ 6173972b0daSStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 6183972b0daSStefano Zampini 6193972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 6203972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 6213972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 6223972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6233972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6243972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6253972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6263972b0daSStefano Zampini ierr = PCBDDCGetDirichletBoundaries(pc,&dirIS);CHKERRQ(ierr); 6273972b0daSStefano Zampini if (dirIS) { 6283972b0daSStefano Zampini ierr = ISGetSize(dirIS,&dirsize);CHKERRQ(ierr); 6293972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 6303972b0daSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 6313972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6322fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 6333972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6343972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 6353972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 6363972b0daSStefano Zampini } 6373972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6383972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 639b76ba322SStefano Zampini 6403972b0daSStefano Zampini /* remove the computed solution from the rhs */ 6413972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 6423972b0daSStefano Zampini ierr = MatMultAdd(pc->pmat,used_vec,rhs,rhs);CHKERRQ(ierr); 6433972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 6443308cffdSStefano Zampini } 645b76ba322SStefano Zampini 646b76ba322SStefano Zampini /* store partially computed solution and set initial guess */ 6473972b0daSStefano Zampini if (x) { 6483972b0daSStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 6493972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 65015aaf578SStefano Zampini if (pcbddc->use_exact_dirichlet && !pcbddc->coarse_psi_B) { 651b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 652b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 653b76ba322SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 654b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 655b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 656b76ba322SStefano Zampini if (ksp) { 657b76ba322SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 658b76ba322SStefano Zampini } 659b76ba322SStefano Zampini } 6603972b0daSStefano Zampini } 661b76ba322SStefano Zampini 662674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 663b76ba322SStefano Zampini /* swap pointers for local matrices */ 664b76ba322SStefano Zampini temp_mat = matis->A; 665b76ba322SStefano Zampini matis->A = pcbddc->local_mat; 666b76ba322SStefano Zampini pcbddc->local_mat = temp_mat; 6673308cffdSStefano Zampini } 6683308cffdSStefano Zampini if (pcbddc->use_change_of_basis && rhs) { 669b76ba322SStefano Zampini /* Get local rhs and apply transformation of basis */ 670b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 671b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 672b76ba322SStefano Zampini /* from original basis to modified basis */ 673b76ba322SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 674b76ba322SStefano Zampini /* put back modified values into the global vec using INSERT_VALUES copy mode */ 675b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 676b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 677674ae819SStefano Zampini } 6780bdf917eSStefano Zampini if (ksp && pcbddc->NullSpace) { 679d0195637SJed Brown ierr = MatNullSpaceRemove(pcbddc->NullSpace,used_vec);CHKERRQ(ierr); 680d0195637SJed Brown ierr = MatNullSpaceRemove(pcbddc->NullSpace,rhs);CHKERRQ(ierr); 681b76ba322SStefano Zampini } 6820bdf917eSStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 683534831adSStefano Zampini PetscFunctionReturn(0); 684534831adSStefano Zampini } 685534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 686534831adSStefano Zampini #undef __FUNCT__ 687534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC" 688534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 689534831adSStefano Zampini /* 690534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 691534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 692534831adSStefano Zampini 693534831adSStefano Zampini Input Parameter: 694534831adSStefano Zampini + pc - the preconditioner contex 695534831adSStefano Zampini 696534831adSStefano Zampini Application Interface Routine: PCPostSolve() 697534831adSStefano Zampini 698534831adSStefano Zampini Notes: 699534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 700534831adSStefano Zampini the user, but instead is called by KSPSolve(). 701534831adSStefano Zampini */ 702534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 703534831adSStefano Zampini { 704534831adSStefano Zampini PetscErrorCode ierr; 705534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 706534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 707534831adSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 708534831adSStefano Zampini Mat temp_mat; 709534831adSStefano Zampini 710534831adSStefano Zampini PetscFunctionBegin; 711674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 712534831adSStefano Zampini /* swap pointers for local matrices */ 713534831adSStefano Zampini temp_mat = matis->A; 714534831adSStefano Zampini matis->A = pcbddc->local_mat; 715534831adSStefano Zampini pcbddc->local_mat = temp_mat; 7163425bc38SStefano Zampini } 7173308cffdSStefano Zampini if (pcbddc->use_change_of_basis && x) { 718534831adSStefano Zampini /* Get Local boundary and apply transformation of basis to solution vector */ 719534831adSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 720534831adSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 721534831adSStefano Zampini /* from modified basis to original basis */ 722534831adSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 723534831adSStefano Zampini /* put back modified values into the global vec using INSERT_VALUES copy mode */ 724534831adSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 725534831adSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 726534831adSStefano Zampini } 7273972b0daSStefano Zampini /* add solution removed in presolve */ 7283425bc38SStefano Zampini if (x) { 7293425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 7303425bc38SStefano Zampini } 731fb223d50SStefano Zampini /* restore rhs to its original state */ 732fb223d50SStefano Zampini if (rhs) { 733fb223d50SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,rhs);CHKERRQ(ierr); 734fb223d50SStefano Zampini } 735534831adSStefano Zampini PetscFunctionReturn(0); 736534831adSStefano Zampini } 737534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 73853cdbc3dSStefano Zampini #undef __FUNCT__ 73953cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 7400c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 7410c7d97c5SJed Brown /* 7420c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 7430c7d97c5SJed Brown by setting data structures and options. 7440c7d97c5SJed Brown 7450c7d97c5SJed Brown Input Parameter: 74653cdbc3dSStefano Zampini + pc - the preconditioner context 7470c7d97c5SJed Brown 7480c7d97c5SJed Brown Application Interface Routine: PCSetUp() 7490c7d97c5SJed Brown 7500c7d97c5SJed Brown Notes: 7510c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 7520c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 7530c7d97c5SJed Brown */ 75453cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 7550c7d97c5SJed Brown { 7560c7d97c5SJed Brown PetscErrorCode ierr; 7570c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 758674ae819SStefano Zampini MatStructure flag; 759674ae819SStefano Zampini PetscBool computeis,computetopography,computesolvers; 7600c7d97c5SJed Brown 7610c7d97c5SJed Brown PetscFunctionBegin; 762674ae819SStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other nonoverlapping preconditioners */ 7633b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 7649c0446d6SStefano Zampini So, we set to pcnone the Neumann problem of pcis in order to avoid unneeded computation 7650c7d97c5SJed Brown Also, we decide to directly build the (same) Dirichlet problem */ 7660c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localN_pc_type","none");CHKERRQ(ierr); 7670c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localD_pc_type","none");CHKERRQ(ierr); 7683b03a366Sstefano_zampini /* Get stdout for dbg */ 769674ae819SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->dbg_viewer) { 770ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pc),&pcbddc->dbg_viewer);CHKERRQ(ierr); 771e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 772e269702eSStefano Zampini } 773674ae819SStefano Zampini /* first attempt to split work */ 774674ae819SStefano Zampini if (pc->setupcalled) { 775674ae819SStefano Zampini computeis = PETSC_FALSE; 776674ae819SStefano Zampini ierr = PCGetOperators(pc,NULL,NULL,&flag);CHKERRQ(ierr); 777674ae819SStefano Zampini if (flag == SAME_PRECONDITIONER) { 778674ae819SStefano Zampini computetopography = PETSC_FALSE; 779674ae819SStefano Zampini computesolvers = PETSC_FALSE; 780674ae819SStefano Zampini } else if (flag == SAME_NONZERO_PATTERN) { 781674ae819SStefano Zampini computetopography = PETSC_FALSE; 782674ae819SStefano Zampini computesolvers = PETSC_TRUE; 783674ae819SStefano Zampini } else { /* DIFFERENT_NONZERO_PATTERN */ 784674ae819SStefano Zampini computetopography = PETSC_TRUE; 785674ae819SStefano Zampini computesolvers = PETSC_TRUE; 786674ae819SStefano Zampini } 787674ae819SStefano Zampini } else { 788674ae819SStefano Zampini computeis = PETSC_TRUE; 789674ae819SStefano Zampini computetopography = PETSC_TRUE; 790674ae819SStefano Zampini computesolvers = PETSC_TRUE; 791674ae819SStefano Zampini } 792674ae819SStefano Zampini /* Set up all the "iterative substructuring" common block */ 793674ae819SStefano Zampini if (computeis) { 794674ae819SStefano Zampini ierr = PCISSetUp(pc);CHKERRQ(ierr); 795674ae819SStefano Zampini } 796674ae819SStefano Zampini /* Analyze interface and set up local constraint and change of basis matrices */ 797674ae819SStefano Zampini if (computetopography) { 798674ae819SStefano Zampini /* reset data */ 799674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 800674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 801674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 802674ae819SStefano Zampini } 803674ae819SStefano Zampini if (computesolvers) { 804674ae819SStefano Zampini /* reset data */ 805674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 806674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 807*99cc7994SStefano Zampini /* Create coarse and local stuffs */ 808*99cc7994SStefano Zampini ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr); 809674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 8100c7d97c5SJed Brown } 8110c7d97c5SJed Brown PetscFunctionReturn(0); 8120c7d97c5SJed Brown } 8130c7d97c5SJed Brown 8140c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 8150c7d97c5SJed Brown /* 8160c7d97c5SJed Brown PCApply_BDDC - Applies the BDDC preconditioner to a vector. 8170c7d97c5SJed Brown 8180c7d97c5SJed Brown Input Parameters: 8190c7d97c5SJed Brown . pc - the preconditioner context 8200c7d97c5SJed Brown . r - input vector (global) 8210c7d97c5SJed Brown 8220c7d97c5SJed Brown Output Parameter: 8230c7d97c5SJed Brown . z - output vector (global) 8240c7d97c5SJed Brown 8250c7d97c5SJed Brown Application Interface Routine: PCApply() 8260c7d97c5SJed Brown */ 8270c7d97c5SJed Brown #undef __FUNCT__ 8280c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 82953cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 8300c7d97c5SJed Brown { 8310c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 8320c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 8330c7d97c5SJed Brown PetscErrorCode ierr; 8343b03a366Sstefano_zampini const PetscScalar one = 1.0; 8353b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 8362617d88aSStefano Zampini const PetscScalar zero = 0.0; 8370c7d97c5SJed Brown 8380c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 8390c7d97c5SJed Brown NN interface preconditioner changed to BDDC 84029622bf0SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->inexact_prec_type = PETSC_TRUE) */ 8410c7d97c5SJed Brown 8420c7d97c5SJed Brown PetscFunctionBegin; 84315aaf578SStefano Zampini if (!pcbddc->use_exact_dirichlet || pcbddc->coarse_psi_B) { 8440c7d97c5SJed Brown /* First Dirichlet solve */ 8450c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8460c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 84753cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 8480c7d97c5SJed Brown /* 8490c7d97c5SJed Brown Assembling right hand side for BDDC operator 850674ae819SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE) 851674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 8520c7d97c5SJed Brown */ 8530c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 8540c7d97c5SJed Brown ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 85529622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 8560c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 8570c7d97c5SJed Brown ierr = VecCopy(r,z);CHKERRQ(ierr); 8580c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8590c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 860674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 861b76ba322SStefano Zampini } else { 8620bdf917eSStefano Zampini ierr = VecSet(pcis->vec1_D,zero);CHKERRQ(ierr); 863b76ba322SStefano Zampini ierr = VecSet(pcis->vec2_D,zero);CHKERRQ(ierr); 864674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 865b76ba322SStefano Zampini } 866b76ba322SStefano Zampini 8672617d88aSStefano Zampini /* Apply interface preconditioner 8682617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 8692617d88aSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc);CHKERRQ(ierr); 8702617d88aSStefano Zampini 871674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 872674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 8730c7d97c5SJed Brown 8743b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 8750c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8760c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8770c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 87829622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 87953cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr); 8800c7d97c5SJed Brown ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr); 88129622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); } 8820c7d97c5SJed Brown ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr); 8830c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8840c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8850c7d97c5SJed Brown PetscFunctionReturn(0); 8860c7d97c5SJed Brown } 887da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 888674ae819SStefano Zampini 889da1bb401SStefano Zampini #undef __FUNCT__ 890da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC" 891da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 892da1bb401SStefano Zampini { 893da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 894da1bb401SStefano Zampini PetscErrorCode ierr; 895da1bb401SStefano Zampini 896da1bb401SStefano Zampini PetscFunctionBegin; 897da1bb401SStefano Zampini /* free data created by PCIS */ 898da1bb401SStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 899674ae819SStefano Zampini /* free BDDC custom data */ 900674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 901674ae819SStefano Zampini /* destroy objects related to topography */ 902674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 903674ae819SStefano Zampini /* free allocated graph structure */ 904da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr); 905674ae819SStefano Zampini /* free data for scaling operator */ 906674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 907674ae819SStefano Zampini /* free solvers stuff */ 908674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 90933bc96a4SStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 91033bc96a4SStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 911ac78edfcSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 91262a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 91362a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 91462a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 9153425bc38SStefano Zampini /* remove functions */ 916674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 917bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 918bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetMaxLevels_C",NULL);CHKERRQ(ierr); 919bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",NULL);CHKERRQ(ierr); 920bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 921bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 922bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 923bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 924bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseProblemType_C",NULL);CHKERRQ(ierr); 925bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 926bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 927bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 928bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 929bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 930674ae819SStefano Zampini /* Free the private data structure */ 931674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 932da1bb401SStefano Zampini PetscFunctionReturn(0); 933da1bb401SStefano Zampini } 9343425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 9351e6b0712SBarry Smith 9363425bc38SStefano Zampini #undef __FUNCT__ 9373425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC" 9383425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 9393425bc38SStefano Zampini { 940674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 9413425bc38SStefano Zampini PC_IS* pcis; 9423425bc38SStefano Zampini PC_BDDC* pcbddc; 9433425bc38SStefano Zampini PetscErrorCode ierr; 9440c7d97c5SJed Brown 9453425bc38SStefano Zampini PetscFunctionBegin; 9463425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 9473425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 9483425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 9493425bc38SStefano Zampini 9503425bc38SStefano Zampini /* change of basis for physical rhs if needed 9513425bc38SStefano Zampini It also changes the rhs in case of dirichlet boundaries */ 9523308cffdSStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,standard_rhs,NULL);CHKERRQ(ierr); 9533425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 9543425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9553425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 956fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 957fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 9583425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9593425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 960674ae819SStefano Zampini /* Apply partition of unity */ 9613425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 962674ae819SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 96329622bf0SStefano Zampini if (!pcbddc->inexact_prec_type) { 9643425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 9653425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 9663425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 9673425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 9683425bc38SStefano Zampini ierr = VecSet(standard_rhs,0.0);CHKERRQ(ierr); 9693425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9703425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 971674ae819SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 9723425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9733425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9743425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 9753425bc38SStefano Zampini } 9763425bc38SStefano Zampini /* BDDC rhs */ 9773425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 97829622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { 9793425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 9803425bc38SStefano Zampini } 9813425bc38SStefano Zampini /* apply BDDC */ 9823425bc38SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr); 9833425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 9843425bc38SStefano Zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 9853425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 9863425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9873425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9883425bc38SStefano Zampini /* restore original rhs */ 9893425bc38SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,standard_rhs);CHKERRQ(ierr); 9903425bc38SStefano Zampini PetscFunctionReturn(0); 9913425bc38SStefano Zampini } 9921e6b0712SBarry Smith 9933425bc38SStefano Zampini #undef __FUNCT__ 9943425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS" 9953425bc38SStefano Zampini /*@ 9963425bc38SStefano Zampini PCBDDCMatFETIDPGetRHS - Get rhs for FETIDP linear system. 9973425bc38SStefano Zampini 9983425bc38SStefano Zampini Collective 9993425bc38SStefano Zampini 10003425bc38SStefano Zampini Input Parameters: 10013425bc38SStefano Zampini + fetidp_mat - the FETIDP mat obtained by a call to PCBDDCCreateFETIDPOperators 10023425bc38SStefano Zampini + standard_rhs - the rhs of your linear system 10033425bc38SStefano Zampini 10043425bc38SStefano Zampini Output Parameters: 10053425bc38SStefano Zampini + fetidp_flux_rhs - the rhs of the FETIDP linear system 10063425bc38SStefano Zampini 10073425bc38SStefano Zampini Level: developer 10083425bc38SStefano Zampini 10093425bc38SStefano Zampini Notes: 10103425bc38SStefano Zampini 10113425bc38SStefano Zampini .seealso: PCBDDC 10123425bc38SStefano Zampini @*/ 10133425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 10143425bc38SStefano Zampini { 1015674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 10163425bc38SStefano Zampini PetscErrorCode ierr; 10173425bc38SStefano Zampini 10183425bc38SStefano Zampini PetscFunctionBegin; 10193425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10203425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 10213425bc38SStefano Zampini PetscFunctionReturn(0); 10223425bc38SStefano Zampini } 10233425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 10241e6b0712SBarry Smith 10253425bc38SStefano Zampini #undef __FUNCT__ 10263425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC" 10273425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 10283425bc38SStefano Zampini { 1029674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 10303425bc38SStefano Zampini PC_IS* pcis; 10313425bc38SStefano Zampini PC_BDDC* pcbddc; 10323425bc38SStefano Zampini PetscErrorCode ierr; 10333425bc38SStefano Zampini 10343425bc38SStefano Zampini PetscFunctionBegin; 10353425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10363425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 10373425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 10383425bc38SStefano Zampini 10393425bc38SStefano Zampini /* apply B_delta^T */ 10403425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10413425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10423425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 10433425bc38SStefano Zampini /* compute rhs for BDDC application */ 10443425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 104529622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { 10463425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 10473425bc38SStefano Zampini } 10483425bc38SStefano Zampini /* apply BDDC */ 10493425bc38SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr); 10503425bc38SStefano Zampini /* put values into standard global vector */ 10513425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10523425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 105329622bf0SStefano Zampini if (!pcbddc->inexact_prec_type) { 10543425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 10553425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 10563425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_D,-1.0,pcis->vec1_D);CHKERRQ(ierr); 10573425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 10583425bc38SStefano Zampini } 10593425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10603425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10613425bc38SStefano Zampini /* final change of basis if needed 10623425bc38SStefano Zampini Is also sums the dirichlet part removed during RHS assembling */ 10633308cffdSStefano Zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 10643425bc38SStefano Zampini PetscFunctionReturn(0); 10653425bc38SStefano Zampini } 10661e6b0712SBarry Smith 10673425bc38SStefano Zampini #undef __FUNCT__ 10683425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution" 10693425bc38SStefano Zampini /*@ 10703425bc38SStefano Zampini PCBDDCMatFETIDPGetSolution - Get Solution for FETIDP linear system. 10713425bc38SStefano Zampini 10723425bc38SStefano Zampini Collective 10733425bc38SStefano Zampini 10743425bc38SStefano Zampini Input Parameters: 10753425bc38SStefano Zampini + fetidp_mat - the FETIDP mat obtained by a call to PCBDDCCreateFETIDPOperators 10763425bc38SStefano Zampini + fetidp_flux_sol - the solution of the FETIDP linear system 10773425bc38SStefano Zampini 10783425bc38SStefano Zampini Output Parameters: 10793425bc38SStefano Zampini + standard_sol - the solution on the global domain 10803425bc38SStefano Zampini 10813425bc38SStefano Zampini Level: developer 10823425bc38SStefano Zampini 10833425bc38SStefano Zampini Notes: 10843425bc38SStefano Zampini 10853425bc38SStefano Zampini .seealso: PCBDDC 10863425bc38SStefano Zampini @*/ 10873425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 10883425bc38SStefano Zampini { 1089674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 10903425bc38SStefano Zampini PetscErrorCode ierr; 10913425bc38SStefano Zampini 10923425bc38SStefano Zampini PetscFunctionBegin; 10933425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10943425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 10953425bc38SStefano Zampini PetscFunctionReturn(0); 10963425bc38SStefano Zampini } 10973425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 10981e6b0712SBarry Smith 1099f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec); 1100f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat); 1101f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec); 1102f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC); 1103674ae819SStefano Zampini 11043425bc38SStefano Zampini #undef __FUNCT__ 11053425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC" 11063425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 11073425bc38SStefano Zampini { 1108674ae819SStefano Zampini 1109674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 11103425bc38SStefano Zampini Mat newmat; 1111674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 11123425bc38SStefano Zampini PC newpc; 1113ce94432eSBarry Smith MPI_Comm comm; 11143425bc38SStefano Zampini PetscErrorCode ierr; 11153425bc38SStefano Zampini 11163425bc38SStefano Zampini PetscFunctionBegin; 1117ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 11183425bc38SStefano Zampini /* FETIDP linear matrix */ 11193425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 11203425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 11213425bc38SStefano Zampini ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 11223425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 11233425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 11243425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 11253425bc38SStefano Zampini /* FETIDP preconditioner */ 11263425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 11273425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 11283425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 11293425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 11303425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 11313425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 11323425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 11333425bc38SStefano Zampini ierr = PCSetOperators(newpc,newmat,newmat,SAME_PRECONDITIONER);CHKERRQ(ierr); 11343425bc38SStefano Zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 11353425bc38SStefano Zampini /* return pointers for objects created */ 11363425bc38SStefano Zampini *fetidp_mat=newmat; 11373425bc38SStefano Zampini *fetidp_pc=newpc; 11383425bc38SStefano Zampini PetscFunctionReturn(0); 11393425bc38SStefano Zampini } 11401e6b0712SBarry Smith 11413425bc38SStefano Zampini #undef __FUNCT__ 11423425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators" 11433425bc38SStefano Zampini /*@ 11443425bc38SStefano Zampini PCBDDCCreateFETIDPOperators - Create operators for FETIDP. 11453425bc38SStefano Zampini 11463425bc38SStefano Zampini Collective 11473425bc38SStefano Zampini 11483425bc38SStefano Zampini Input Parameters: 11493425bc38SStefano Zampini + pc - the BDDC preconditioning context (setup must be already called) 11503425bc38SStefano Zampini 11513425bc38SStefano Zampini Level: developer 11523425bc38SStefano Zampini 11533425bc38SStefano Zampini Notes: 11543425bc38SStefano Zampini 11553425bc38SStefano Zampini .seealso: PCBDDC 11563425bc38SStefano Zampini @*/ 11573425bc38SStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 11583425bc38SStefano Zampini { 11593425bc38SStefano Zampini PetscErrorCode ierr; 11603425bc38SStefano Zampini 11613425bc38SStefano Zampini PetscFunctionBegin; 11623425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 11633425bc38SStefano Zampini if (pc->setupcalled) { 11643425bc38SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,Mat*,PC*),(pc,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 1165f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n"); 11663425bc38SStefano Zampini PetscFunctionReturn(0); 11673425bc38SStefano Zampini } 11680c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1169da1bb401SStefano Zampini /*MC 1170da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 11710c7d97c5SJed Brown 1172da1bb401SStefano Zampini Options Database Keys: 1173da1bb401SStefano Zampini . -pcbddc ??? - 1174da1bb401SStefano Zampini 1175da1bb401SStefano Zampini Level: intermediate 1176da1bb401SStefano Zampini 1177da1bb401SStefano Zampini Notes: The matrix used with this preconditioner must be of type MATIS 1178da1bb401SStefano Zampini 1179da1bb401SStefano Zampini Unlike more 'conventional' interface preconditioners, this iterates over ALL the 1180da1bb401SStefano Zampini degrees of freedom, NOT just those on the interface (this allows the use of approximate solvers 1181da1bb401SStefano Zampini on the subdomains). 1182da1bb401SStefano Zampini 1183da1bb401SStefano Zampini Options for the coarse grid preconditioner can be set with - 1184da1bb401SStefano Zampini Options for the Dirichlet subproblem can be set with - 1185da1bb401SStefano Zampini Options for the Neumann subproblem can be set with - 1186da1bb401SStefano Zampini 1187da1bb401SStefano Zampini Contributed by Stefano Zampini 1188da1bb401SStefano Zampini 1189da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 1190da1bb401SStefano Zampini M*/ 1191b2573a8aSBarry Smith 1192da1bb401SStefano Zampini #undef __FUNCT__ 1193da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC" 11948cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 1195da1bb401SStefano Zampini { 1196da1bb401SStefano Zampini PetscErrorCode ierr; 1197da1bb401SStefano Zampini PC_BDDC *pcbddc; 1198da1bb401SStefano Zampini 1199da1bb401SStefano Zampini PetscFunctionBegin; 1200da1bb401SStefano Zampini /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 1201da1bb401SStefano Zampini ierr = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr); 1202da1bb401SStefano Zampini pc->data = (void*)pcbddc; 1203da1bb401SStefano Zampini 1204da1bb401SStefano Zampini /* create PCIS data structure */ 1205da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 1206da1bb401SStefano Zampini 1207da1bb401SStefano Zampini /* BDDC specific */ 1208674ae819SStefano Zampini pcbddc->user_primal_vertices = 0; 12090bdf917eSStefano Zampini pcbddc->NullSpace = 0; 12103972b0daSStefano Zampini pcbddc->temp_solution = 0; 1211534831adSStefano Zampini pcbddc->original_rhs = 0; 1212534831adSStefano Zampini pcbddc->local_mat = 0; 1213534831adSStefano Zampini pcbddc->ChangeOfBasisMatrix = 0; 1214674ae819SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 1215674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 1216da1bb401SStefano Zampini pcbddc->coarse_vec = 0; 1217da1bb401SStefano Zampini pcbddc->coarse_rhs = 0; 1218da1bb401SStefano Zampini pcbddc->coarse_ksp = 0; 1219da1bb401SStefano Zampini pcbddc->coarse_phi_B = 0; 1220da1bb401SStefano Zampini pcbddc->coarse_phi_D = 0; 122115aaf578SStefano Zampini pcbddc->coarse_psi_B = 0; 122215aaf578SStefano Zampini pcbddc->coarse_psi_D = 0; 1223da1bb401SStefano Zampini pcbddc->vec1_P = 0; 1224da1bb401SStefano Zampini pcbddc->vec1_R = 0; 1225da1bb401SStefano Zampini pcbddc->vec2_R = 0; 1226da1bb401SStefano Zampini pcbddc->local_auxmat1 = 0; 1227da1bb401SStefano Zampini pcbddc->local_auxmat2 = 0; 1228da1bb401SStefano Zampini pcbddc->R_to_B = 0; 1229da1bb401SStefano Zampini pcbddc->R_to_D = 0; 1230da1bb401SStefano Zampini pcbddc->ksp_D = 0; 1231da1bb401SStefano Zampini pcbddc->ksp_R = 0; 1232da1bb401SStefano Zampini pcbddc->local_primal_indices = 0; 123329622bf0SStefano Zampini pcbddc->inexact_prec_type = PETSC_FALSE; 1234da1bb401SStefano Zampini pcbddc->NeumannBoundaries = 0; 1235da1bb401SStefano Zampini pcbddc->ISForDofs = 0; 1236da1bb401SStefano Zampini pcbddc->ConstraintMatrix = 0; 1237da1bb401SStefano Zampini pcbddc->use_nnsp_true = PETSC_FALSE; 1238da1bb401SStefano Zampini pcbddc->local_primal_sizes = 0; 1239da1bb401SStefano Zampini pcbddc->local_primal_displacements = 0; 1240da1bb401SStefano Zampini pcbddc->coarse_loc_to_glob = 0; 12419d9e44b6SStefano Zampini pcbddc->dbg_flag = 0; 1242da1bb401SStefano Zampini pcbddc->coarsening_ratio = 8; 1243b76ba322SStefano Zampini pcbddc->use_exact_dirichlet = PETSC_TRUE; 12444fad6a16SStefano Zampini pcbddc->current_level = 0; 12454fad6a16SStefano Zampini pcbddc->max_levels = 1; 1246674ae819SStefano Zampini pcbddc->replicated_local_primal_indices = 0; 1247674ae819SStefano Zampini pcbddc->replicated_local_primal_values = 0; 1248da1bb401SStefano Zampini 1249674ae819SStefano Zampini /* create local graph structure */ 1250674ae819SStefano Zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 1251674ae819SStefano Zampini 1252674ae819SStefano Zampini /* scaling */ 1253674ae819SStefano Zampini pcbddc->use_deluxe_scaling = PETSC_FALSE; 1254674ae819SStefano Zampini pcbddc->work_scaling = 0; 1255da1bb401SStefano Zampini 1256da1bb401SStefano Zampini /* function pointers */ 1257da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 1258da1bb401SStefano Zampini pc->ops->applytranspose = 0; 1259da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 1260da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 1261da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 1262da1bb401SStefano Zampini pc->ops->view = 0; 1263da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 1264da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 1265da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 1266534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 1267534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 1268da1bb401SStefano Zampini 1269da1bb401SStefano Zampini /* composing function */ 1270674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 1271bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 1272bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetMaxLevels_C",PCBDDCSetMaxLevels_BDDC);CHKERRQ(ierr); 1273bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",PCBDDCSetNullSpace_BDDC);CHKERRQ(ierr); 1274bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 1275bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 1276bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 1277bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 1278bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseProblemType_C",PCBDDCSetCoarseProblemType_BDDC);CHKERRQ(ierr); 1279bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 1280bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 1281bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 1282bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 1283bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 1284da1bb401SStefano Zampini PetscFunctionReturn(0); 1285da1bb401SStefano Zampini } 12863425bc38SStefano Zampini 1287da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 1288da1bb401SStefano Zampini /* All static functions from now on */ 1289da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 129029622bf0SStefano Zampini 12913b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 12920c7d97c5SJed Brown #undef __FUNCT__ 1293*99cc7994SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 1294*99cc7994SStefano Zampini static PetscErrorCode PCBDDCSetUpSolvers(PC pc) 12950c7d97c5SJed Brown { 12960c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1297dcedc2aeSStefano Zampini PetscErrorCode ierr; 1298dcedc2aeSStefano Zampini 1299dcedc2aeSStefano Zampini PetscFunctionBegin; 1300*99cc7994SStefano Zampini /* Compute matrix after change of basis and extract local submatrices */ 1301dcedc2aeSStefano Zampini ierr = PCBDDCSetUpLocalMatrices(pc);CHKERRQ(ierr); 1302dcedc2aeSStefano Zampini 1303*99cc7994SStefano Zampini /* Allocate needed vectors */ 1304*99cc7994SStefano Zampini ierr = PCBDDCCreateWorkVectors(pc);CHKERRQ(ierr); 1305*99cc7994SStefano Zampini 1306*99cc7994SStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D : PCBDDCCreateWorkVectors should be called first! */ 1307*99cc7994SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 1308*99cc7994SStefano Zampini 1309*99cc7994SStefano Zampini /* Setup local solvers ksp_D and ksp_R */ 1310*99cc7994SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc);CHKERRQ(ierr); 1311*99cc7994SStefano Zampini 1312dcedc2aeSStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 1313dcedc2aeSStefano Zampini if (pcbddc->NullSpace && pcbddc->use_change_of_basis) { 1314dcedc2aeSStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 1315dcedc2aeSStefano Zampini } 1316dcedc2aeSStefano Zampini 131788ebb749SStefano Zampini /* setup local correction and local part of coarse basis */ 13188ce42a96SStefano Zampini ierr = PCBDDCSetUpCoarseLocal(pc);CHKERRQ(ierr); 1319674ae819SStefano Zampini 13200c7d97c5SJed Brown PetscFunctionReturn(0); 13210c7d97c5SJed Brown } 13220c7d97c5SJed Brown 13230c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 13240c7d97c5SJed Brown 13257cbb387bSStefano Zampini /* BDDC requires metis 5.0.1 for multilevel */ 13267cbb387bSStefano Zampini #if defined(PETSC_HAVE_METIS) 13277cbb387bSStefano Zampini #include "metis.h" 13287cbb387bSStefano Zampini #define MetisInt idx_t 13297cbb387bSStefano Zampini #define MetisScalar real_t 13307cbb387bSStefano Zampini #endif 13317cbb387bSStefano Zampini 13320c7d97c5SJed Brown #undef __FUNCT__ 1333674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseEnvironment" 133488ebb749SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseEnvironment(PC pc,PetscScalar* coarse_submat_vals) 13350c7d97c5SJed Brown { 1336674ae819SStefano Zampini 1337674ae819SStefano Zampini 13380c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 13390c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 13400c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 1341ce94432eSBarry Smith MPI_Comm prec_comm; 13420c7d97c5SJed Brown MPI_Comm coarse_comm; 13430c7d97c5SJed Brown 1344674ae819SStefano Zampini MatNullSpace CoarseNullSpace; 1345674ae819SStefano Zampini 13460c7d97c5SJed Brown /* common to all choiches */ 13470c7d97c5SJed Brown PetscScalar *temp_coarse_mat_vals; 13480c7d97c5SJed Brown PetscScalar *ins_coarse_mat_vals; 13490c7d97c5SJed Brown PetscInt *ins_local_primal_indices; 13500c7d97c5SJed Brown PetscMPIInt *localsizes2,*localdispl2; 13510c7d97c5SJed Brown PetscMPIInt size_prec_comm; 13520c7d97c5SJed Brown PetscMPIInt rank_prec_comm; 13530c7d97c5SJed Brown PetscMPIInt active_rank=MPI_PROC_NULL; 13540c7d97c5SJed Brown PetscMPIInt master_proc=0; 13550c7d97c5SJed Brown PetscInt ins_local_primal_size; 13560c7d97c5SJed Brown /* specific to MULTILEVEL_BDDC */ 13575b08dc53SStefano Zampini PetscMPIInt *ranks_recv=0; 13580c7d97c5SJed Brown PetscMPIInt count_recv=0; 13595b08dc53SStefano Zampini PetscMPIInt rank_coarse_proc_send_to=-1; 13600c7d97c5SJed Brown PetscMPIInt coarse_color = MPI_UNDEFINED; 13610c7d97c5SJed Brown ISLocalToGlobalMapping coarse_ISLG; 13620c7d97c5SJed Brown /* some other variables */ 13630c7d97c5SJed Brown PetscErrorCode ierr; 136419fd82e9SBarry Smith MatType coarse_mat_type; 136519fd82e9SBarry Smith PCType coarse_pc_type; 136619fd82e9SBarry Smith KSPType coarse_ksp_type; 136753cdbc3dSStefano Zampini PC pc_temp; 13684fad6a16SStefano Zampini PetscInt i,j,k; 13693b03a366Sstefano_zampini PetscInt max_it_coarse_ksp=1; /* don't increase this value */ 1370e269702eSStefano Zampini /* verbose output viewer */ 1371e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 13725b08dc53SStefano Zampini PetscInt dbg_flag=pcbddc->dbg_flag; 1373142dfd88SStefano Zampini 1374ea7e1babSStefano Zampini PetscInt offset,offset2; 1375a929c220SStefano Zampini PetscMPIInt im_active,active_procs; 1376523858cfSStefano Zampini PetscInt *dnz,*onz; 1377142dfd88SStefano Zampini 1378142dfd88SStefano Zampini PetscBool setsym,issym=PETSC_FALSE; 13790c7d97c5SJed Brown 13800c7d97c5SJed Brown PetscFunctionBegin; 13814b2d0b89SJed Brown ierr = PetscObjectGetComm((PetscObject)pc,&prec_comm);CHKERRQ(ierr); 13820c7d97c5SJed Brown ins_local_primal_indices = 0; 13830c7d97c5SJed Brown ins_coarse_mat_vals = 0; 13840c7d97c5SJed Brown localsizes2 = 0; 13850c7d97c5SJed Brown localdispl2 = 0; 13860c7d97c5SJed Brown temp_coarse_mat_vals = 0; 13870c7d97c5SJed Brown coarse_ISLG = 0; 13880c7d97c5SJed Brown 138953cdbc3dSStefano Zampini ierr = MPI_Comm_size(prec_comm,&size_prec_comm);CHKERRQ(ierr); 139053cdbc3dSStefano Zampini ierr = MPI_Comm_rank(prec_comm,&rank_prec_comm);CHKERRQ(ierr); 1391142dfd88SStefano Zampini ierr = MatIsSymmetricKnown(pc->pmat,&setsym,&issym);CHKERRQ(ierr); 1392142dfd88SStefano Zampini 1393beed3852SStefano Zampini /* Assign global numbering to coarse dofs */ 1394beed3852SStefano Zampini { 1395674ae819SStefano Zampini PetscInt *auxlocal_primal,*aux_idx; 1396ef028eecSStefano Zampini PetscMPIInt mpi_local_primal_size; 1397ef028eecSStefano Zampini PetscScalar coarsesum,*array; 1398ef028eecSStefano Zampini 1399ef028eecSStefano Zampini mpi_local_primal_size = (PetscMPIInt)pcbddc->local_primal_size; 1400beed3852SStefano Zampini 1401beed3852SStefano Zampini /* Construct needed data structures for message passing */ 1402ffe5efe1SStefano Zampini j = 0; 1403142dfd88SStefano Zampini if (rank_prec_comm == 0 || pcbddc->coarse_problem_type == REPLICATED_BDDC || pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 1404ffe5efe1SStefano Zampini j = size_prec_comm; 1405ffe5efe1SStefano Zampini } 1406ffe5efe1SStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->local_primal_sizes);CHKERRQ(ierr); 1407ffe5efe1SStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 1408beed3852SStefano Zampini /* Gather local_primal_size information for all processes */ 1409142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == REPLICATED_BDDC || pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 14105619798eSStefano Zampini ierr = MPI_Allgather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,prec_comm);CHKERRQ(ierr); 1411ffe5efe1SStefano Zampini } else { 1412ffe5efe1SStefano Zampini ierr = MPI_Gather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 1413ffe5efe1SStefano Zampini } 1414beed3852SStefano Zampini pcbddc->replicated_primal_size = 0; 1415ffe5efe1SStefano Zampini for (i=0; i<j; i++) { 1416beed3852SStefano Zampini pcbddc->local_primal_displacements[i] = pcbddc->replicated_primal_size ; 1417beed3852SStefano Zampini pcbddc->replicated_primal_size += pcbddc->local_primal_sizes[i]; 1418beed3852SStefano Zampini } 1419beed3852SStefano Zampini 1420da1bb401SStefano Zampini /* First let's count coarse dofs. 1421beed3852SStefano Zampini This code fragment assumes that the number of local constraints per connected component 1422beed3852SStefano Zampini is not greater than the number of nodes defined for the connected component 1423beed3852SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 1424ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscInt),&auxlocal_primal);CHKERRQ(ierr); 1425674ae819SStefano Zampini ierr = PCBDDCGetPrimalVerticesLocalIdx(pc,&i,&aux_idx);CHKERRQ(ierr); 1426674ae819SStefano Zampini ierr = PetscMemcpy(auxlocal_primal,aux_idx,i*sizeof(PetscInt));CHKERRQ(ierr); 1427674ae819SStefano Zampini ierr = PetscFree(aux_idx);CHKERRQ(ierr); 1428674ae819SStefano Zampini ierr = PCBDDCGetPrimalConstraintsLocalIdx(pc,&j,&aux_idx);CHKERRQ(ierr); 1429674ae819SStefano Zampini ierr = PetscMemcpy(&auxlocal_primal[i],aux_idx,j*sizeof(PetscInt));CHKERRQ(ierr); 1430674ae819SStefano Zampini ierr = PetscFree(aux_idx);CHKERRQ(ierr); 1431ef028eecSStefano Zampini /* Compute number of coarse dofs */ 1432674ae819SStefano Zampini ierr = PCBDDCSubsetNumbering(prec_comm,matis->mapping,pcbddc->local_primal_size,auxlocal_primal,NULL,&pcbddc->coarse_size,&pcbddc->local_primal_indices);CHKERRQ(ierr); 1433ef028eecSStefano Zampini 1434ef028eecSStefano Zampini if (dbg_flag) { 14352e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14362e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 14372e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Check coarse indices\n");CHKERRQ(ierr); 14382e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 14392e8d2280SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14402fa5cd67SKarl Rupp for (i=0;i<pcbddc->local_primal_size;i++) array[auxlocal_primal[i]]=1.0; 1441beed3852SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14422e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 1443da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1444da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1445da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1446da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1447da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14482e8d2280SStefano Zampini for (i=0;i<pcis->n;i++) { 14492e8d2280SStefano Zampini if (array[i] == 1.0) { 14502e8d2280SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,1,&i,&j);CHKERRQ(ierr); 14512e8d2280SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d: WRONG COARSE INDEX %d (local %d)\n",PetscGlobalRank,j,i);CHKERRQ(ierr); 14522e8d2280SStefano Zampini } 14532e8d2280SStefano Zampini } 14542e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14552e8d2280SStefano Zampini for (i=0;i<pcis->n;i++) { 14565b08dc53SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 14572e8d2280SStefano Zampini } 1458da1bb401SStefano 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 = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 14632e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem SHOULD be %lf\n",coarsesum);CHKERRQ(ierr); 14642e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14652e8d2280SStefano Zampini } 1466142dfd88SStefano Zampini ierr = PetscFree(auxlocal_primal);CHKERRQ(ierr); 14670bdf917eSStefano Zampini } 14680bdf917eSStefano Zampini 14692e8d2280SStefano Zampini if (dbg_flag) { 14707cf533a6SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem is %d\n",pcbddc->coarse_size);CHKERRQ(ierr); 14719d9e44b6SStefano Zampini if (dbg_flag > 1) { 1472674ae819SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 14732e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1474674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 1475674ae819SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 1476674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_primal_indices[%d]=%d \n",i,pcbddc->local_primal_indices[i]); 1477674ae819SStefano Zampini } 14782e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14792e8d2280SStefano Zampini } 14802e8d2280SStefano Zampini } 14812e8d2280SStefano Zampini 1482a929c220SStefano Zampini im_active = 0; 14832fa5cd67SKarl Rupp if (pcis->n) im_active = 1; 1484a929c220SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,prec_comm);CHKERRQ(ierr); 14850bdf917eSStefano Zampini 14860bdf917eSStefano Zampini /* adapt coarse problem type */ 14877cbb387bSStefano Zampini #if defined(PETSC_HAVE_METIS) 14884fad6a16SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 14894fad6a16SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 1490a929c220SStefano Zampini if ( (active_procs/pcbddc->coarsening_ratio) < 2 ) { 14910bdf917eSStefano Zampini if (dbg_flag) { 1492a929c220SStefano 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); 14930bdf917eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14940bdf917eSStefano Zampini } 14950bdf917eSStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 1496142dfd88SStefano Zampini } 14974fad6a16SStefano Zampini } else { 14984fad6a16SStefano Zampini if (dbg_flag) { 1499a929c220SStefano 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); 15004fad6a16SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 15014fad6a16SStefano Zampini } 15024fad6a16SStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 15034fad6a16SStefano Zampini } 15044fad6a16SStefano Zampini } 15057cbb387bSStefano Zampini #else 15067cbb387bSStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 15077cbb387bSStefano Zampini #endif 1508beed3852SStefano Zampini 15090c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 15100c7d97c5SJed Brown 1511da1bb401SStefano Zampini case(MULTILEVEL_BDDC): /* we define a coarse mesh where subdomains are elements */ 15120c7d97c5SJed Brown { 15137cbb387bSStefano Zampini #if defined(PETSC_HAVE_METIS) 15140c7d97c5SJed Brown /* we need additional variables */ 15150c7d97c5SJed Brown MetisInt n_subdomains,n_parts,objval,ncon,faces_nvtxs; 15160c7d97c5SJed Brown MetisInt *metis_coarse_subdivision; 15170c7d97c5SJed Brown MetisInt options[METIS_NOPTIONS]; 15180c7d97c5SJed Brown PetscMPIInt size_coarse_comm,rank_coarse_comm; 15190c7d97c5SJed Brown PetscMPIInt procs_jumps_coarse_comm; 15200c7d97c5SJed Brown PetscMPIInt *coarse_subdivision; 15210c7d97c5SJed Brown PetscMPIInt *total_count_recv; 15220c7d97c5SJed Brown PetscMPIInt *total_ranks_recv; 15230c7d97c5SJed Brown PetscMPIInt *displacements_recv; 15240c7d97c5SJed Brown PetscMPIInt *my_faces_connectivity; 15250c7d97c5SJed Brown PetscMPIInt *petsc_faces_adjncy; 15260c7d97c5SJed Brown MetisInt *faces_adjncy; 15270c7d97c5SJed Brown MetisInt *faces_xadj; 15280c7d97c5SJed Brown PetscMPIInt *number_of_faces; 15290c7d97c5SJed Brown PetscMPIInt *faces_displacements; 15300c7d97c5SJed Brown PetscInt *array_int; 15310c7d97c5SJed Brown PetscMPIInt my_faces=0; 15320c7d97c5SJed Brown PetscMPIInt total_faces=0; 15333828260eSStefano Zampini PetscInt ranks_stretching_ratio; 15340c7d97c5SJed Brown 15350c7d97c5SJed Brown /* define some quantities */ 15360c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 15370c7d97c5SJed Brown coarse_mat_type = MATIS; 15380c7d97c5SJed Brown coarse_pc_type = PCBDDC; 1539142dfd88SStefano Zampini coarse_ksp_type = KSPRICHARDSON; 15400c7d97c5SJed Brown 15410c7d97c5SJed Brown /* details of coarse decomposition */ 1542a929c220SStefano Zampini n_subdomains = active_procs; 15430c7d97c5SJed Brown n_parts = n_subdomains/pcbddc->coarsening_ratio; 1544a929c220SStefano Zampini ranks_stretching_ratio = size_prec_comm/active_procs; 15453828260eSStefano Zampini procs_jumps_coarse_comm = pcbddc->coarsening_ratio*ranks_stretching_ratio; 15463828260eSStefano Zampini 1547a929c220SStefano Zampini #if 0 1548a929c220SStefano Zampini PetscMPIInt *old_ranks; 1549a929c220SStefano Zampini PetscInt *new_ranks,*jj,*ii; 1550a929c220SStefano Zampini MatPartitioning mat_part; 1551a929c220SStefano Zampini IS coarse_new_decomposition,is_numbering; 1552a929c220SStefano Zampini PetscViewer viewer_test; 1553a929c220SStefano Zampini MPI_Comm test_coarse_comm; 1554a929c220SStefano Zampini PetscMPIInt test_coarse_color; 1555a929c220SStefano Zampini Mat mat_adj; 1556a929c220SStefano Zampini /* Create new communicator for coarse problem splitting the old one */ 1557a929c220SStefano Zampini /* procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 1558a929c220SStefano Zampini key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator */ 1559a929c220SStefano Zampini test_coarse_color = ( im_active ? 0 : MPI_UNDEFINED ); 1560a929c220SStefano Zampini test_coarse_comm = MPI_COMM_NULL; 1561a929c220SStefano Zampini ierr = MPI_Comm_split(prec_comm,test_coarse_color,rank_prec_comm,&test_coarse_comm);CHKERRQ(ierr); 1562a929c220SStefano Zampini if (im_active) { 1563a929c220SStefano Zampini ierr = PetscMalloc(n_subdomains*sizeof(PetscMPIInt),&old_ranks); 1564a929c220SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscInt),&new_ranks); 1565a929c220SStefano Zampini ierr = MPI_Comm_rank(test_coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 1566a929c220SStefano Zampini ierr = MPI_Comm_size(test_coarse_comm,&j);CHKERRQ(ierr); 1567a929c220SStefano Zampini ierr = MPI_Allgather(&rank_prec_comm,1,MPIU_INT,old_ranks,1,MPIU_INT,test_coarse_comm);CHKERRQ(ierr); 1568674ae819SStefano Zampini for (i=0; i<size_prec_comm; i++) new_ranks[i] = -1; 1569674ae819SStefano Zampini for (i=0; i<n_subdomains; i++) new_ranks[old_ranks[i]] = i; 1570a929c220SStefano Zampini ierr = PetscViewerASCIIOpen(test_coarse_comm,"test_mat_part.out",&viewer_test);CHKERRQ(ierr); 1571a929c220SStefano Zampini k = pcis->n_neigh-1; 1572a929c220SStefano Zampini ierr = PetscMalloc(2*sizeof(PetscInt),&ii); 1573a929c220SStefano Zampini ii[0]=0; 1574a929c220SStefano Zampini ii[1]=k; 1575a929c220SStefano Zampini ierr = PetscMalloc(k*sizeof(PetscInt),&jj); 1576674ae819SStefano Zampini for (i=0; i<k; i++) jj[i]=new_ranks[pcis->neigh[i+1]]; 1577a929c220SStefano Zampini ierr = PetscSortInt(k,jj);CHKERRQ(ierr); 15780298fd71SBarry Smith ierr = MatCreateMPIAdj(test_coarse_comm,1,n_subdomains,ii,jj,NULL,&mat_adj);CHKERRQ(ierr); 1579a929c220SStefano Zampini ierr = MatView(mat_adj,viewer_test);CHKERRQ(ierr); 1580a929c220SStefano Zampini ierr = MatPartitioningCreate(test_coarse_comm,&mat_part);CHKERRQ(ierr); 1581a929c220SStefano Zampini ierr = MatPartitioningSetAdjacency(mat_part,mat_adj);CHKERRQ(ierr); 1582a929c220SStefano Zampini ierr = MatPartitioningSetFromOptions(mat_part);CHKERRQ(ierr); 1583a929c220SStefano Zampini printf("Setting Nparts %d\n",n_parts); 1584a929c220SStefano Zampini ierr = MatPartitioningSetNParts(mat_part,n_parts);CHKERRQ(ierr); 1585a929c220SStefano Zampini ierr = MatPartitioningView(mat_part,viewer_test);CHKERRQ(ierr); 1586a929c220SStefano Zampini ierr = MatPartitioningApply(mat_part,&coarse_new_decomposition);CHKERRQ(ierr); 1587a929c220SStefano Zampini ierr = ISView(coarse_new_decomposition,viewer_test);CHKERRQ(ierr); 1588a929c220SStefano Zampini ierr = ISPartitioningToNumbering(coarse_new_decomposition,&is_numbering);CHKERRQ(ierr); 1589a929c220SStefano Zampini ierr = ISView(is_numbering,viewer_test);CHKERRQ(ierr); 1590a929c220SStefano Zampini ierr = PetscViewerDestroy(&viewer_test);CHKERRQ(ierr); 1591a929c220SStefano Zampini ierr = ISDestroy(&coarse_new_decomposition);CHKERRQ(ierr); 1592a929c220SStefano Zampini ierr = ISDestroy(&is_numbering);CHKERRQ(ierr); 1593a929c220SStefano Zampini ierr = MatPartitioningDestroy(&mat_part);CHKERRQ(ierr); 1594a929c220SStefano Zampini ierr = PetscFree(old_ranks);CHKERRQ(ierr); 1595a929c220SStefano Zampini ierr = PetscFree(new_ranks);CHKERRQ(ierr); 1596a929c220SStefano Zampini ierr = MPI_Comm_free(&test_coarse_comm);CHKERRQ(ierr); 1597a929c220SStefano Zampini } 1598a929c220SStefano Zampini #endif 1599a929c220SStefano Zampini 16004fad6a16SStefano Zampini /* build CSR graph of subdomains' connectivity */ 16010c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&array_int);CHKERRQ(ierr); 16023828260eSStefano Zampini ierr = PetscMemzero(array_int,pcis->n*sizeof(PetscInt));CHKERRQ(ierr); 16030c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++){/* i=1 so I don't count myself -> faces nodes counts to 1 */ 16040c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++){ 16050c7d97c5SJed Brown array_int[ pcis->shared[i][j] ]+=1; 16060c7d97c5SJed Brown } 16070c7d97c5SJed Brown } 16080c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++){ 16090c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++){ 16107cf533a6SStefano Zampini if (array_int[ pcis->shared[i][j] ] > 0 ){ 16110c7d97c5SJed Brown my_faces++; 16120c7d97c5SJed Brown break; 16130c7d97c5SJed Brown } 16140c7d97c5SJed Brown } 16150c7d97c5SJed Brown } 16160c7d97c5SJed Brown 161753cdbc3dSStefano Zampini ierr = MPI_Reduce(&my_faces,&total_faces,1,MPIU_INT,MPI_SUM,master_proc,prec_comm);CHKERRQ(ierr); 16180c7d97c5SJed Brown ierr = PetscMalloc (my_faces*sizeof(PetscInt),&my_faces_connectivity);CHKERRQ(ierr); 16190c7d97c5SJed Brown my_faces=0; 16200c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++){ 16210c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++){ 16227cf533a6SStefano Zampini if (array_int[ pcis->shared[i][j] ] > 0 ){ 16230c7d97c5SJed Brown my_faces_connectivity[my_faces]=pcis->neigh[i]; 16240c7d97c5SJed Brown my_faces++; 16250c7d97c5SJed Brown break; 16260c7d97c5SJed Brown } 16270c7d97c5SJed Brown } 16280c7d97c5SJed Brown } 16290c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 16300c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(PetscMPIInt),&petsc_faces_adjncy);CHKERRQ(ierr); 16310c7d97c5SJed Brown ierr = PetscMalloc (size_prec_comm*sizeof(PetscMPIInt),&number_of_faces);CHKERRQ(ierr); 16320c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(MetisInt),&faces_adjncy);CHKERRQ(ierr); 16330c7d97c5SJed Brown ierr = PetscMalloc ((n_subdomains+1)*sizeof(MetisInt),&faces_xadj);CHKERRQ(ierr); 16340c7d97c5SJed Brown ierr = PetscMalloc ((size_prec_comm+1)*sizeof(PetscMPIInt),&faces_displacements);CHKERRQ(ierr); 16350c7d97c5SJed Brown } 163653cdbc3dSStefano Zampini ierr = MPI_Gather(&my_faces,1,MPIU_INT,&number_of_faces[0],1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 16370c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 16380c7d97c5SJed Brown faces_xadj[0]=0; 16390c7d97c5SJed Brown faces_displacements[0]=0; 16400c7d97c5SJed Brown j=0; 16410c7d97c5SJed Brown for (i=1;i<size_prec_comm+1;i++) { 16420c7d97c5SJed Brown faces_displacements[i]=faces_displacements[i-1]+number_of_faces[i-1]; 16430c7d97c5SJed Brown if (number_of_faces[i-1]) { 16440c7d97c5SJed Brown j++; 16450c7d97c5SJed Brown faces_xadj[j]=faces_xadj[j-1]+number_of_faces[i-1]; 16460c7d97c5SJed Brown } 16470c7d97c5SJed Brown } 16480c7d97c5SJed Brown } 164953cdbc3dSStefano 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); 16500c7d97c5SJed Brown ierr = PetscFree(my_faces_connectivity);CHKERRQ(ierr); 16510c7d97c5SJed Brown ierr = PetscFree(array_int);CHKERRQ(ierr); 16520c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 16533828260eSStefano Zampini for (i=0;i<total_faces;i++) faces_adjncy[i]=(MetisInt)(petsc_faces_adjncy[i]/ranks_stretching_ratio); /* cast to MetisInt */ 16540c7d97c5SJed Brown ierr = PetscFree(faces_displacements);CHKERRQ(ierr); 16550c7d97c5SJed Brown ierr = PetscFree(number_of_faces);CHKERRQ(ierr); 16560c7d97c5SJed Brown ierr = PetscFree(petsc_faces_adjncy);CHKERRQ(ierr); 16570c7d97c5SJed Brown } 16580c7d97c5SJed Brown 16590c7d97c5SJed Brown if ( rank_prec_comm == master_proc ) { 1660674ae819SStefano Zampini 16613828260eSStefano Zampini PetscInt heuristic_for_metis=3; 1662674ae819SStefano Zampini 16630c7d97c5SJed Brown ncon=1; 16640c7d97c5SJed Brown faces_nvtxs=n_subdomains; 16650c7d97c5SJed Brown /* partition graoh induced by face connectivity */ 16660c7d97c5SJed Brown ierr = PetscMalloc (n_subdomains*sizeof(MetisInt),&metis_coarse_subdivision);CHKERRQ(ierr); 16670c7d97c5SJed Brown ierr = METIS_SetDefaultOptions(options); 16680c7d97c5SJed Brown /* we need a contiguous partition of the coarse mesh */ 16690c7d97c5SJed Brown options[METIS_OPTION_CONTIG]=1; 16700c7d97c5SJed Brown options[METIS_OPTION_NITER]=30; 16714fad6a16SStefano Zampini if (pcbddc->coarsening_ratio > 1) { 16723828260eSStefano Zampini if (n_subdomains>n_parts*heuristic_for_metis) { 16733828260eSStefano Zampini options[METIS_OPTION_IPTYPE]=METIS_IPTYPE_EDGE; 16743828260eSStefano Zampini options[METIS_OPTION_OBJTYPE]=METIS_OBJTYPE_CUT; 16750c7d97c5SJed Brown ierr = METIS_PartGraphKway(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 1676674ae819SStefano 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); 16773828260eSStefano Zampini } else { 16783828260eSStefano Zampini ierr = METIS_PartGraphRecursive(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 1679674ae819SStefano 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); 16803828260eSStefano Zampini } 16814fad6a16SStefano Zampini } else { 16822fa5cd67SKarl Rupp for (i=0;i<n_subdomains;i++) metis_coarse_subdivision[i]=i; 16834fad6a16SStefano Zampini } 16840c7d97c5SJed Brown ierr = PetscFree(faces_xadj);CHKERRQ(ierr); 16850c7d97c5SJed Brown ierr = PetscFree(faces_adjncy);CHKERRQ(ierr); 16860bdf917eSStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&coarse_subdivision);CHKERRQ(ierr); 16872fa5cd67SKarl Rupp 16880c7d97c5SJed Brown /* copy/cast values avoiding possible type conflicts between PETSc, MPI and METIS */ 16892fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) coarse_subdivision[i]=MPI_PROC_NULL; 16902fa5cd67SKarl Rupp for (i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=(PetscInt)(metis_coarse_subdivision[i]); 16910c7d97c5SJed Brown ierr = PetscFree(metis_coarse_subdivision);CHKERRQ(ierr); 16920c7d97c5SJed Brown } 16930c7d97c5SJed Brown 16940c7d97c5SJed Brown /* Create new communicator for coarse problem splitting the old one */ 16950c7d97c5SJed Brown if ( !(rank_prec_comm%procs_jumps_coarse_comm) && rank_prec_comm < procs_jumps_coarse_comm*n_parts ){ 1696da1bb401SStefano Zampini coarse_color=0; /* for communicator splitting */ 1697da1bb401SStefano Zampini active_rank=rank_prec_comm; /* for insertion of matrix values */ 16980c7d97c5SJed Brown } 1699da1bb401SStefano Zampini /* procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 1700da1bb401SStefano Zampini key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator */ 170153cdbc3dSStefano Zampini ierr = MPI_Comm_split(prec_comm,coarse_color,rank_prec_comm,&coarse_comm);CHKERRQ(ierr); 17020c7d97c5SJed Brown 17030c7d97c5SJed Brown if ( coarse_color == 0 ) { 170453cdbc3dSStefano Zampini ierr = MPI_Comm_size(coarse_comm,&size_coarse_comm);CHKERRQ(ierr); 170553cdbc3dSStefano Zampini ierr = MPI_Comm_rank(coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 17060c7d97c5SJed Brown } else { 17070c7d97c5SJed Brown rank_coarse_comm = MPI_PROC_NULL; 17080c7d97c5SJed Brown } 17090c7d97c5SJed Brown 17107cf533a6SStefano Zampini /* master proc take care of arranging and distributing coarse information */ 17110c7d97c5SJed Brown if (rank_coarse_comm == master_proc) { 17120c7d97c5SJed Brown ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&displacements_recv);CHKERRQ(ierr); 17130bdf917eSStefano Zampini ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&total_count_recv);CHKERRQ(ierr); 17140bdf917eSStefano Zampini ierr = PetscMalloc (n_subdomains*sizeof(PetscMPIInt),&total_ranks_recv);CHKERRQ(ierr); 17150c7d97c5SJed Brown /* some initializations */ 17160c7d97c5SJed Brown displacements_recv[0]=0; 17170bdf917eSStefano Zampini ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 17180c7d97c5SJed Brown /* count from how many processes the j-th process of the coarse decomposition will receive data */ 17190bdf917eSStefano Zampini for (j=0;j<size_coarse_comm;j++) { 17200bdf917eSStefano Zampini for (i=0;i<size_prec_comm;i++) { 17212fa5cd67SKarl Rupp if (coarse_subdivision[i]==j) total_count_recv[j]++; 17220bdf917eSStefano Zampini } 17230bdf917eSStefano Zampini } 17240c7d97c5SJed Brown /* displacements needed for scatterv of total_ranks_recv */ 17252fa5cd67SKarl Rupp for (i=1; i<size_coarse_comm; i++) displacements_recv[i]=displacements_recv[i-1]+total_count_recv[i-1]; 17262fa5cd67SKarl Rupp 17270c7d97c5SJed Brown /* Now fill properly total_ranks_recv -> each coarse process will receive the ranks (in prec_comm communicator) of its friend (sending) processes */ 17280c7d97c5SJed Brown ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 17290c7d97c5SJed Brown for (j=0;j<size_coarse_comm;j++) { 17303828260eSStefano Zampini for (i=0;i<size_prec_comm;i++) { 17310c7d97c5SJed Brown if (coarse_subdivision[i]==j) { 17320c7d97c5SJed Brown total_ranks_recv[displacements_recv[j]+total_count_recv[j]]=i; 17333828260eSStefano Zampini total_count_recv[j]+=1; 17340c7d97c5SJed Brown } 17350c7d97c5SJed Brown } 17360c7d97c5SJed Brown } 1737da1bb401SStefano Zampini /*for (j=0;j<size_coarse_comm;j++) { 17383828260eSStefano Zampini printf("process %d in new rank will receive from %d processes (original ranks follows)\n",j,total_count_recv[j]); 17393828260eSStefano Zampini for (i=0;i<total_count_recv[j];i++) { 17403828260eSStefano Zampini printf("%d ",total_ranks_recv[displacements_recv[j]+i]); 17413828260eSStefano Zampini } 17423828260eSStefano Zampini printf("\n"); 1743da1bb401SStefano Zampini }*/ 17440c7d97c5SJed Brown 17450c7d97c5SJed Brown /* identify new decomposition in terms of ranks in the old communicator */ 17460bdf917eSStefano Zampini for (i=0;i<n_subdomains;i++) { 17470bdf917eSStefano Zampini coarse_subdivision[ranks_stretching_ratio*i]=coarse_subdivision[ranks_stretching_ratio*i]*procs_jumps_coarse_comm; 17480bdf917eSStefano Zampini } 1749da1bb401SStefano Zampini /*printf("coarse_subdivision in old end new ranks\n"); 1750674ae819SStefano Zampini for (i=0;i<size_prec_comm;i++) 17513828260eSStefano Zampini if (coarse_subdivision[i]!=MPI_PROC_NULL) { 17523828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]/procs_jumps_coarse_comm); 17533828260eSStefano Zampini } else { 17543828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]); 17553828260eSStefano Zampini } 1756da1bb401SStefano Zampini printf("\n");*/ 17570c7d97c5SJed Brown } 17580c7d97c5SJed Brown 17590c7d97c5SJed Brown /* Scatter new decomposition for send details */ 176053cdbc3dSStefano Zampini ierr = MPI_Scatter(&coarse_subdivision[0],1,MPIU_INT,&rank_coarse_proc_send_to,1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 17610c7d97c5SJed Brown /* Scatter receiving details to members of coarse decomposition */ 17620c7d97c5SJed Brown if ( coarse_color == 0) { 176353cdbc3dSStefano Zampini ierr = MPI_Scatter(&total_count_recv[0],1,MPIU_INT,&count_recv,1,MPIU_INT,master_proc,coarse_comm);CHKERRQ(ierr); 17640c7d97c5SJed Brown ierr = PetscMalloc (count_recv*sizeof(PetscMPIInt),&ranks_recv);CHKERRQ(ierr); 176553cdbc3dSStefano 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); 17660c7d97c5SJed Brown } 17670c7d97c5SJed Brown 1768da1bb401SStefano Zampini /*printf("I will send my matrix data to proc %d\n",rank_coarse_proc_send_to); 1769da1bb401SStefano Zampini if (coarse_color == 0) { 1770da1bb401SStefano Zampini printf("I will receive some matrix data from %d processes (ranks follows)\n",count_recv); 1771da1bb401SStefano Zampini for (i=0;i<count_recv;i++) 1772da1bb401SStefano Zampini printf("%d ",ranks_recv[i]); 1773da1bb401SStefano Zampini printf("\n"); 1774da1bb401SStefano Zampini }*/ 17750c7d97c5SJed Brown 17760c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 17770bdf917eSStefano Zampini ierr = PetscFree(coarse_subdivision);CHKERRQ(ierr); 1778da1bb401SStefano Zampini ierr = PetscFree(total_count_recv);CHKERRQ(ierr); 17790bdf917eSStefano Zampini ierr = PetscFree(total_ranks_recv);CHKERRQ(ierr); 17800c7d97c5SJed Brown ierr = PetscFree(displacements_recv);CHKERRQ(ierr); 17810c7d97c5SJed Brown } 17827cbb387bSStefano Zampini #endif 17830c7d97c5SJed Brown break; 17840c7d97c5SJed Brown } 17850c7d97c5SJed Brown 17860c7d97c5SJed Brown case(REPLICATED_BDDC): 17870c7d97c5SJed Brown 17880c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 17890c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 17900c7d97c5SJed Brown coarse_pc_type = PCLU; 179153cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 17920c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 17930c7d97c5SJed Brown active_rank = rank_prec_comm; 17940c7d97c5SJed Brown break; 17950c7d97c5SJed Brown 17960c7d97c5SJed Brown case(PARALLEL_BDDC): 17970c7d97c5SJed Brown 17980c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 1799674ae819SStefano Zampini coarse_mat_type = MATAIJ; 18000c7d97c5SJed Brown coarse_pc_type = PCREDUNDANT; 180153cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 18020c7d97c5SJed Brown coarse_comm = prec_comm; 18030c7d97c5SJed Brown active_rank = rank_prec_comm; 18040c7d97c5SJed Brown break; 18050c7d97c5SJed Brown 18060c7d97c5SJed Brown case(SEQUENTIAL_BDDC): 18070c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 1808674ae819SStefano Zampini coarse_mat_type = MATAIJ; 18090c7d97c5SJed Brown coarse_pc_type = PCLU; 181053cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 18110c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 18120c7d97c5SJed Brown active_rank = master_proc; 18130c7d97c5SJed Brown break; 18140c7d97c5SJed Brown } 18150c7d97c5SJed Brown 18160c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 18170c7d97c5SJed Brown 18180c7d97c5SJed Brown case(SCATTERS_BDDC): 18190c7d97c5SJed Brown { 18200c7d97c5SJed Brown if (pcbddc->coarse_problem_type==MULTILEVEL_BDDC) { 18210c7d97c5SJed Brown 18222e8d2280SStefano Zampini IS coarse_IS; 18232e8d2280SStefano Zampini 1824523858cfSStefano Zampini if(pcbddc->coarsening_ratio == 1) { 1825523858cfSStefano Zampini ins_local_primal_size = pcbddc->local_primal_size; 1826523858cfSStefano Zampini ins_local_primal_indices = pcbddc->local_primal_indices; 1827523858cfSStefano Zampini if (coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 1828523858cfSStefano Zampini /* nonzeros */ 1829523858cfSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&dnz);CHKERRQ(ierr); 1830523858cfSStefano Zampini ierr = PetscMemzero(dnz,ins_local_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 1831523858cfSStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 1832523858cfSStefano Zampini dnz[i] = ins_local_primal_size; 1833523858cfSStefano Zampini } 1834523858cfSStefano Zampini } else { 18350c7d97c5SJed Brown PetscMPIInt send_size; 1836ef028eecSStefano Zampini PetscMPIInt *send_buffer; 18370c7d97c5SJed Brown PetscInt *aux_ins_indices; 18380c7d97c5SJed Brown PetscInt ii,jj; 18390c7d97c5SJed Brown MPI_Request *requests; 1840ef028eecSStefano Zampini 1841523858cfSStefano Zampini ierr = PetscMalloc(count_recv*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 1842523858cfSStefano Zampini /* reusing pcbddc->local_primal_displacements and pcbddc->replicated_primal_size */ 1843523858cfSStefano Zampini ierr = PetscFree(pcbddc->local_primal_displacements);CHKERRQ(ierr); 1844523858cfSStefano Zampini ierr = PetscMalloc((count_recv+1)*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 1845523858cfSStefano Zampini pcbddc->replicated_primal_size = count_recv; 1846523858cfSStefano Zampini j = 0; 1847523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 1848523858cfSStefano Zampini pcbddc->local_primal_displacements[i] = j; 1849523858cfSStefano Zampini j += pcbddc->local_primal_sizes[ranks_recv[i]]; 1850523858cfSStefano Zampini } 1851523858cfSStefano Zampini pcbddc->local_primal_displacements[count_recv] = j; 1852523858cfSStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 18530c7d97c5SJed Brown /* allocate auxiliary space */ 1854523858cfSStefano Zampini ierr = PetscMalloc(count_recv*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 18550c7d97c5SJed Brown ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscInt),&aux_ins_indices);CHKERRQ(ierr); 18560c7d97c5SJed Brown ierr = PetscMemzero(aux_ins_indices,pcbddc->coarse_size*sizeof(PetscInt));CHKERRQ(ierr); 18570c7d97c5SJed Brown /* allocate stuffs for message massing */ 18580c7d97c5SJed Brown ierr = PetscMalloc((count_recv+1)*sizeof(MPI_Request),&requests);CHKERRQ(ierr); 1859523858cfSStefano Zampini for (i=0;i<count_recv+1;i++) { requests[i]=MPI_REQUEST_NULL; } 1860523858cfSStefano Zampini /* send indices to be inserted */ 1861523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 1862523858cfSStefano Zampini send_size = pcbddc->local_primal_sizes[ranks_recv[i]]; 1863523858cfSStefano 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); 1864523858cfSStefano Zampini } 1865523858cfSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 1866523858cfSStefano Zampini send_size = pcbddc->local_primal_size; 1867ef028eecSStefano Zampini ierr = PetscMalloc(send_size*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 1868ef028eecSStefano Zampini for (i=0;i<send_size;i++) { 1869ef028eecSStefano Zampini send_buffer[i]=(PetscMPIInt)pcbddc->local_primal_indices[i]; 1870ef028eecSStefano Zampini } 1871ef028eecSStefano Zampini ierr = MPI_Isend(send_buffer,send_size,MPIU_INT,rank_coarse_proc_send_to,999,prec_comm,&requests[count_recv]);CHKERRQ(ierr); 1872523858cfSStefano Zampini } 1873523858cfSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 1874ef028eecSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 1875ef028eecSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 1876ef028eecSStefano Zampini } 18770c7d97c5SJed Brown j = 0; 18780c7d97c5SJed Brown for (i=0;i<count_recv;i++) { 18792e8d2280SStefano Zampini ii = pcbddc->local_primal_displacements[i+1]-pcbddc->local_primal_displacements[i]; 18802e8d2280SStefano Zampini localsizes2[i] = ii*ii; 18810c7d97c5SJed Brown localdispl2[i] = j; 18820c7d97c5SJed Brown j += localsizes2[i]; 1883523858cfSStefano Zampini jj = pcbddc->local_primal_displacements[i]; 18844fad6a16SStefano Zampini /* it counts the coarse subdomains sharing the coarse node */ 18852e8d2280SStefano Zampini for (k=0;k<ii;k++) { 18864fad6a16SStefano Zampini aux_ins_indices[pcbddc->replicated_local_primal_indices[jj+k]] += 1; 18870c7d97c5SJed Brown } 18884fad6a16SStefano Zampini } 1889523858cfSStefano Zampini /* temp_coarse_mat_vals used to store matrix values to be received */ 18900c7d97c5SJed Brown ierr = PetscMalloc(j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 18910c7d97c5SJed Brown /* evaluate how many values I will insert in coarse mat */ 18920c7d97c5SJed Brown ins_local_primal_size = 0; 1893ea7e1babSStefano Zampini for (i=0;i<pcbddc->coarse_size;i++) { 1894ea7e1babSStefano Zampini if (aux_ins_indices[i]) { 18950c7d97c5SJed Brown ins_local_primal_size++; 1896ea7e1babSStefano Zampini } 1897ea7e1babSStefano Zampini } 18980c7d97c5SJed Brown /* evaluate indices I will insert in coarse mat */ 18990c7d97c5SJed Brown ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 19000c7d97c5SJed Brown j = 0; 1901ea7e1babSStefano Zampini for(i=0;i<pcbddc->coarse_size;i++) { 1902ea7e1babSStefano Zampini if(aux_ins_indices[i]) { 19032e8d2280SStefano Zampini ins_local_primal_indices[j] = i; 19042e8d2280SStefano Zampini j++; 1905ea7e1babSStefano Zampini } 1906ea7e1babSStefano Zampini } 1907523858cfSStefano Zampini /* processes partecipating in coarse problem receive matrix data from their friends */ 1908523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 1909523858cfSStefano Zampini ierr = MPI_Irecv(&temp_coarse_mat_vals[localdispl2[i]],localsizes2[i],MPIU_SCALAR,ranks_recv[i],666,prec_comm,&requests[i]);CHKERRQ(ierr); 1910523858cfSStefano Zampini } 1911523858cfSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 1912523858cfSStefano Zampini send_size = pcbddc->local_primal_size*pcbddc->local_primal_size; 1913523858cfSStefano 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); 1914523858cfSStefano Zampini } 1915523858cfSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 1916523858cfSStefano Zampini /* nonzeros */ 1917523858cfSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&dnz);CHKERRQ(ierr); 1918523858cfSStefano Zampini ierr = PetscMemzero(dnz,ins_local_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 19190c7d97c5SJed Brown /* use aux_ins_indices to realize a global to local mapping */ 19200c7d97c5SJed Brown j=0; 19210c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++){ 19220c7d97c5SJed Brown if(aux_ins_indices[i]==0){ 19230c7d97c5SJed Brown aux_ins_indices[i]=-1; 19240c7d97c5SJed Brown } else { 19250c7d97c5SJed Brown aux_ins_indices[i]=j; 19260c7d97c5SJed Brown j++; 19270c7d97c5SJed Brown } 19280c7d97c5SJed Brown } 19294fad6a16SStefano Zampini for (i=0;i<count_recv;i++) { 1930523858cfSStefano Zampini j = pcbddc->local_primal_sizes[ranks_recv[i]]; 1931523858cfSStefano Zampini for (k=0;k<j;k++) { 1932523858cfSStefano Zampini dnz[aux_ins_indices[pcbddc->replicated_local_primal_indices[pcbddc->local_primal_displacements[i]+k]]] += j; 19330c7d97c5SJed Brown } 19340c7d97c5SJed Brown } 1935523858cfSStefano Zampini /* check */ 1936523858cfSStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 1937523858cfSStefano Zampini if (dnz[i] > ins_local_primal_size) { 1938523858cfSStefano Zampini dnz[i] = ins_local_primal_size; 19390c7d97c5SJed Brown } 19400c7d97c5SJed Brown } 19410c7d97c5SJed Brown ierr = PetscFree(requests);CHKERRQ(ierr); 19420c7d97c5SJed Brown ierr = PetscFree(aux_ins_indices);CHKERRQ(ierr); 19430c7d97c5SJed Brown if (coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 19444fad6a16SStefano Zampini } 19450c7d97c5SJed Brown /* create local to global mapping needed by coarse MATIS */ 1946142dfd88SStefano Zampini if (coarse_comm != MPI_COMM_NULL ) {ierr = MPI_Comm_free(&coarse_comm);CHKERRQ(ierr);} 19470c7d97c5SJed Brown coarse_comm = prec_comm; 19480c7d97c5SJed Brown active_rank = rank_prec_comm; 19490c7d97c5SJed Brown ierr = ISCreateGeneral(coarse_comm,ins_local_primal_size,ins_local_primal_indices,PETSC_COPY_VALUES,&coarse_IS);CHKERRQ(ierr); 19500c7d97c5SJed Brown ierr = ISLocalToGlobalMappingCreateIS(coarse_IS,&coarse_ISLG);CHKERRQ(ierr); 19510c7d97c5SJed Brown ierr = ISDestroy(&coarse_IS);CHKERRQ(ierr); 19522e8d2280SStefano Zampini } else if (pcbddc->coarse_problem_type==PARALLEL_BDDC) { 19530c7d97c5SJed Brown /* arrays for values insertion */ 19540c7d97c5SJed Brown ins_local_primal_size = pcbddc->local_primal_size; 19552e8d2280SStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 19560c7d97c5SJed Brown ierr = PetscMalloc(ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 19570c7d97c5SJed Brown for (j=0;j<ins_local_primal_size;j++){ 19580c7d97c5SJed Brown ins_local_primal_indices[j]=pcbddc->local_primal_indices[j]; 19594fad6a16SStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 19604fad6a16SStefano Zampini ins_coarse_mat_vals[j*ins_local_primal_size+i]=coarse_submat_vals[j*ins_local_primal_size+i]; 19614fad6a16SStefano Zampini } 19620c7d97c5SJed Brown } 19630c7d97c5SJed Brown } 19640c7d97c5SJed Brown break; 1965674ae819SStefano Zampini 19660c7d97c5SJed Brown } 19670c7d97c5SJed Brown 19680c7d97c5SJed Brown case(GATHERS_BDDC): 19690c7d97c5SJed Brown { 1970674ae819SStefano Zampini 19710c7d97c5SJed Brown PetscMPIInt mysize,mysize2; 1972ef028eecSStefano Zampini PetscMPIInt *send_buffer; 19730c7d97c5SJed Brown 19740c7d97c5SJed Brown if (rank_prec_comm==active_rank) { 19750c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 19760bdf917eSStefano Zampini ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscScalar),&pcbddc->replicated_local_primal_values);CHKERRQ(ierr); 19770c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 19780c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 19790c7d97c5SJed Brown /* arrays for values insertion */ 19802fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) localsizes2[i]=pcbddc->local_primal_sizes[i]*pcbddc->local_primal_sizes[i]; 19810c7d97c5SJed Brown localdispl2[0]=0; 19822fa5cd67SKarl Rupp for (i=1;i<size_prec_comm;i++) localdispl2[i]=localsizes2[i-1]+localdispl2[i-1]; 19830c7d97c5SJed Brown j=0; 19842fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) j+=localsizes2[i]; 19850c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 19860c7d97c5SJed Brown } 19870c7d97c5SJed Brown 19880c7d97c5SJed Brown mysize=pcbddc->local_primal_size; 19890c7d97c5SJed Brown mysize2=pcbddc->local_primal_size*pcbddc->local_primal_size; 1990ef028eecSStefano Zampini ierr = PetscMalloc(mysize*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 19912fa5cd67SKarl Rupp for (i=0; i<mysize; i++) send_buffer[i]=(PetscMPIInt)pcbddc->local_primal_indices[i]; 19922fa5cd67SKarl Rupp 19930c7d97c5SJed Brown if (pcbddc->coarse_problem_type == SEQUENTIAL_BDDC){ 1994ef028eecSStefano 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); 199553cdbc3dSStefano 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); 19960c7d97c5SJed Brown } else { 1997ef028eecSStefano 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); 199853cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,prec_comm);CHKERRQ(ierr); 19990c7d97c5SJed Brown } 2000ef028eecSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 20010c7d97c5SJed Brown break; 2002da1bb401SStefano Zampini }/* switch on coarse problem and communications associated with finished */ 20030c7d97c5SJed Brown } 20040c7d97c5SJed Brown 20050c7d97c5SJed Brown /* Now create and fill up coarse matrix */ 20060c7d97c5SJed Brown if ( rank_prec_comm == active_rank ) { 2007142dfd88SStefano Zampini 2008142dfd88SStefano Zampini Mat matis_coarse_local_mat; 2009142dfd88SStefano Zampini 20100c7d97c5SJed Brown if (pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 20110c7d97c5SJed Brown ierr = MatCreate(coarse_comm,&pcbddc->coarse_mat);CHKERRQ(ierr); 20120c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_mat,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size);CHKERRQ(ierr); 20130c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_mat,coarse_mat_type);CHKERRQ(ierr); 2014674ae819SStefano Zampini ierr = MatSetOptionsPrefix(pcbddc->coarse_mat,"coarse_");CHKERRQ(ierr); 2015674ae819SStefano Zampini ierr = MatSetFromOptions(pcbddc->coarse_mat);CHKERRQ(ierr); 20163b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 2017da1bb401SStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 20183b03a366Sstefano_zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 20190c7d97c5SJed Brown } else { 20204fad6a16SStefano Zampini ierr = MatCreateIS(coarse_comm,1,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_ISLG,&pcbddc->coarse_mat);CHKERRQ(ierr); 20213b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 20220c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 2023674ae819SStefano Zampini ierr = MatSetOptionsPrefix(pcbddc->coarse_mat,"coarse_");CHKERRQ(ierr); 2024674ae819SStefano Zampini ierr = MatSetFromOptions(pcbddc->coarse_mat);CHKERRQ(ierr); 20253b03a366Sstefano_zampini ierr = MatSetUp(matis_coarse_local_mat);CHKERRQ(ierr); 2026da1bb401SStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 2027a0ba757dSStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 20280c7d97c5SJed Brown } 2029142dfd88SStefano Zampini /* preallocation */ 2030142dfd88SStefano Zampini if (pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 2031ef028eecSStefano Zampini 2032674ae819SStefano Zampini PetscInt lrows,lcols,bs; 2033ef028eecSStefano Zampini 2034142dfd88SStefano Zampini ierr = MatGetLocalSize(pcbddc->coarse_mat,&lrows,&lcols);CHKERRQ(ierr); 2035142dfd88SStefano Zampini ierr = MatPreallocateInitialize(coarse_comm,lrows,lcols,dnz,onz);CHKERRQ(ierr); 2036674ae819SStefano Zampini ierr = MatGetBlockSize(pcbddc->coarse_mat,&bs);CHKERRQ(ierr); 2037ef028eecSStefano Zampini 2038142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == PARALLEL_BDDC) { 2039ef028eecSStefano Zampini 2040ef028eecSStefano Zampini Vec vec_dnz,vec_onz; 2041ef028eecSStefano Zampini PetscScalar *my_dnz,*my_onz,*array; 2042ef028eecSStefano Zampini PetscInt *mat_ranges,*row_ownership; 2043ef028eecSStefano Zampini PetscInt coarse_index_row,coarse_index_col,owner; 2044ef028eecSStefano Zampini 2045ef028eecSStefano Zampini ierr = VecCreate(prec_comm,&vec_dnz);CHKERRQ(ierr); 2046674ae819SStefano Zampini ierr = VecSetBlockSize(vec_dnz,bs);CHKERRQ(ierr); 2047ef028eecSStefano Zampini ierr = VecSetSizes(vec_dnz,PETSC_DECIDE,pcbddc->coarse_size);CHKERRQ(ierr); 2048ef028eecSStefano Zampini ierr = VecSetType(vec_dnz,VECMPI);CHKERRQ(ierr); 2049ef028eecSStefano Zampini ierr = VecDuplicate(vec_dnz,&vec_onz);CHKERRQ(ierr); 2050ef028eecSStefano Zampini 2051ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscScalar),&my_dnz);CHKERRQ(ierr); 2052ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscScalar),&my_onz);CHKERRQ(ierr); 2053ef028eecSStefano Zampini ierr = PetscMemzero(my_dnz,pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 2054ef028eecSStefano Zampini ierr = PetscMemzero(my_onz,pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 2055ef028eecSStefano Zampini 2056ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscInt),&row_ownership);CHKERRQ(ierr); 2057ef028eecSStefano Zampini ierr = MatGetOwnershipRanges(pcbddc->coarse_mat,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 2058142dfd88SStefano Zampini for (i=0;i<size_prec_comm;i++) { 2059ef028eecSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 2060ef028eecSStefano Zampini row_ownership[j]=i; 2061142dfd88SStefano Zampini } 2062142dfd88SStefano Zampini } 2063ef028eecSStefano Zampini 2064ef028eecSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 2065ef028eecSStefano Zampini coarse_index_row = pcbddc->local_primal_indices[i]; 2066ef028eecSStefano Zampini owner = row_ownership[coarse_index_row]; 2067ef028eecSStefano Zampini for (j=i;j<pcbddc->local_primal_size;j++) { 2068ef028eecSStefano Zampini owner = row_ownership[coarse_index_row]; 2069ef028eecSStefano Zampini coarse_index_col = pcbddc->local_primal_indices[j]; 2070ef028eecSStefano Zampini if (coarse_index_col > mat_ranges[owner]-1 && coarse_index_col < mat_ranges[owner+1] ) { 2071ef028eecSStefano Zampini my_dnz[i] += 1.0; 2072142dfd88SStefano Zampini } else { 2073ef028eecSStefano Zampini my_onz[i] += 1.0; 2074142dfd88SStefano Zampini } 2075ef028eecSStefano Zampini if (i != j) { 2076ef028eecSStefano Zampini owner = row_ownership[coarse_index_col]; 2077ef028eecSStefano Zampini if (coarse_index_row > mat_ranges[owner]-1 && coarse_index_row < mat_ranges[owner+1] ) { 2078ef028eecSStefano Zampini my_dnz[j] += 1.0; 2079142dfd88SStefano Zampini } else { 2080ef028eecSStefano Zampini my_onz[j] += 1.0; 2081142dfd88SStefano Zampini } 2082142dfd88SStefano Zampini } 2083142dfd88SStefano Zampini } 2084142dfd88SStefano Zampini } 2085ef028eecSStefano Zampini ierr = VecSet(vec_dnz,0.0);CHKERRQ(ierr); 2086ef028eecSStefano Zampini ierr = VecSet(vec_onz,0.0);CHKERRQ(ierr); 2087a929c220SStefano Zampini if (pcbddc->local_primal_size) { 2088ef028eecSStefano Zampini ierr = VecSetValues(vec_dnz,pcbddc->local_primal_size,pcbddc->local_primal_indices,my_dnz,ADD_VALUES);CHKERRQ(ierr); 2089ef028eecSStefano Zampini ierr = VecSetValues(vec_onz,pcbddc->local_primal_size,pcbddc->local_primal_indices,my_onz,ADD_VALUES);CHKERRQ(ierr); 2090a929c220SStefano Zampini } 2091ef028eecSStefano Zampini ierr = VecAssemblyBegin(vec_dnz);CHKERRQ(ierr); 2092ef028eecSStefano Zampini ierr = VecAssemblyBegin(vec_onz);CHKERRQ(ierr); 2093ef028eecSStefano Zampini ierr = VecAssemblyEnd(vec_dnz);CHKERRQ(ierr); 2094ef028eecSStefano Zampini ierr = VecAssemblyEnd(vec_onz);CHKERRQ(ierr); 2095ef028eecSStefano Zampini j = mat_ranges[rank_prec_comm+1]-mat_ranges[rank_prec_comm]; 2096ef028eecSStefano Zampini ierr = VecGetArray(vec_dnz,&array);CHKERRQ(ierr); 20975b08dc53SStefano Zampini for (i=0; i<j; i++) dnz[i] = (PetscInt)PetscRealPart(array[i]); 20982fa5cd67SKarl Rupp 2099ef028eecSStefano Zampini ierr = VecRestoreArray(vec_dnz,&array);CHKERRQ(ierr); 2100ef028eecSStefano Zampini ierr = VecGetArray(vec_onz,&array);CHKERRQ(ierr); 21015b08dc53SStefano Zampini for (i=0;i<j;i++) onz[i] = (PetscInt)PetscRealPart(array[i]); 21022fa5cd67SKarl Rupp 2103ef028eecSStefano Zampini ierr = VecRestoreArray(vec_onz,&array);CHKERRQ(ierr); 2104ef028eecSStefano Zampini ierr = PetscFree(my_dnz);CHKERRQ(ierr); 2105ef028eecSStefano Zampini ierr = PetscFree(my_onz);CHKERRQ(ierr); 2106ef028eecSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 2107ef028eecSStefano Zampini ierr = VecDestroy(&vec_dnz);CHKERRQ(ierr); 2108ef028eecSStefano Zampini ierr = VecDestroy(&vec_onz);CHKERRQ(ierr); 2109142dfd88SStefano Zampini } else { 2110142dfd88SStefano Zampini for (k=0;k<size_prec_comm;k++){ 2111142dfd88SStefano Zampini offset=pcbddc->local_primal_displacements[k]; 2112142dfd88SStefano Zampini offset2=localdispl2[k]; 2113142dfd88SStefano Zampini ins_local_primal_size = pcbddc->local_primal_sizes[k]; 2114ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2115ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2116ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2117ef028eecSStefano Zampini } 2118142dfd88SStefano Zampini for (j=0;j<ins_local_primal_size;j++) { 2119142dfd88SStefano Zampini ierr = MatPreallocateSet(ins_local_primal_indices[j],ins_local_primal_size,ins_local_primal_indices,dnz,onz);CHKERRQ(ierr); 2120142dfd88SStefano Zampini } 2121ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2122142dfd88SStefano Zampini } 2123142dfd88SStefano Zampini } 21242fa5cd67SKarl Rupp 2125142dfd88SStefano Zampini /* check */ 2126142dfd88SStefano Zampini for (i=0;i<lrows;i++) { 21272fa5cd67SKarl Rupp if (dnz[i]>lcols) dnz[i]=lcols; 21282fa5cd67SKarl Rupp if (onz[i]>pcbddc->coarse_size-lcols) onz[i]=pcbddc->coarse_size-lcols; 2129142dfd88SStefano Zampini } 2130d9a4edebSJed Brown ierr = MatSeqAIJSetPreallocation(pcbddc->coarse_mat,0,dnz);CHKERRQ(ierr); 2131d9a4edebSJed Brown ierr = MatMPIAIJSetPreallocation(pcbddc->coarse_mat,0,dnz,0,onz);CHKERRQ(ierr); 2132142dfd88SStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 2133142dfd88SStefano Zampini } else { 2134523858cfSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis_coarse_local_mat,0,dnz);CHKERRQ(ierr); 2135523858cfSStefano Zampini ierr = PetscFree(dnz);CHKERRQ(ierr); 2136142dfd88SStefano Zampini } 2137142dfd88SStefano Zampini /* insert values */ 2138523858cfSStefano Zampini if (pcbddc->coarse_problem_type == PARALLEL_BDDC) { 21390c7d97c5SJed 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); 2140523858cfSStefano Zampini } else if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2141523858cfSStefano Zampini if (pcbddc->coarsening_ratio == 1) { 2142523858cfSStefano Zampini ins_coarse_mat_vals = coarse_submat_vals; 2143523858cfSStefano 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); 2144523858cfSStefano Zampini } else { 2145523858cfSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2146523858cfSStefano Zampini for (k=0;k<pcbddc->replicated_primal_size;k++) { 2147523858cfSStefano Zampini offset = pcbddc->local_primal_displacements[k]; 2148523858cfSStefano Zampini offset2 = localdispl2[k]; 2149523858cfSStefano Zampini ins_local_primal_size = pcbddc->local_primal_displacements[k+1]-pcbddc->local_primal_displacements[k]; 2150ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2151ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2152ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2153ef028eecSStefano Zampini } 2154523858cfSStefano Zampini ins_coarse_mat_vals = &temp_coarse_mat_vals[offset2]; 2155523858cfSStefano 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); 2156ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2157523858cfSStefano Zampini } 2158523858cfSStefano Zampini } 2159523858cfSStefano Zampini ins_local_primal_indices = 0; 2160523858cfSStefano Zampini ins_coarse_mat_vals = 0; 2161ea7e1babSStefano Zampini } else { 2162ea7e1babSStefano Zampini for (k=0;k<size_prec_comm;k++){ 2163ea7e1babSStefano Zampini offset=pcbddc->local_primal_displacements[k]; 2164ea7e1babSStefano Zampini offset2=localdispl2[k]; 2165ea7e1babSStefano Zampini ins_local_primal_size = pcbddc->local_primal_sizes[k]; 2166ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2167ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2168ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2169ef028eecSStefano Zampini } 2170ea7e1babSStefano Zampini ins_coarse_mat_vals = &temp_coarse_mat_vals[offset2]; 2171ea7e1babSStefano 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); 2172ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2173ea7e1babSStefano Zampini } 2174ea7e1babSStefano Zampini ins_local_primal_indices = 0; 2175ea7e1babSStefano Zampini ins_coarse_mat_vals = 0; 2176ea7e1babSStefano Zampini } 21770c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 21780c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2179142dfd88SStefano Zampini /* symmetry of coarse matrix */ 2180142dfd88SStefano Zampini if (issym) { 2181142dfd88SStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 2182142dfd88SStefano Zampini } 21830c7d97c5SJed Brown ierr = MatGetVecs(pcbddc->coarse_mat,&pcbddc->coarse_vec,&pcbddc->coarse_rhs);CHKERRQ(ierr); 21840bdf917eSStefano Zampini } 21850bdf917eSStefano Zampini 21860bdf917eSStefano Zampini /* create loc to glob scatters if needed */ 21870bdf917eSStefano Zampini if (pcbddc->coarse_communications_type == SCATTERS_BDDC) { 21880bdf917eSStefano Zampini IS local_IS,global_IS; 21890bdf917eSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&local_IS);CHKERRQ(ierr); 21900bdf917eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_indices,PETSC_COPY_VALUES,&global_IS);CHKERRQ(ierr); 21910bdf917eSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,local_IS,pcbddc->coarse_vec,global_IS,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 21920bdf917eSStefano Zampini ierr = ISDestroy(&local_IS);CHKERRQ(ierr); 21930bdf917eSStefano Zampini ierr = ISDestroy(&global_IS);CHKERRQ(ierr); 21940bdf917eSStefano Zampini } 21950bdf917eSStefano Zampini 2196a929c220SStefano Zampini /* free memory no longer needed */ 2197a929c220SStefano Zampini if (coarse_ISLG) { ierr = ISLocalToGlobalMappingDestroy(&coarse_ISLG);CHKERRQ(ierr); } 2198a929c220SStefano Zampini if (ins_local_primal_indices) { ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); } 2199a929c220SStefano Zampini if (ins_coarse_mat_vals) { ierr = PetscFree(ins_coarse_mat_vals);CHKERRQ(ierr); } 2200a929c220SStefano Zampini if (localsizes2) { ierr = PetscFree(localsizes2);CHKERRQ(ierr); } 2201a929c220SStefano Zampini if (localdispl2) { ierr = PetscFree(localdispl2);CHKERRQ(ierr); } 2202a929c220SStefano Zampini if (temp_coarse_mat_vals) { ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr); } 2203a929c220SStefano Zampini 2204674ae819SStefano Zampini /* Compute coarse null space */ 2205674ae819SStefano Zampini CoarseNullSpace = 0; 22060bdf917eSStefano Zampini if (pcbddc->NullSpace) { 2207674ae819SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,&CoarseNullSpace);CHKERRQ(ierr); 22080bdf917eSStefano Zampini } 22090bdf917eSStefano Zampini 22100bdf917eSStefano Zampini /* KSP for coarse problem */ 22110bdf917eSStefano Zampini if (rank_prec_comm == active_rank) { 22122e8d2280SStefano Zampini PetscBool isbddc=PETSC_FALSE; 22130bdf917eSStefano Zampini 221453cdbc3dSStefano Zampini ierr = KSPCreate(coarse_comm,&pcbddc->coarse_ksp);CHKERRQ(ierr); 221553cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 221653cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 22173b03a366Sstefano_zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,max_it_coarse_ksp);CHKERRQ(ierr); 221853cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 221953cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 222053cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 22210c7d97c5SJed Brown /* Allow user's customization */ 2222da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,"coarse_");CHKERRQ(ierr); 22230c7d97c5SJed Brown /* Set Up PC for coarse problem BDDC */ 222453cdbc3dSStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 22254fad6a16SStefano Zampini i = pcbddc->current_level+1; 22264fad6a16SStefano Zampini ierr = PCBDDCSetLevel(pc_temp,i);CHKERRQ(ierr); 22274fad6a16SStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 22284fad6a16SStefano Zampini ierr = PCBDDCSetMaxLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 222953cdbc3dSStefano Zampini ierr = PCBDDCSetCoarseProblemType(pc_temp,MULTILEVEL_BDDC);CHKERRQ(ierr); 2230674ae819SStefano Zampini if (CoarseNullSpace) { 2231674ae819SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 2232674ae819SStefano Zampini } 22334fad6a16SStefano Zampini if (dbg_flag) { 22344fad6a16SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------Level %d: Setting up level %d---------------\n",pcbddc->current_level,i);CHKERRQ(ierr); 22354fad6a16SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 223653cdbc3dSStefano Zampini } 2237674ae819SStefano Zampini } else { 2238674ae819SStefano Zampini if (CoarseNullSpace) { 2239674ae819SStefano Zampini ierr = KSPSetNullSpace(pcbddc->coarse_ksp,CoarseNullSpace);CHKERRQ(ierr); 2240674ae819SStefano Zampini } 22414fad6a16SStefano Zampini } 22424fad6a16SStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 224353cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 2244142dfd88SStefano Zampini 22450298fd71SBarry Smith ierr = KSPGetTolerances(pcbddc->coarse_ksp,NULL,NULL,NULL,&j);CHKERRQ(ierr); 22462e8d2280SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 22472e8d2280SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 22482e8d2280SStefano Zampini if (j == 1) { 22492e8d2280SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 22502e8d2280SStefano Zampini if (isbddc) { 22512e8d2280SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc_temp,PETSC_FALSE);CHKERRQ(ierr); 22525619798eSStefano Zampini } 22535619798eSStefano Zampini } 22540c7d97c5SJed Brown } 2255a929c220SStefano Zampini /* Check coarse problem if requested */ 2256142dfd88SStefano Zampini if ( dbg_flag && rank_prec_comm == active_rank ) { 2257142dfd88SStefano Zampini KSP check_ksp; 2258142dfd88SStefano Zampini PC check_pc; 2259142dfd88SStefano Zampini Vec check_vec; 2260142dfd88SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min,lambda_max; 226119fd82e9SBarry Smith KSPType check_ksp_type; 22620c7d97c5SJed Brown 2263142dfd88SStefano Zampini /* Create ksp object suitable for extreme eigenvalues' estimation */ 2264142dfd88SStefano Zampini ierr = KSPCreate(coarse_comm,&check_ksp);CHKERRQ(ierr); 2265142dfd88SStefano Zampini ierr = KSPSetOperators(check_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 22660bdf917eSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 2267142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 22682fa5cd67SKarl Rupp if (issym) check_ksp_type = KSPCG; 22692fa5cd67SKarl Rupp else check_ksp_type = KSPGMRES; 2270142dfd88SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,PETSC_TRUE);CHKERRQ(ierr); 2271142dfd88SStefano Zampini } else { 2272142dfd88SStefano Zampini check_ksp_type = KSPPREONLY; 2273142dfd88SStefano Zampini } 2274142dfd88SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 2275142dfd88SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 2276142dfd88SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 2277142dfd88SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 2278142dfd88SStefano Zampini /* create random vec */ 2279142dfd88SStefano Zampini ierr = VecDuplicate(pcbddc->coarse_vec,&check_vec);CHKERRQ(ierr); 22800298fd71SBarry Smith ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 2281674ae819SStefano Zampini if (CoarseNullSpace) { 22821cb54aadSJed Brown ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 2283674ae819SStefano Zampini } 2284142dfd88SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,check_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 2285142dfd88SStefano Zampini /* solve coarse problem */ 2286142dfd88SStefano Zampini ierr = KSPSolve(check_ksp,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 2287674ae819SStefano Zampini if (CoarseNullSpace) { 22881cb54aadSJed Brown ierr = MatNullSpaceRemove(CoarseNullSpace,pcbddc->coarse_vec);CHKERRQ(ierr); 2289674ae819SStefano Zampini } 2290142dfd88SStefano Zampini /* check coarse problem residual error */ 2291142dfd88SStefano Zampini ierr = VecAXPY(check_vec,-1.0,pcbddc->coarse_vec);CHKERRQ(ierr); 2292142dfd88SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 2293142dfd88SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,check_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 2294142dfd88SStefano Zampini ierr = VecNorm(pcbddc->coarse_rhs,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 2295142dfd88SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 2296142dfd88SStefano Zampini /* get eigenvalue estimation if inexact */ 2297142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2298142dfd88SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); 2299142dfd88SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&k);CHKERRQ(ierr); 2300142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues estimated with %d iterations of %s.\n",k,check_ksp_type);CHKERRQ(ierr); 2301e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues: % 1.14e %1.14e\n",lambda_min,lambda_max);CHKERRQ(ierr); 23023b03a366Sstefano_zampini } 2303142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem exact infty_error : %1.14e\n",infty_error);CHKERRQ(ierr); 2304142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem residual infty_error: %1.14e\n",abs_infty_error);CHKERRQ(ierr); 2305142dfd88SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 230653cdbc3dSStefano Zampini } 2307674ae819SStefano Zampini if (dbg_flag) { 2308da1bb401SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2309da1bb401SStefano Zampini } 2310674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 2311a0ba757dSStefano Zampini 23120c7d97c5SJed Brown PetscFunctionReturn(0); 23130c7d97c5SJed Brown } 23140c7d97c5SJed Brown 2315