153cdbc3dSStefano Zampini /* TODOLIST 2da1bb401SStefano Zampini DofSplitting and DM attached to pc? 3da1bb401SStefano Zampini Change SetNeumannBoundaries to SetNeumannBoundariesLocal and provide new SetNeumannBoundaries (same Dirichlet) 4a0ba757dSStefano Zampini change how to deal with the coarse problem (PCBDDCSetCoarseEnvironment): 5a0ba757dSStefano Zampini - simplify coarse problem structure -> PCBDDC or PCREDUDANT, nothing else -> same comm for all levels? 6a0ba757dSStefano Zampini - remove coarse enums and allow use of PCBDDCGetCoarseKSP 7674ae819SStefano Zampini - remove metis dependency -> use MatPartitioning for multilevel -> Assemble serial adjacency in PCBDDCAnalyzeInterface? 8a0ba757dSStefano Zampini code refactoring: 9a0ba757dSStefano Zampini - pick up better names for static functions 10a0ba757dSStefano Zampini change options structure: 11a0ba757dSStefano Zampini - insert BDDC into MG framework? 12a0ba757dSStefano Zampini provide other ops? Ask to developers 13a0ba757dSStefano Zampini remove all unused printf 14a0ba757dSStefano Zampini man pages 1553cdbc3dSStefano Zampini */ 160c7d97c5SJed Brown 1753cdbc3dSStefano Zampini /* ---------------------------------------------------------------------------------------------------------------------------------------------- 180c7d97c5SJed Brown Implementation of BDDC preconditioner based on: 190c7d97c5SJed Brown C. Dohrmann "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 2053cdbc3dSStefano Zampini ---------------------------------------------------------------------------------------------------------------------------------------------- */ 2153cdbc3dSStefano Zampini 22674ae819SStefano Zampini #include "bddc.h" /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 23674ae819SStefano Zampini #include "bddcprivate.h" 243b03a366Sstefano_zampini #include <petscblaslapack.h> 25674ae819SStefano Zampini 26674ae819SStefano Zampini /* prototypes for static functions contained in bddc.c */ 27674ae819SStefano Zampini static PetscErrorCode PCBDDCSetLevel(PC,PetscInt); 28674ae819SStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC); 29674ae819SStefano Zampini 300c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 310c7d97c5SJed Brown #undef __FUNCT__ 320c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC" 330c7d97c5SJed Brown PetscErrorCode PCSetFromOptions_BDDC(PC pc) 340c7d97c5SJed Brown { 350c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 360c7d97c5SJed Brown PetscErrorCode ierr; 370c7d97c5SJed Brown 380c7d97c5SJed Brown PetscFunctionBegin; 390c7d97c5SJed Brown ierr = PetscOptionsHead("BDDC options");CHKERRQ(ierr); 400c7d97c5SJed Brown /* Verbose debugging of main data structures */ 419d9e44b6SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_check_level" ,"Verbose (debugging) output for PCBDDC" ,"none",pcbddc->dbg_flag ,&pcbddc->dbg_flag ,NULL);CHKERRQ(ierr); 420c7d97c5SJed Brown /* Some customization for default primal space */ 430298fd71SBarry Smith ierr = PetscOptionsBool("-pc_bddc_vertices_only" ,"Use only vertices in coarse space (i.e. discard constraints)","none",pcbddc->vertices_flag ,&pcbddc->vertices_flag ,NULL);CHKERRQ(ierr); 440298fd71SBarry Smith ierr = PetscOptionsBool("-pc_bddc_constraints_only","Use only constraints in coarse space (i.e. discard vertices)","none",pcbddc->constraints_flag,&pcbddc->constraints_flag,NULL);CHKERRQ(ierr); 450298fd71SBarry Smith ierr = PetscOptionsBool("-pc_bddc_faces_only" ,"Use only faces among constraints of coarse space (i.e. discard edges)" ,"none",pcbddc->faces_flag ,&pcbddc->faces_flag ,NULL);CHKERRQ(ierr); 460298fd71SBarry Smith ierr = PetscOptionsBool("-pc_bddc_edges_only" ,"Use only edges among constraints of coarse space (i.e. discard faces)" ,"none",pcbddc->edges_flag ,&pcbddc->edges_flag ,NULL);CHKERRQ(ierr); 470c7d97c5SJed Brown /* Coarse solver context */ 486c667b0aSStefano Zampini static const char * const avail_coarse_problems[] = {"sequential","replicated","parallel","multilevel","CoarseProblemType","PC_BDDC_",0}; /*order of choiches depends on ENUM defined in bddc.h */ 490298fd71SBarry Smith ierr = PetscOptionsEnum("-pc_bddc_coarse_problem_type","Set coarse problem type","none",avail_coarse_problems,(PetscEnum)pcbddc->coarse_problem_type,(PetscEnum*)&pcbddc->coarse_problem_type,NULL);CHKERRQ(ierr); 500c7d97c5SJed Brown /* Two different application of BDDC to the whole set of dofs, internal and interface */ 510298fd71SBarry Smith ierr = PetscOptionsBool("-pc_bddc_switch_preconditioning_type","Switch between M_2 (default) and M_3 preconditioners (as defined by Dohrmann)","none",pcbddc->inexact_prec_type,&pcbddc->inexact_prec_type,NULL);CHKERRQ(ierr); 52674ae819SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_change_of_basis","Use change of basis approach for primal space","none",pcbddc->use_change_of_basis,&pcbddc->use_change_of_basis,NULL);CHKERRQ(ierr); 53674ae819SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_change_on_faces","Use change of basis approach for face constraints","none",pcbddc->use_change_on_faces,&pcbddc->use_change_on_faces,NULL);CHKERRQ(ierr); 54674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 55674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 56674ae819SStefano Zampini } 570298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr); 580298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_max_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr); 59674ae819SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_deluxe_scaling","Use deluxe scaling for BDDC","none",pcbddc->use_deluxe_scaling,&pcbddc->use_deluxe_scaling,NULL);CHKERRQ(ierr); 600c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 610c7d97c5SJed Brown PetscFunctionReturn(0); 620c7d97c5SJed Brown } 630c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 64674ae819SStefano Zampini #undef __FUNCT__ 65674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS_BDDC" 66674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 67674ae819SStefano Zampini { 68674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 69674ae819SStefano Zampini PetscErrorCode ierr; 701e6b0712SBarry Smith 71674ae819SStefano Zampini PetscFunctionBegin; 72674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 73674ae819SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 74674ae819SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 75674ae819SStefano Zampini PetscFunctionReturn(0); 76674ae819SStefano Zampini } 77674ae819SStefano Zampini #undef __FUNCT__ 78674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS" 79674ae819SStefano Zampini /*@ 80674ae819SStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set user defined primal vertices in PCBDDC. 81674ae819SStefano Zampini 82674ae819SStefano Zampini Not collective 83674ae819SStefano Zampini 84674ae819SStefano Zampini Input Parameters: 85674ae819SStefano Zampini + pc - the preconditioning context 86674ae819SStefano Zampini - PrimalVertices - index sets of primal vertices in local numbering 87674ae819SStefano Zampini 88674ae819SStefano Zampini Level: intermediate 89674ae819SStefano Zampini 90674ae819SStefano Zampini Notes: 91674ae819SStefano Zampini 92674ae819SStefano Zampini .seealso: PCBDDC 93674ae819SStefano Zampini @*/ 94674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 95674ae819SStefano Zampini { 96674ae819SStefano Zampini PetscErrorCode ierr; 97674ae819SStefano Zampini 98674ae819SStefano Zampini PetscFunctionBegin; 99674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 100674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 101674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 102674ae819SStefano Zampini PetscFunctionReturn(0); 103674ae819SStefano Zampini } 104674ae819SStefano Zampini /* -------------------------------------------------------------------------- */ 1050c7d97c5SJed Brown #undef __FUNCT__ 1060c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType_BDDC" 10753cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetCoarseProblemType_BDDC(PC pc, CoarseProblemType CPT) 1080c7d97c5SJed Brown { 1090c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1100c7d97c5SJed Brown 1110c7d97c5SJed Brown PetscFunctionBegin; 1120c7d97c5SJed Brown pcbddc->coarse_problem_type = CPT; 1130c7d97c5SJed Brown PetscFunctionReturn(0); 1140c7d97c5SJed Brown } 1151e6b0712SBarry Smith 1160c7d97c5SJed Brown #undef __FUNCT__ 1170c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType" 11853cdbc3dSStefano Zampini /*@ 1199c0446d6SStefano Zampini PCBDDCSetCoarseProblemType - Set coarse problem type in PCBDDC. 12053cdbc3dSStefano Zampini 1219c0446d6SStefano Zampini Not collective 12253cdbc3dSStefano Zampini 12353cdbc3dSStefano Zampini Input Parameters: 12453cdbc3dSStefano Zampini + pc - the preconditioning context 12553cdbc3dSStefano Zampini - CoarseProblemType - pick a better name and explain what this is 12653cdbc3dSStefano Zampini 12753cdbc3dSStefano Zampini Level: intermediate 12853cdbc3dSStefano Zampini 12953cdbc3dSStefano Zampini Notes: 130da1bb401SStefano Zampini Not collective but all procs must call with same arguments. 13153cdbc3dSStefano Zampini 13253cdbc3dSStefano Zampini .seealso: PCBDDC 13353cdbc3dSStefano Zampini @*/ 1340c7d97c5SJed Brown PetscErrorCode PCBDDCSetCoarseProblemType(PC pc, CoarseProblemType CPT) 1350c7d97c5SJed Brown { 1360c7d97c5SJed Brown PetscErrorCode ierr; 1370c7d97c5SJed Brown 1380c7d97c5SJed Brown PetscFunctionBegin; 1390c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1400c7d97c5SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetCoarseProblemType_C",(PC,CoarseProblemType),(pc,CPT));CHKERRQ(ierr); 1410c7d97c5SJed Brown PetscFunctionReturn(0); 1420c7d97c5SJed Brown } 1430c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1440c7d97c5SJed Brown #undef __FUNCT__ 1454fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio_BDDC" 1464fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 1474fad6a16SStefano Zampini { 1484fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1494fad6a16SStefano Zampini 1504fad6a16SStefano Zampini PetscFunctionBegin; 1514fad6a16SStefano Zampini pcbddc->coarsening_ratio=k; 1524fad6a16SStefano Zampini PetscFunctionReturn(0); 1534fad6a16SStefano Zampini } 1541e6b0712SBarry Smith 1554fad6a16SStefano Zampini #undef __FUNCT__ 1564fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio" 1574fad6a16SStefano Zampini /*@ 1584fad6a16SStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel coarsening 1594fad6a16SStefano Zampini 1604fad6a16SStefano Zampini Logically collective on PC 1614fad6a16SStefano Zampini 1624fad6a16SStefano Zampini Input Parameters: 1634fad6a16SStefano Zampini + pc - the preconditioning context 1644fad6a16SStefano Zampini - k - coarsening ratio 1654fad6a16SStefano Zampini 1664fad6a16SStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level. 1674fad6a16SStefano Zampini 1684fad6a16SStefano Zampini Level: intermediate 1694fad6a16SStefano Zampini 1704fad6a16SStefano Zampini Notes: 1714fad6a16SStefano Zampini 1724fad6a16SStefano Zampini .seealso: PCBDDC 1734fad6a16SStefano Zampini @*/ 1744fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 1754fad6a16SStefano Zampini { 1764fad6a16SStefano Zampini PetscErrorCode ierr; 1774fad6a16SStefano Zampini 1784fad6a16SStefano Zampini PetscFunctionBegin; 1794fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1804fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 1814fad6a16SStefano Zampini PetscFunctionReturn(0); 1824fad6a16SStefano Zampini } 1834fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 1841e6b0712SBarry Smith 1854fad6a16SStefano Zampini #undef __FUNCT__ 1864fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetMaxLevels_BDDC" 1874fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetMaxLevels_BDDC(PC pc,PetscInt max_levels) 1884fad6a16SStefano Zampini { 1894fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1904fad6a16SStefano Zampini 1914fad6a16SStefano Zampini PetscFunctionBegin; 1924fad6a16SStefano Zampini pcbddc->max_levels=max_levels; 1934fad6a16SStefano Zampini PetscFunctionReturn(0); 1944fad6a16SStefano Zampini } 1951e6b0712SBarry Smith 1964fad6a16SStefano Zampini #undef __FUNCT__ 1974fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetMaxLevels" 1984fad6a16SStefano Zampini /*@ 1994fad6a16SStefano Zampini PCBDDCSetMaxLevels - Sets the maximum number of levels within the multilevel approach. 2004fad6a16SStefano Zampini 2014fad6a16SStefano Zampini Logically collective on PC 2024fad6a16SStefano Zampini 2034fad6a16SStefano Zampini Input Parameters: 2044fad6a16SStefano Zampini + pc - the preconditioning context 2054fad6a16SStefano Zampini - max_levels - the maximum number of levels 2064fad6a16SStefano Zampini 2074fad6a16SStefano Zampini Default value is 1, i.e. coarse problem will be solved inexactly with one application 2084fad6a16SStefano Zampini of PCBDDC preconditioner if the multilevel approach is requested. 2094fad6a16SStefano Zampini 2104fad6a16SStefano Zampini Level: intermediate 2114fad6a16SStefano Zampini 2124fad6a16SStefano Zampini Notes: 2134fad6a16SStefano Zampini 2144fad6a16SStefano Zampini .seealso: PCBDDC 2154fad6a16SStefano Zampini @*/ 2164fad6a16SStefano Zampini PetscErrorCode PCBDDCSetMaxLevels(PC pc,PetscInt max_levels) 2174fad6a16SStefano Zampini { 2184fad6a16SStefano Zampini PetscErrorCode ierr; 2194fad6a16SStefano Zampini 2204fad6a16SStefano Zampini PetscFunctionBegin; 2214fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2224fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetMaxLevels_C",(PC,PetscInt),(pc,max_levels));CHKERRQ(ierr); 2234fad6a16SStefano Zampini PetscFunctionReturn(0); 2244fad6a16SStefano Zampini } 2254fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 2261e6b0712SBarry Smith 2274fad6a16SStefano Zampini #undef __FUNCT__ 2280bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace_BDDC" 2290bdf917eSStefano Zampini static PetscErrorCode PCBDDCSetNullSpace_BDDC(PC pc,MatNullSpace NullSpace) 2300bdf917eSStefano Zampini { 2310bdf917eSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2320bdf917eSStefano Zampini PetscErrorCode ierr; 2330bdf917eSStefano Zampini 2340bdf917eSStefano Zampini PetscFunctionBegin; 2350bdf917eSStefano Zampini ierr = PetscObjectReference((PetscObject)NullSpace);CHKERRQ(ierr); 2360bdf917eSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 2370bdf917eSStefano Zampini pcbddc->NullSpace=NullSpace; 2380bdf917eSStefano Zampini PetscFunctionReturn(0); 2390bdf917eSStefano Zampini } 2401e6b0712SBarry Smith 2410bdf917eSStefano Zampini #undef __FUNCT__ 2420bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace" 2430bdf917eSStefano Zampini /*@ 2440bdf917eSStefano Zampini PCBDDCSetNullSpace - Set NullSpace of global operator of BDDC preconditioned mat. 2450bdf917eSStefano Zampini 2460bdf917eSStefano Zampini Logically collective on PC and MatNullSpace 2470bdf917eSStefano Zampini 2480bdf917eSStefano Zampini Input Parameters: 2490bdf917eSStefano Zampini + pc - the preconditioning context 2500bdf917eSStefano Zampini - NullSpace - Null space of the linear operator to be preconditioned. 2510bdf917eSStefano Zampini 2520bdf917eSStefano Zampini Level: intermediate 2530bdf917eSStefano Zampini 2540bdf917eSStefano Zampini Notes: 2550bdf917eSStefano Zampini 2560bdf917eSStefano Zampini .seealso: PCBDDC 2570bdf917eSStefano Zampini @*/ 2580bdf917eSStefano Zampini PetscErrorCode PCBDDCSetNullSpace(PC pc,MatNullSpace NullSpace) 2590bdf917eSStefano Zampini { 2600bdf917eSStefano Zampini PetscErrorCode ierr; 2610bdf917eSStefano Zampini 2620bdf917eSStefano Zampini PetscFunctionBegin; 2630bdf917eSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 264674ae819SStefano Zampini PetscValidHeaderSpecific(NullSpace,MAT_NULLSPACE_CLASSID,2); 2650bdf917eSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNullSpace_C",(PC,MatNullSpace),(pc,NullSpace));CHKERRQ(ierr); 2660bdf917eSStefano Zampini PetscFunctionReturn(0); 2670bdf917eSStefano Zampini } 2680bdf917eSStefano Zampini /* -------------------------------------------------------------------------- */ 2691e6b0712SBarry Smith 2700bdf917eSStefano Zampini #undef __FUNCT__ 2713b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC" 2723b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 2733b03a366Sstefano_zampini { 2743b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2753b03a366Sstefano_zampini PetscErrorCode ierr; 2763b03a366Sstefano_zampini 2773b03a366Sstefano_zampini PetscFunctionBegin; 2783b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 27936e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 28036e030ebSStefano Zampini pcbddc->DirichletBoundaries=DirichletBoundaries; 2813b03a366Sstefano_zampini PetscFunctionReturn(0); 2823b03a366Sstefano_zampini } 2831e6b0712SBarry Smith 2843b03a366Sstefano_zampini #undef __FUNCT__ 2853b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries" 2863b03a366Sstefano_zampini /*@ 287da1bb401SStefano Zampini PCBDDCSetDirichletBoundaries - Set index set defining subdomain part (in local ordering) 288da1bb401SStefano Zampini of Dirichlet boundaries for the global problem. 2893b03a366Sstefano_zampini 2903b03a366Sstefano_zampini Not collective 2913b03a366Sstefano_zampini 2923b03a366Sstefano_zampini Input Parameters: 2933b03a366Sstefano_zampini + pc - the preconditioning context 2940298fd71SBarry Smith - DirichletBoundaries - sequential index set defining the subdomain part of Dirichlet boundaries (can be NULL) 2953b03a366Sstefano_zampini 2963b03a366Sstefano_zampini Level: intermediate 2973b03a366Sstefano_zampini 2983b03a366Sstefano_zampini Notes: 2993b03a366Sstefano_zampini 3003b03a366Sstefano_zampini .seealso: PCBDDC 3013b03a366Sstefano_zampini @*/ 3023b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 3033b03a366Sstefano_zampini { 3043b03a366Sstefano_zampini PetscErrorCode ierr; 3053b03a366Sstefano_zampini 3063b03a366Sstefano_zampini PetscFunctionBegin; 3073b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 308674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 3093b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 3103b03a366Sstefano_zampini PetscFunctionReturn(0); 3113b03a366Sstefano_zampini } 3123b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 3131e6b0712SBarry Smith 3143b03a366Sstefano_zampini #undef __FUNCT__ 3150c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 31653cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 3170c7d97c5SJed Brown { 3180c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 31953cdbc3dSStefano Zampini PetscErrorCode ierr; 3200c7d97c5SJed Brown 3210c7d97c5SJed Brown PetscFunctionBegin; 32253cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 32336e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 32436e030ebSStefano Zampini pcbddc->NeumannBoundaries=NeumannBoundaries; 3250c7d97c5SJed Brown PetscFunctionReturn(0); 3260c7d97c5SJed Brown } 3271e6b0712SBarry Smith 3280c7d97c5SJed Brown #undef __FUNCT__ 3290c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 33057527edcSJed Brown /*@ 331da1bb401SStefano Zampini PCBDDCSetNeumannBoundaries - Set index set defining subdomain part (in local ordering) 332da1bb401SStefano Zampini of Neumann boundaries for the global problem. 33357527edcSJed Brown 3349c0446d6SStefano Zampini Not collective 33557527edcSJed Brown 33657527edcSJed Brown Input Parameters: 33757527edcSJed Brown + pc - the preconditioning context 3380298fd71SBarry Smith - NeumannBoundaries - sequential index set defining the subdomain part of Neumann boundaries (can be NULL) 33957527edcSJed Brown 34057527edcSJed Brown Level: intermediate 34157527edcSJed Brown 34257527edcSJed Brown Notes: 34357527edcSJed Brown 34457527edcSJed Brown .seealso: PCBDDC 34557527edcSJed Brown @*/ 34653cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 3470c7d97c5SJed Brown { 3480c7d97c5SJed Brown PetscErrorCode ierr; 3490c7d97c5SJed Brown 3500c7d97c5SJed Brown PetscFunctionBegin; 3510c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 352674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 35353cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 35453cdbc3dSStefano Zampini PetscFunctionReturn(0); 35553cdbc3dSStefano Zampini } 35653cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 3571e6b0712SBarry Smith 35853cdbc3dSStefano Zampini #undef __FUNCT__ 359da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC" 360da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 361da1bb401SStefano Zampini { 362da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 363da1bb401SStefano Zampini 364da1bb401SStefano Zampini PetscFunctionBegin; 365da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 366da1bb401SStefano Zampini PetscFunctionReturn(0); 367da1bb401SStefano Zampini } 3681e6b0712SBarry Smith 369da1bb401SStefano Zampini #undef __FUNCT__ 370da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries" 371da1bb401SStefano Zampini /*@ 372da1bb401SStefano Zampini PCBDDCGetDirichletBoundaries - Get index set defining subdomain part (in local ordering) 373da1bb401SStefano Zampini of Dirichlet boundaries for the global problem. 374da1bb401SStefano Zampini 375da1bb401SStefano Zampini Not collective 376da1bb401SStefano Zampini 377da1bb401SStefano Zampini Input Parameters: 378da1bb401SStefano Zampini + pc - the preconditioning context 379da1bb401SStefano Zampini 380da1bb401SStefano Zampini Output Parameters: 381da1bb401SStefano Zampini + DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 382da1bb401SStefano Zampini 383da1bb401SStefano Zampini Level: intermediate 384da1bb401SStefano Zampini 385da1bb401SStefano Zampini Notes: 386da1bb401SStefano Zampini 387da1bb401SStefano Zampini .seealso: PCBDDC 388da1bb401SStefano Zampini @*/ 389da1bb401SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 390da1bb401SStefano Zampini { 391da1bb401SStefano Zampini PetscErrorCode ierr; 392da1bb401SStefano Zampini 393da1bb401SStefano Zampini PetscFunctionBegin; 394da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 395da1bb401SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 396da1bb401SStefano Zampini PetscFunctionReturn(0); 397da1bb401SStefano Zampini } 398da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 3991e6b0712SBarry Smith 400da1bb401SStefano Zampini #undef __FUNCT__ 40153cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 40253cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 40353cdbc3dSStefano Zampini { 40453cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 40553cdbc3dSStefano Zampini 40653cdbc3dSStefano Zampini PetscFunctionBegin; 40753cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 40853cdbc3dSStefano Zampini PetscFunctionReturn(0); 40953cdbc3dSStefano Zampini } 4101e6b0712SBarry Smith 41153cdbc3dSStefano Zampini #undef __FUNCT__ 41253cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 41353cdbc3dSStefano Zampini /*@ 414da1bb401SStefano Zampini PCBDDCGetNeumannBoundaries - Get index set defining subdomain part (in local ordering) 415da1bb401SStefano Zampini of Neumann boundaries for the global problem. 41653cdbc3dSStefano Zampini 4179c0446d6SStefano Zampini Not collective 41853cdbc3dSStefano Zampini 41953cdbc3dSStefano Zampini Input Parameters: 42053cdbc3dSStefano Zampini + pc - the preconditioning context 42153cdbc3dSStefano Zampini 42253cdbc3dSStefano Zampini Output Parameters: 42353cdbc3dSStefano Zampini + NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 42453cdbc3dSStefano Zampini 42553cdbc3dSStefano Zampini Level: intermediate 42653cdbc3dSStefano Zampini 42753cdbc3dSStefano Zampini Notes: 42853cdbc3dSStefano Zampini 42953cdbc3dSStefano Zampini .seealso: PCBDDC 43053cdbc3dSStefano Zampini @*/ 43153cdbc3dSStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 43253cdbc3dSStefano Zampini { 43353cdbc3dSStefano Zampini PetscErrorCode ierr; 43453cdbc3dSStefano Zampini 43553cdbc3dSStefano Zampini PetscFunctionBegin; 43653cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 43753cdbc3dSStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 4380c7d97c5SJed Brown PetscFunctionReturn(0); 4390c7d97c5SJed Brown } 44036e030ebSStefano Zampini /* -------------------------------------------------------------------------- */ 4411e6b0712SBarry Smith 44236e030ebSStefano Zampini #undef __FUNCT__ 443da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC" 4441a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 44536e030ebSStefano Zampini { 44636e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 447da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 448da1bb401SStefano Zampini PetscErrorCode ierr; 44936e030ebSStefano Zampini 45036e030ebSStefano Zampini PetscFunctionBegin; 451674ae819SStefano Zampini /* free old CSR */ 452674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 453fb223d50SStefano Zampini /* TODO: PCBDDCGraphSetAdjacency */ 454674ae819SStefano Zampini /* get CSR into graph structure */ 455da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 456674ae819SStefano Zampini ierr = PetscMalloc((nvtxs+1)*sizeof(PetscInt),&mat_graph->xadj);CHKERRQ(ierr); 457674ae819SStefano Zampini ierr = PetscMalloc(xadj[nvtxs]*sizeof(PetscInt),&mat_graph->adjncy);CHKERRQ(ierr); 458674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 459674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 460da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 4611a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 4621a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 463674ae819SStefano Zampini } 464575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 46536e030ebSStefano Zampini PetscFunctionReturn(0); 46636e030ebSStefano Zampini } 4671e6b0712SBarry Smith 46836e030ebSStefano Zampini #undef __FUNCT__ 469da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph" 47036e030ebSStefano Zampini /*@ 471da1bb401SStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set CSR graph of local matrix for use of PCBDDC. 47236e030ebSStefano Zampini 47336e030ebSStefano Zampini Not collective 47436e030ebSStefano Zampini 47536e030ebSStefano Zampini Input Parameters: 47636e030ebSStefano Zampini + pc - the preconditioning context 477da1bb401SStefano Zampini - nvtxs - number of local vertices of the graph 478da1bb401SStefano Zampini - xadj, adjncy - the CSR graph 479da1bb401SStefano Zampini - copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER. In the former case the user must free the array passed in; 480da1bb401SStefano Zampini in the latter case, memory must be obtained with PetscMalloc. 48136e030ebSStefano Zampini 48236e030ebSStefano Zampini Level: intermediate 48336e030ebSStefano Zampini 48436e030ebSStefano Zampini Notes: 48536e030ebSStefano Zampini 48636e030ebSStefano Zampini .seealso: PCBDDC 48736e030ebSStefano Zampini @*/ 4881a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 48936e030ebSStefano Zampini { 490575ad6abSStefano Zampini void (*f)(void) = 0; 49136e030ebSStefano Zampini PetscErrorCode ierr; 49236e030ebSStefano Zampini 49336e030ebSStefano Zampini PetscFunctionBegin; 49436e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 495674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 496674ae819SStefano Zampini PetscValidIntPointer(xadj,4); 497674ae819SStefano Zampini if (copymode != PETSC_COPY_VALUES && copymode != PETSC_OWN_POINTER) { 498674ae819SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d in %s\n",copymode,__FUNCT__); 499da1bb401SStefano Zampini } 50036e030ebSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 501575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 502575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 503575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 504575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 505575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 50636e030ebSStefano Zampini } 50736e030ebSStefano Zampini PetscFunctionReturn(0); 50836e030ebSStefano Zampini } 5099c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 5101e6b0712SBarry Smith 5119c0446d6SStefano Zampini #undef __FUNCT__ 5129c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 5139c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 5149c0446d6SStefano Zampini { 5159c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5169c0446d6SStefano Zampini PetscInt i; 5179c0446d6SStefano Zampini PetscErrorCode ierr; 5189c0446d6SStefano Zampini 5199c0446d6SStefano Zampini PetscFunctionBegin; 520da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 5219c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 5229c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 5239c0446d6SStefano Zampini } 524d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 525da1bb401SStefano Zampini /* allocate space then set */ 5269c0446d6SStefano Zampini ierr = PetscMalloc(n_is*sizeof(IS),&pcbddc->ISForDofs);CHKERRQ(ierr); 5279c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 528da1bb401SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 529da1bb401SStefano Zampini pcbddc->ISForDofs[i]=ISForDofs[i]; 5309c0446d6SStefano Zampini } 5319c0446d6SStefano Zampini pcbddc->n_ISForDofs=n_is; 5329c0446d6SStefano Zampini PetscFunctionReturn(0); 5339c0446d6SStefano Zampini } 5341e6b0712SBarry Smith 5359c0446d6SStefano Zampini #undef __FUNCT__ 5369c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 5379c0446d6SStefano Zampini /*@ 538da1bb401SStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of local mat. 5399c0446d6SStefano Zampini 5409c0446d6SStefano Zampini Not collective 5419c0446d6SStefano Zampini 5429c0446d6SStefano Zampini Input Parameters: 5439c0446d6SStefano Zampini + pc - the preconditioning context 544da1bb401SStefano Zampini - n - number of index sets defining the fields 545da1bb401SStefano Zampini - IS[] - array of IS describing the fields 5469c0446d6SStefano Zampini 5479c0446d6SStefano Zampini Level: intermediate 5489c0446d6SStefano Zampini 5499c0446d6SStefano Zampini Notes: 5509c0446d6SStefano Zampini 5519c0446d6SStefano Zampini .seealso: PCBDDC 5529c0446d6SStefano Zampini @*/ 5539c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 5549c0446d6SStefano Zampini { 5559c0446d6SStefano Zampini PetscErrorCode ierr; 5569c0446d6SStefano Zampini 5579c0446d6SStefano Zampini PetscFunctionBegin; 5589c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5599c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 5609c0446d6SStefano Zampini PetscFunctionReturn(0); 5619c0446d6SStefano Zampini } 562da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 563534831adSStefano Zampini #undef __FUNCT__ 564534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC" 565534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 566534831adSStefano Zampini /* 567534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 568534831adSStefano Zampini guess if a transformation of basis approach has been selected. 5699c0446d6SStefano Zampini 570534831adSStefano Zampini Input Parameter: 571534831adSStefano Zampini + pc - the preconditioner contex 572534831adSStefano Zampini 573534831adSStefano Zampini Application Interface Routine: PCPreSolve() 574534831adSStefano Zampini 575534831adSStefano Zampini Notes: 576534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 577534831adSStefano Zampini the user, but instead is called by KSPSolve(). 578534831adSStefano Zampini */ 579534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 580534831adSStefano Zampini { 581534831adSStefano Zampini PetscErrorCode ierr; 582534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 583534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 584534831adSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 585534831adSStefano Zampini Mat temp_mat; 5863972b0daSStefano Zampini IS dirIS; 5873972b0daSStefano Zampini PetscInt dirsize,i,*is_indices; 5883972b0daSStefano Zampini PetscScalar *array_x,*array_diagonal; 5893972b0daSStefano Zampini Vec used_vec; 5903972b0daSStefano Zampini PetscBool guess_nonzero; 591534831adSStefano Zampini 592534831adSStefano Zampini PetscFunctionBegin; 59362a6ff1dSStefano Zampini /* Creates parallel work vectors used in presolve. */ 59462a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 59562a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 59662a6ff1dSStefano Zampini } 59762a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 59862a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 59962a6ff1dSStefano Zampini } 6003972b0daSStefano Zampini if (x) { 6013972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 6023972b0daSStefano Zampini used_vec = x; 6033972b0daSStefano Zampini } else { 6043972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 6053972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 6063972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 6073972b0daSStefano Zampini } 6083972b0daSStefano Zampini /* hack into ksp data structure PCPreSolve comes earlier in src/ksp/ksp/interface/itfunc.c */ 6093972b0daSStefano Zampini if (ksp) { 6103972b0daSStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&guess_nonzero);CHKERRQ(ierr); 6113972b0daSStefano Zampini if ( !guess_nonzero ) { 6123972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 6133972b0daSStefano Zampini } 6143972b0daSStefano Zampini } 6153308cffdSStefano Zampini 61662a6ff1dSStefano Zampini if (rhs) { /* TODO: wiser handling of rhs removal, which is only needed in case of zeroed rows */ 6173972b0daSStefano Zampini /* store the original rhs */ 6183972b0daSStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 6193972b0daSStefano Zampini 6203972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 6213972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 6223972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 6233972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6243972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6253972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6263972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6273972b0daSStefano Zampini ierr = PCBDDCGetDirichletBoundaries(pc,&dirIS);CHKERRQ(ierr); 6283972b0daSStefano Zampini if (dirIS) { 6293972b0daSStefano Zampini ierr = ISGetSize(dirIS,&dirsize);CHKERRQ(ierr); 6303972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 6313972b0daSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 6323972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6332fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 6343972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6353972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 6363972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 6373972b0daSStefano Zampini } 6383972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6393972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 640b76ba322SStefano Zampini 6413972b0daSStefano Zampini /* remove the computed solution from the rhs */ 6423972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 6433972b0daSStefano Zampini ierr = MatMultAdd(pc->pmat,used_vec,rhs,rhs);CHKERRQ(ierr); 6443972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 6453308cffdSStefano Zampini } 646b76ba322SStefano Zampini 647b76ba322SStefano Zampini /* store partially computed solution and set initial guess */ 6483972b0daSStefano Zampini if (x) { 6493972b0daSStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 6503972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 65115aaf578SStefano Zampini if (pcbddc->use_exact_dirichlet && !pcbddc->coarse_psi_B) { 652b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 653b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 654b76ba322SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 655b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 656b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 657b76ba322SStefano Zampini if (ksp) { 658b76ba322SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 659b76ba322SStefano Zampini } 660b76ba322SStefano Zampini } 6613972b0daSStefano Zampini } 662b76ba322SStefano Zampini 663674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 664b76ba322SStefano Zampini /* swap pointers for local matrices */ 665b76ba322SStefano Zampini temp_mat = matis->A; 666b76ba322SStefano Zampini matis->A = pcbddc->local_mat; 667b76ba322SStefano Zampini pcbddc->local_mat = temp_mat; 6683308cffdSStefano Zampini } 6693308cffdSStefano Zampini if (pcbddc->use_change_of_basis && rhs) { 670b76ba322SStefano Zampini /* Get local rhs and apply transformation of basis */ 671b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 672b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 673b76ba322SStefano Zampini /* from original basis to modified basis */ 674b76ba322SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 675b76ba322SStefano Zampini /* put back modified values into the global vec using INSERT_VALUES copy mode */ 676b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 677b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 678674ae819SStefano Zampini } 6790bdf917eSStefano Zampini if (ksp && pcbddc->NullSpace) { 680d0195637SJed Brown ierr = MatNullSpaceRemove(pcbddc->NullSpace,used_vec);CHKERRQ(ierr); 681d0195637SJed Brown ierr = MatNullSpaceRemove(pcbddc->NullSpace,rhs);CHKERRQ(ierr); 682b76ba322SStefano Zampini } 6830bdf917eSStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 684534831adSStefano Zampini PetscFunctionReturn(0); 685534831adSStefano Zampini } 686534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 687534831adSStefano Zampini #undef __FUNCT__ 688534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC" 689534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 690534831adSStefano Zampini /* 691534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 692534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 693534831adSStefano Zampini 694534831adSStefano Zampini Input Parameter: 695534831adSStefano Zampini + pc - the preconditioner contex 696534831adSStefano Zampini 697534831adSStefano Zampini Application Interface Routine: PCPostSolve() 698534831adSStefano Zampini 699534831adSStefano Zampini Notes: 700534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 701534831adSStefano Zampini the user, but instead is called by KSPSolve(). 702534831adSStefano Zampini */ 703534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 704534831adSStefano Zampini { 705534831adSStefano Zampini PetscErrorCode ierr; 706534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 707534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 708534831adSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 709534831adSStefano Zampini Mat temp_mat; 710534831adSStefano Zampini 711534831adSStefano Zampini PetscFunctionBegin; 712674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 713534831adSStefano Zampini /* swap pointers for local matrices */ 714534831adSStefano Zampini temp_mat = matis->A; 715534831adSStefano Zampini matis->A = pcbddc->local_mat; 716534831adSStefano Zampini pcbddc->local_mat = temp_mat; 7173425bc38SStefano Zampini } 7183308cffdSStefano Zampini if (pcbddc->use_change_of_basis && x) { 719534831adSStefano Zampini /* Get Local boundary and apply transformation of basis to solution vector */ 720534831adSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 721534831adSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 722534831adSStefano Zampini /* from modified basis to original basis */ 723534831adSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 724534831adSStefano Zampini /* put back modified values into the global vec using INSERT_VALUES copy mode */ 725534831adSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 726534831adSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 727534831adSStefano Zampini } 7283972b0daSStefano Zampini /* add solution removed in presolve */ 7293425bc38SStefano Zampini if (x) { 7303425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 7313425bc38SStefano Zampini } 732fb223d50SStefano Zampini /* restore rhs to its original state */ 733fb223d50SStefano Zampini if (rhs) { 734fb223d50SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,rhs);CHKERRQ(ierr); 735fb223d50SStefano Zampini } 736534831adSStefano Zampini PetscFunctionReturn(0); 737534831adSStefano Zampini } 738534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 73953cdbc3dSStefano Zampini #undef __FUNCT__ 74053cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 7410c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 7420c7d97c5SJed Brown /* 7430c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 7440c7d97c5SJed Brown by setting data structures and options. 7450c7d97c5SJed Brown 7460c7d97c5SJed Brown Input Parameter: 74753cdbc3dSStefano Zampini + pc - the preconditioner context 7480c7d97c5SJed Brown 7490c7d97c5SJed Brown Application Interface Routine: PCSetUp() 7500c7d97c5SJed Brown 7510c7d97c5SJed Brown Notes: 7520c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 7530c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 7540c7d97c5SJed Brown */ 75553cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 7560c7d97c5SJed Brown { 7570c7d97c5SJed Brown PetscErrorCode ierr; 7580c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 759674ae819SStefano Zampini MatStructure flag; 760674ae819SStefano Zampini PetscBool computeis,computetopography,computesolvers; 7610c7d97c5SJed Brown 7620c7d97c5SJed Brown PetscFunctionBegin; 763674ae819SStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other nonoverlapping preconditioners */ 7643b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 7659c0446d6SStefano Zampini So, we set to pcnone the Neumann problem of pcis in order to avoid unneeded computation 7660c7d97c5SJed Brown Also, we decide to directly build the (same) Dirichlet problem */ 7670c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localN_pc_type","none");CHKERRQ(ierr); 7680c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localD_pc_type","none");CHKERRQ(ierr); 7693b03a366Sstefano_zampini /* Get stdout for dbg */ 770674ae819SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->dbg_viewer) { 771ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pc),&pcbddc->dbg_viewer);CHKERRQ(ierr); 772e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 773e269702eSStefano Zampini } 774674ae819SStefano Zampini /* first attempt to split work */ 775674ae819SStefano Zampini if (pc->setupcalled) { 776674ae819SStefano Zampini computeis = PETSC_FALSE; 777674ae819SStefano Zampini ierr = PCGetOperators(pc,NULL,NULL,&flag);CHKERRQ(ierr); 778674ae819SStefano Zampini if (flag == SAME_PRECONDITIONER) { 779674ae819SStefano Zampini computetopography = PETSC_FALSE; 780674ae819SStefano Zampini computesolvers = PETSC_FALSE; 781674ae819SStefano Zampini } else if (flag == SAME_NONZERO_PATTERN) { 782674ae819SStefano Zampini computetopography = PETSC_FALSE; 783674ae819SStefano Zampini computesolvers = PETSC_TRUE; 784674ae819SStefano Zampini } else { /* DIFFERENT_NONZERO_PATTERN */ 785674ae819SStefano Zampini computetopography = PETSC_TRUE; 786674ae819SStefano Zampini computesolvers = PETSC_TRUE; 787674ae819SStefano Zampini } 788674ae819SStefano Zampini } else { 789674ae819SStefano Zampini computeis = PETSC_TRUE; 790674ae819SStefano Zampini computetopography = PETSC_TRUE; 791674ae819SStefano Zampini computesolvers = PETSC_TRUE; 792674ae819SStefano Zampini } 793674ae819SStefano Zampini /* Set up all the "iterative substructuring" common block */ 794674ae819SStefano Zampini if (computeis) { 795674ae819SStefano Zampini ierr = PCISSetUp(pc);CHKERRQ(ierr); 796674ae819SStefano Zampini } 797674ae819SStefano Zampini /* Analyze interface and set up local constraint and change of basis matrices */ 798674ae819SStefano Zampini if (computetopography) { 799674ae819SStefano Zampini /* reset data */ 800674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 801674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 802674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 803674ae819SStefano Zampini } 804674ae819SStefano Zampini if (computesolvers) { 805674ae819SStefano Zampini /* reset data */ 806674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 807674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 8080c7d97c5SJed Brown /* Create coarse and local stuffs used for evaluating action of preconditioner */ 8090c7d97c5SJed Brown ierr = PCBDDCCoarseSetUp(pc);CHKERRQ(ierr); 810674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 8110c7d97c5SJed Brown } 8120c7d97c5SJed Brown PetscFunctionReturn(0); 8130c7d97c5SJed Brown } 8140c7d97c5SJed Brown 8150c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 8160c7d97c5SJed Brown /* 8170c7d97c5SJed Brown PCApply_BDDC - Applies the BDDC preconditioner to a vector. 8180c7d97c5SJed Brown 8190c7d97c5SJed Brown Input Parameters: 8200c7d97c5SJed Brown . pc - the preconditioner context 8210c7d97c5SJed Brown . r - input vector (global) 8220c7d97c5SJed Brown 8230c7d97c5SJed Brown Output Parameter: 8240c7d97c5SJed Brown . z - output vector (global) 8250c7d97c5SJed Brown 8260c7d97c5SJed Brown Application Interface Routine: PCApply() 8270c7d97c5SJed Brown */ 8280c7d97c5SJed Brown #undef __FUNCT__ 8290c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 83053cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 8310c7d97c5SJed Brown { 8320c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 8330c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 8340c7d97c5SJed Brown PetscErrorCode ierr; 8353b03a366Sstefano_zampini const PetscScalar one = 1.0; 8363b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 8372617d88aSStefano Zampini const PetscScalar zero = 0.0; 8380c7d97c5SJed Brown 8390c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 8400c7d97c5SJed Brown NN interface preconditioner changed to BDDC 84129622bf0SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->inexact_prec_type = PETSC_TRUE) */ 8420c7d97c5SJed Brown 8430c7d97c5SJed Brown PetscFunctionBegin; 84415aaf578SStefano Zampini if (!pcbddc->use_exact_dirichlet || pcbddc->coarse_psi_B) { 8450c7d97c5SJed Brown /* First Dirichlet solve */ 8460c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8470c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 84853cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 8490c7d97c5SJed Brown /* 8500c7d97c5SJed Brown Assembling right hand side for BDDC operator 851674ae819SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE) 852674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 8530c7d97c5SJed Brown */ 8540c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 8550c7d97c5SJed Brown ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 85629622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 8570c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 8580c7d97c5SJed Brown ierr = VecCopy(r,z);CHKERRQ(ierr); 8590c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8600c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 861674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 862b76ba322SStefano Zampini } else { 8630bdf917eSStefano Zampini ierr = VecSet(pcis->vec1_D,zero);CHKERRQ(ierr); 864b76ba322SStefano Zampini ierr = VecSet(pcis->vec2_D,zero);CHKERRQ(ierr); 865674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 866b76ba322SStefano Zampini } 867b76ba322SStefano Zampini 8682617d88aSStefano Zampini /* Apply interface preconditioner 8692617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 8702617d88aSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc);CHKERRQ(ierr); 8712617d88aSStefano Zampini 872674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 873674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 8740c7d97c5SJed Brown 8753b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 8760c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8770c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8780c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 87929622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 88053cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr); 8810c7d97c5SJed Brown ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr); 88229622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); } 8830c7d97c5SJed Brown ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr); 8840c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8850c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8860c7d97c5SJed Brown PetscFunctionReturn(0); 8870c7d97c5SJed Brown } 888da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 889674ae819SStefano Zampini 890da1bb401SStefano Zampini #undef __FUNCT__ 891da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC" 892da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 893da1bb401SStefano Zampini { 894da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 895da1bb401SStefano Zampini PetscErrorCode ierr; 896da1bb401SStefano Zampini 897da1bb401SStefano Zampini PetscFunctionBegin; 898da1bb401SStefano Zampini /* free data created by PCIS */ 899da1bb401SStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 900674ae819SStefano Zampini /* free BDDC custom data */ 901674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 902674ae819SStefano Zampini /* destroy objects related to topography */ 903674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 904674ae819SStefano Zampini /* free allocated graph structure */ 905da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr); 906674ae819SStefano Zampini /* free data for scaling operator */ 907674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 908674ae819SStefano Zampini /* free solvers stuff */ 909674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 91033bc96a4SStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 91133bc96a4SStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 912ac78edfcSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 91362a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 91462a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 91562a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 9163425bc38SStefano Zampini /* remove functions */ 917674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 918bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 919bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetMaxLevels_C",NULL);CHKERRQ(ierr); 920bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",NULL);CHKERRQ(ierr); 921bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 922bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 923bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 924bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 925bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseProblemType_C",NULL);CHKERRQ(ierr); 926bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 927bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 928bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 929bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 930bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 931674ae819SStefano Zampini /* Free the private data structure */ 932674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 933da1bb401SStefano Zampini PetscFunctionReturn(0); 934da1bb401SStefano Zampini } 9353425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 9361e6b0712SBarry Smith 9373425bc38SStefano Zampini #undef __FUNCT__ 9383425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC" 9393425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 9403425bc38SStefano Zampini { 941674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 9423425bc38SStefano Zampini PC_IS* pcis; 9433425bc38SStefano Zampini PC_BDDC* pcbddc; 9443425bc38SStefano Zampini PetscErrorCode ierr; 9450c7d97c5SJed Brown 9463425bc38SStefano Zampini PetscFunctionBegin; 9473425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 9483425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 9493425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 9503425bc38SStefano Zampini 9513425bc38SStefano Zampini /* change of basis for physical rhs if needed 9523425bc38SStefano Zampini It also changes the rhs in case of dirichlet boundaries */ 9533308cffdSStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,standard_rhs,NULL);CHKERRQ(ierr); 9543425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 9553425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9563425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 957fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 958fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 9593425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9603425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 961674ae819SStefano Zampini /* Apply partition of unity */ 9623425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 963674ae819SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 96429622bf0SStefano Zampini if (!pcbddc->inexact_prec_type) { 9653425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 9663425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 9673425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 9683425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 9693425bc38SStefano Zampini ierr = VecSet(standard_rhs,0.0);CHKERRQ(ierr); 9703425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9713425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 972674ae819SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 9733425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9743425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9753425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 9763425bc38SStefano Zampini } 9773425bc38SStefano Zampini /* BDDC rhs */ 9783425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 97929622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { 9803425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 9813425bc38SStefano Zampini } 9823425bc38SStefano Zampini /* apply BDDC */ 9833425bc38SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr); 9843425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 9853425bc38SStefano Zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 9863425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 9873425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9883425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9893425bc38SStefano Zampini /* restore original rhs */ 9903425bc38SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,standard_rhs);CHKERRQ(ierr); 9913425bc38SStefano Zampini PetscFunctionReturn(0); 9923425bc38SStefano Zampini } 9931e6b0712SBarry Smith 9943425bc38SStefano Zampini #undef __FUNCT__ 9953425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS" 9963425bc38SStefano Zampini /*@ 9973425bc38SStefano Zampini PCBDDCMatFETIDPGetRHS - Get rhs for FETIDP linear system. 9983425bc38SStefano Zampini 9993425bc38SStefano Zampini Collective 10003425bc38SStefano Zampini 10013425bc38SStefano Zampini Input Parameters: 10023425bc38SStefano Zampini + fetidp_mat - the FETIDP mat obtained by a call to PCBDDCCreateFETIDPOperators 10033425bc38SStefano Zampini + standard_rhs - the rhs of your linear system 10043425bc38SStefano Zampini 10053425bc38SStefano Zampini Output Parameters: 10063425bc38SStefano Zampini + fetidp_flux_rhs - the rhs of the FETIDP linear system 10073425bc38SStefano Zampini 10083425bc38SStefano Zampini Level: developer 10093425bc38SStefano Zampini 10103425bc38SStefano Zampini Notes: 10113425bc38SStefano Zampini 10123425bc38SStefano Zampini .seealso: PCBDDC 10133425bc38SStefano Zampini @*/ 10143425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 10153425bc38SStefano Zampini { 1016674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 10173425bc38SStefano Zampini PetscErrorCode ierr; 10183425bc38SStefano Zampini 10193425bc38SStefano Zampini PetscFunctionBegin; 10203425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10213425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 10223425bc38SStefano Zampini PetscFunctionReturn(0); 10233425bc38SStefano Zampini } 10243425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 10251e6b0712SBarry Smith 10263425bc38SStefano Zampini #undef __FUNCT__ 10273425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC" 10283425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 10293425bc38SStefano Zampini { 1030674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 10313425bc38SStefano Zampini PC_IS* pcis; 10323425bc38SStefano Zampini PC_BDDC* pcbddc; 10333425bc38SStefano Zampini PetscErrorCode ierr; 10343425bc38SStefano Zampini 10353425bc38SStefano Zampini PetscFunctionBegin; 10363425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10373425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 10383425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 10393425bc38SStefano Zampini 10403425bc38SStefano Zampini /* apply B_delta^T */ 10413425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10423425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10433425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 10443425bc38SStefano Zampini /* compute rhs for BDDC application */ 10453425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 104629622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { 10473425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 10483425bc38SStefano Zampini } 10493425bc38SStefano Zampini /* apply BDDC */ 10503425bc38SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr); 10513425bc38SStefano Zampini /* put values into standard global vector */ 10523425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10533425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 105429622bf0SStefano Zampini if (!pcbddc->inexact_prec_type) { 10553425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 10563425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 10573425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_D,-1.0,pcis->vec1_D);CHKERRQ(ierr); 10583425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 10593425bc38SStefano Zampini } 10603425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10613425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10623425bc38SStefano Zampini /* final change of basis if needed 10633425bc38SStefano Zampini Is also sums the dirichlet part removed during RHS assembling */ 10643308cffdSStefano Zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 10653425bc38SStefano Zampini PetscFunctionReturn(0); 10663425bc38SStefano Zampini } 10671e6b0712SBarry Smith 10683425bc38SStefano Zampini #undef __FUNCT__ 10693425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution" 10703425bc38SStefano Zampini /*@ 10713425bc38SStefano Zampini PCBDDCMatFETIDPGetSolution - Get Solution for FETIDP linear system. 10723425bc38SStefano Zampini 10733425bc38SStefano Zampini Collective 10743425bc38SStefano Zampini 10753425bc38SStefano Zampini Input Parameters: 10763425bc38SStefano Zampini + fetidp_mat - the FETIDP mat obtained by a call to PCBDDCCreateFETIDPOperators 10773425bc38SStefano Zampini + fetidp_flux_sol - the solution of the FETIDP linear system 10783425bc38SStefano Zampini 10793425bc38SStefano Zampini Output Parameters: 10803425bc38SStefano Zampini + standard_sol - the solution on the global domain 10813425bc38SStefano Zampini 10823425bc38SStefano Zampini Level: developer 10833425bc38SStefano Zampini 10843425bc38SStefano Zampini Notes: 10853425bc38SStefano Zampini 10863425bc38SStefano Zampini .seealso: PCBDDC 10873425bc38SStefano Zampini @*/ 10883425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 10893425bc38SStefano Zampini { 1090674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 10913425bc38SStefano Zampini PetscErrorCode ierr; 10923425bc38SStefano Zampini 10933425bc38SStefano Zampini PetscFunctionBegin; 10943425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10953425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 10963425bc38SStefano Zampini PetscFunctionReturn(0); 10973425bc38SStefano Zampini } 10983425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 10991e6b0712SBarry Smith 1100f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec); 1101f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat); 1102f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec); 1103f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC); 1104674ae819SStefano Zampini 11053425bc38SStefano Zampini #undef __FUNCT__ 11063425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC" 11073425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 11083425bc38SStefano Zampini { 1109674ae819SStefano Zampini 1110674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 11113425bc38SStefano Zampini Mat newmat; 1112674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 11133425bc38SStefano Zampini PC newpc; 1114ce94432eSBarry Smith MPI_Comm comm; 11153425bc38SStefano Zampini PetscErrorCode ierr; 11163425bc38SStefano Zampini 11173425bc38SStefano Zampini PetscFunctionBegin; 1118ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 11193425bc38SStefano Zampini /* FETIDP linear matrix */ 11203425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 11213425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 11223425bc38SStefano Zampini ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 11233425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 11243425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 11253425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 11263425bc38SStefano Zampini /* FETIDP preconditioner */ 11273425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 11283425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 11293425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 11303425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 11313425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 11323425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 11333425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 11343425bc38SStefano Zampini ierr = PCSetOperators(newpc,newmat,newmat,SAME_PRECONDITIONER);CHKERRQ(ierr); 11353425bc38SStefano Zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 11363425bc38SStefano Zampini /* return pointers for objects created */ 11373425bc38SStefano Zampini *fetidp_mat=newmat; 11383425bc38SStefano Zampini *fetidp_pc=newpc; 11393425bc38SStefano Zampini PetscFunctionReturn(0); 11403425bc38SStefano Zampini } 11411e6b0712SBarry Smith 11423425bc38SStefano Zampini #undef __FUNCT__ 11433425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators" 11443425bc38SStefano Zampini /*@ 11453425bc38SStefano Zampini PCBDDCCreateFETIDPOperators - Create operators for FETIDP. 11463425bc38SStefano Zampini 11473425bc38SStefano Zampini Collective 11483425bc38SStefano Zampini 11493425bc38SStefano Zampini Input Parameters: 11503425bc38SStefano Zampini + pc - the BDDC preconditioning context (setup must be already called) 11513425bc38SStefano Zampini 11523425bc38SStefano Zampini Level: developer 11533425bc38SStefano Zampini 11543425bc38SStefano Zampini Notes: 11553425bc38SStefano Zampini 11563425bc38SStefano Zampini .seealso: PCBDDC 11573425bc38SStefano Zampini @*/ 11583425bc38SStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 11593425bc38SStefano Zampini { 11603425bc38SStefano Zampini PetscErrorCode ierr; 11613425bc38SStefano Zampini 11623425bc38SStefano Zampini PetscFunctionBegin; 11633425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 11643425bc38SStefano Zampini if (pc->setupcalled) { 11653425bc38SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,Mat*,PC*),(pc,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 1166f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n"); 11673425bc38SStefano Zampini PetscFunctionReturn(0); 11683425bc38SStefano Zampini } 11690c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1170da1bb401SStefano Zampini /*MC 1171da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 11720c7d97c5SJed Brown 1173da1bb401SStefano Zampini Options Database Keys: 1174da1bb401SStefano Zampini . -pcbddc ??? - 1175da1bb401SStefano Zampini 1176da1bb401SStefano Zampini Level: intermediate 1177da1bb401SStefano Zampini 1178da1bb401SStefano Zampini Notes: The matrix used with this preconditioner must be of type MATIS 1179da1bb401SStefano Zampini 1180da1bb401SStefano Zampini Unlike more 'conventional' interface preconditioners, this iterates over ALL the 1181da1bb401SStefano Zampini degrees of freedom, NOT just those on the interface (this allows the use of approximate solvers 1182da1bb401SStefano Zampini on the subdomains). 1183da1bb401SStefano Zampini 1184da1bb401SStefano Zampini Options for the coarse grid preconditioner can be set with - 1185da1bb401SStefano Zampini Options for the Dirichlet subproblem can be set with - 1186da1bb401SStefano Zampini Options for the Neumann subproblem can be set with - 1187da1bb401SStefano Zampini 1188da1bb401SStefano Zampini Contributed by Stefano Zampini 1189da1bb401SStefano Zampini 1190da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 1191da1bb401SStefano Zampini M*/ 1192b2573a8aSBarry Smith 1193da1bb401SStefano Zampini #undef __FUNCT__ 1194da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC" 11958cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 1196da1bb401SStefano Zampini { 1197da1bb401SStefano Zampini PetscErrorCode ierr; 1198da1bb401SStefano Zampini PC_BDDC *pcbddc; 1199da1bb401SStefano Zampini 1200da1bb401SStefano Zampini PetscFunctionBegin; 1201da1bb401SStefano Zampini /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 1202da1bb401SStefano Zampini ierr = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr); 1203da1bb401SStefano Zampini pc->data = (void*)pcbddc; 1204da1bb401SStefano Zampini 1205da1bb401SStefano Zampini /* create PCIS data structure */ 1206da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 1207da1bb401SStefano Zampini 1208da1bb401SStefano Zampini /* BDDC specific */ 1209674ae819SStefano Zampini pcbddc->user_primal_vertices = 0; 12100bdf917eSStefano Zampini pcbddc->NullSpace = 0; 12113972b0daSStefano Zampini pcbddc->temp_solution = 0; 1212534831adSStefano Zampini pcbddc->original_rhs = 0; 1213534831adSStefano Zampini pcbddc->local_mat = 0; 1214534831adSStefano Zampini pcbddc->ChangeOfBasisMatrix = 0; 1215674ae819SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 1216674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 1217da1bb401SStefano Zampini pcbddc->coarse_vec = 0; 1218da1bb401SStefano Zampini pcbddc->coarse_rhs = 0; 1219da1bb401SStefano Zampini pcbddc->coarse_ksp = 0; 1220da1bb401SStefano Zampini pcbddc->coarse_phi_B = 0; 1221da1bb401SStefano Zampini pcbddc->coarse_phi_D = 0; 122215aaf578SStefano Zampini pcbddc->coarse_psi_B = 0; 122315aaf578SStefano Zampini pcbddc->coarse_psi_D = 0; 1224da1bb401SStefano Zampini pcbddc->vec1_P = 0; 1225da1bb401SStefano Zampini pcbddc->vec1_R = 0; 1226da1bb401SStefano Zampini pcbddc->vec2_R = 0; 1227da1bb401SStefano Zampini pcbddc->local_auxmat1 = 0; 1228da1bb401SStefano Zampini pcbddc->local_auxmat2 = 0; 1229da1bb401SStefano Zampini pcbddc->R_to_B = 0; 1230da1bb401SStefano Zampini pcbddc->R_to_D = 0; 1231da1bb401SStefano Zampini pcbddc->ksp_D = 0; 1232da1bb401SStefano Zampini pcbddc->ksp_R = 0; 1233da1bb401SStefano Zampini pcbddc->local_primal_indices = 0; 123429622bf0SStefano Zampini pcbddc->inexact_prec_type = PETSC_FALSE; 1235da1bb401SStefano Zampini pcbddc->NeumannBoundaries = 0; 1236da1bb401SStefano Zampini pcbddc->ISForDofs = 0; 1237da1bb401SStefano Zampini pcbddc->ConstraintMatrix = 0; 1238da1bb401SStefano Zampini pcbddc->use_nnsp_true = PETSC_FALSE; 1239da1bb401SStefano Zampini pcbddc->local_primal_sizes = 0; 1240da1bb401SStefano Zampini pcbddc->local_primal_displacements = 0; 1241da1bb401SStefano Zampini pcbddc->coarse_loc_to_glob = 0; 12429d9e44b6SStefano Zampini pcbddc->dbg_flag = 0; 1243da1bb401SStefano Zampini pcbddc->coarsening_ratio = 8; 1244b76ba322SStefano Zampini pcbddc->use_exact_dirichlet = PETSC_TRUE; 12454fad6a16SStefano Zampini pcbddc->current_level = 0; 12464fad6a16SStefano Zampini pcbddc->max_levels = 1; 1247674ae819SStefano Zampini pcbddc->replicated_local_primal_indices = 0; 1248674ae819SStefano Zampini pcbddc->replicated_local_primal_values = 0; 1249da1bb401SStefano Zampini 1250674ae819SStefano Zampini /* create local graph structure */ 1251674ae819SStefano Zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 1252674ae819SStefano Zampini 1253674ae819SStefano Zampini /* scaling */ 1254674ae819SStefano Zampini pcbddc->use_deluxe_scaling = PETSC_FALSE; 1255674ae819SStefano Zampini pcbddc->work_scaling = 0; 1256da1bb401SStefano Zampini 1257da1bb401SStefano Zampini /* function pointers */ 1258da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 1259da1bb401SStefano Zampini pc->ops->applytranspose = 0; 1260da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 1261da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 1262da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 1263da1bb401SStefano Zampini pc->ops->view = 0; 1264da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 1265da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 1266da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 1267534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 1268534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 1269da1bb401SStefano Zampini 1270da1bb401SStefano Zampini /* composing function */ 1271674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 1272bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 1273bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetMaxLevels_C",PCBDDCSetMaxLevels_BDDC);CHKERRQ(ierr); 1274bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",PCBDDCSetNullSpace_BDDC);CHKERRQ(ierr); 1275bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 1276bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 1277bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 1278bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 1279bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseProblemType_C",PCBDDCSetCoarseProblemType_BDDC);CHKERRQ(ierr); 1280bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 1281bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 1282bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 1283bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 1284bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 1285da1bb401SStefano Zampini PetscFunctionReturn(0); 1286da1bb401SStefano Zampini } 12873425bc38SStefano Zampini 1288da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 1289da1bb401SStefano Zampini /* All static functions from now on */ 1290da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 129129622bf0SStefano Zampini 129229622bf0SStefano Zampini #undef __FUNCT__ 12934fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel" 12944fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 12954fad6a16SStefano Zampini { 12964fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 12974fad6a16SStefano Zampini 12984fad6a16SStefano Zampini PetscFunctionBegin; 12994fad6a16SStefano Zampini pcbddc->current_level=level; 13004fad6a16SStefano Zampini PetscFunctionReturn(0); 13014fad6a16SStefano Zampini } 13023425bc38SStefano Zampini 13033b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 13040c7d97c5SJed Brown #undef __FUNCT__ 13050c7d97c5SJed Brown #define __FUNCT__ "PCBDDCCoarseSetUp" 130653cdbc3dSStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC pc) 13070c7d97c5SJed Brown { 13080c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1309dcedc2aeSStefano Zampini PetscErrorCode ierr; 1310dcedc2aeSStefano Zampini 1311dcedc2aeSStefano Zampini PetscFunctionBegin; 1312dcedc2aeSStefano Zampini /* compute matrix after change of basis and extract local submatrices */ 1313dcedc2aeSStefano Zampini ierr = PCBDDCSetUpLocalMatrices(pc);CHKERRQ(ierr); 1314dcedc2aeSStefano Zampini 1315dcedc2aeSStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 1316dcedc2aeSStefano Zampini if (pcbddc->NullSpace && pcbddc->use_change_of_basis) { 1317dcedc2aeSStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 1318dcedc2aeSStefano Zampini } 1319dcedc2aeSStefano Zampini 1320dcedc2aeSStefano Zampini /* Allocate needed vectors */ 1321dcedc2aeSStefano Zampini ierr = PCBDDCCreateWorkVectors(pc);CHKERRQ(ierr); 1322dcedc2aeSStefano Zampini 1323dcedc2aeSStefano Zampini /* setup local scatters R_to_B and (optionally) R_to_D : PCBDDCCreateWorkVectors should be called first! */ 1324*8ce42a96SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 1325dcedc2aeSStefano Zampini 1326dcedc2aeSStefano Zampini /* setup local solvers ksp_D and ksp_R */ 1327*8ce42a96SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc);CHKERRQ(ierr); 1328dcedc2aeSStefano Zampini 132988ebb749SStefano Zampini /* setup local correction and local part of coarse basis */ 1330*8ce42a96SStefano Zampini ierr = PCBDDCSetUpCoarseLocal(pc);CHKERRQ(ierr); 1331674ae819SStefano Zampini 13320c7d97c5SJed Brown PetscFunctionReturn(0); 13330c7d97c5SJed Brown } 13340c7d97c5SJed Brown 13350c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 13360c7d97c5SJed Brown 13377cbb387bSStefano Zampini /* BDDC requires metis 5.0.1 for multilevel */ 13387cbb387bSStefano Zampini #if defined(PETSC_HAVE_METIS) 13397cbb387bSStefano Zampini #include "metis.h" 13407cbb387bSStefano Zampini #define MetisInt idx_t 13417cbb387bSStefano Zampini #define MetisScalar real_t 13427cbb387bSStefano Zampini #endif 13437cbb387bSStefano Zampini 13440c7d97c5SJed Brown #undef __FUNCT__ 1345674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseEnvironment" 134688ebb749SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseEnvironment(PC pc,PetscScalar* coarse_submat_vals) 13470c7d97c5SJed Brown { 1348674ae819SStefano Zampini 1349674ae819SStefano Zampini 13500c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 13510c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 13520c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 1353ce94432eSBarry Smith MPI_Comm prec_comm; 13540c7d97c5SJed Brown MPI_Comm coarse_comm; 13550c7d97c5SJed Brown 1356674ae819SStefano Zampini MatNullSpace CoarseNullSpace; 1357674ae819SStefano Zampini 13580c7d97c5SJed Brown /* common to all choiches */ 13590c7d97c5SJed Brown PetscScalar *temp_coarse_mat_vals; 13600c7d97c5SJed Brown PetscScalar *ins_coarse_mat_vals; 13610c7d97c5SJed Brown PetscInt *ins_local_primal_indices; 13620c7d97c5SJed Brown PetscMPIInt *localsizes2,*localdispl2; 13630c7d97c5SJed Brown PetscMPIInt size_prec_comm; 13640c7d97c5SJed Brown PetscMPIInt rank_prec_comm; 13650c7d97c5SJed Brown PetscMPIInt active_rank=MPI_PROC_NULL; 13660c7d97c5SJed Brown PetscMPIInt master_proc=0; 13670c7d97c5SJed Brown PetscInt ins_local_primal_size; 13680c7d97c5SJed Brown /* specific to MULTILEVEL_BDDC */ 13695b08dc53SStefano Zampini PetscMPIInt *ranks_recv=0; 13700c7d97c5SJed Brown PetscMPIInt count_recv=0; 13715b08dc53SStefano Zampini PetscMPIInt rank_coarse_proc_send_to=-1; 13720c7d97c5SJed Brown PetscMPIInt coarse_color = MPI_UNDEFINED; 13730c7d97c5SJed Brown ISLocalToGlobalMapping coarse_ISLG; 13740c7d97c5SJed Brown /* some other variables */ 13750c7d97c5SJed Brown PetscErrorCode ierr; 137619fd82e9SBarry Smith MatType coarse_mat_type; 137719fd82e9SBarry Smith PCType coarse_pc_type; 137819fd82e9SBarry Smith KSPType coarse_ksp_type; 137953cdbc3dSStefano Zampini PC pc_temp; 13804fad6a16SStefano Zampini PetscInt i,j,k; 13813b03a366Sstefano_zampini PetscInt max_it_coarse_ksp=1; /* don't increase this value */ 1382e269702eSStefano Zampini /* verbose output viewer */ 1383e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 13845b08dc53SStefano Zampini PetscInt dbg_flag=pcbddc->dbg_flag; 1385142dfd88SStefano Zampini 1386ea7e1babSStefano Zampini PetscInt offset,offset2; 1387a929c220SStefano Zampini PetscMPIInt im_active,active_procs; 1388523858cfSStefano Zampini PetscInt *dnz,*onz; 1389142dfd88SStefano Zampini 1390142dfd88SStefano Zampini PetscBool setsym,issym=PETSC_FALSE; 13910c7d97c5SJed Brown 13920c7d97c5SJed Brown PetscFunctionBegin; 13934b2d0b89SJed Brown ierr = PetscObjectGetComm((PetscObject)pc,&prec_comm);CHKERRQ(ierr); 13940c7d97c5SJed Brown ins_local_primal_indices = 0; 13950c7d97c5SJed Brown ins_coarse_mat_vals = 0; 13960c7d97c5SJed Brown localsizes2 = 0; 13970c7d97c5SJed Brown localdispl2 = 0; 13980c7d97c5SJed Brown temp_coarse_mat_vals = 0; 13990c7d97c5SJed Brown coarse_ISLG = 0; 14000c7d97c5SJed Brown 140153cdbc3dSStefano Zampini ierr = MPI_Comm_size(prec_comm,&size_prec_comm);CHKERRQ(ierr); 140253cdbc3dSStefano Zampini ierr = MPI_Comm_rank(prec_comm,&rank_prec_comm);CHKERRQ(ierr); 1403142dfd88SStefano Zampini ierr = MatIsSymmetricKnown(pc->pmat,&setsym,&issym);CHKERRQ(ierr); 1404142dfd88SStefano Zampini 1405beed3852SStefano Zampini /* Assign global numbering to coarse dofs */ 1406beed3852SStefano Zampini { 1407674ae819SStefano Zampini PetscInt *auxlocal_primal,*aux_idx; 1408ef028eecSStefano Zampini PetscMPIInt mpi_local_primal_size; 1409ef028eecSStefano Zampini PetscScalar coarsesum,*array; 1410ef028eecSStefano Zampini 1411ef028eecSStefano Zampini mpi_local_primal_size = (PetscMPIInt)pcbddc->local_primal_size; 1412beed3852SStefano Zampini 1413beed3852SStefano Zampini /* Construct needed data structures for message passing */ 1414ffe5efe1SStefano Zampini j = 0; 1415142dfd88SStefano Zampini if (rank_prec_comm == 0 || pcbddc->coarse_problem_type == REPLICATED_BDDC || pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 1416ffe5efe1SStefano Zampini j = size_prec_comm; 1417ffe5efe1SStefano Zampini } 1418ffe5efe1SStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->local_primal_sizes);CHKERRQ(ierr); 1419ffe5efe1SStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 1420beed3852SStefano Zampini /* Gather local_primal_size information for all processes */ 1421142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == REPLICATED_BDDC || pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 14225619798eSStefano Zampini ierr = MPI_Allgather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,prec_comm);CHKERRQ(ierr); 1423ffe5efe1SStefano Zampini } else { 1424ffe5efe1SStefano Zampini ierr = MPI_Gather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 1425ffe5efe1SStefano Zampini } 1426beed3852SStefano Zampini pcbddc->replicated_primal_size = 0; 1427ffe5efe1SStefano Zampini for (i=0; i<j; i++) { 1428beed3852SStefano Zampini pcbddc->local_primal_displacements[i] = pcbddc->replicated_primal_size ; 1429beed3852SStefano Zampini pcbddc->replicated_primal_size += pcbddc->local_primal_sizes[i]; 1430beed3852SStefano Zampini } 1431beed3852SStefano Zampini 1432da1bb401SStefano Zampini /* First let's count coarse dofs. 1433beed3852SStefano Zampini This code fragment assumes that the number of local constraints per connected component 1434beed3852SStefano Zampini is not greater than the number of nodes defined for the connected component 1435beed3852SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 1436ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscInt),&auxlocal_primal);CHKERRQ(ierr); 1437674ae819SStefano Zampini ierr = PCBDDCGetPrimalVerticesLocalIdx(pc,&i,&aux_idx);CHKERRQ(ierr); 1438674ae819SStefano Zampini ierr = PetscMemcpy(auxlocal_primal,aux_idx,i*sizeof(PetscInt));CHKERRQ(ierr); 1439674ae819SStefano Zampini ierr = PetscFree(aux_idx);CHKERRQ(ierr); 1440674ae819SStefano Zampini ierr = PCBDDCGetPrimalConstraintsLocalIdx(pc,&j,&aux_idx);CHKERRQ(ierr); 1441674ae819SStefano Zampini ierr = PetscMemcpy(&auxlocal_primal[i],aux_idx,j*sizeof(PetscInt));CHKERRQ(ierr); 1442674ae819SStefano Zampini ierr = PetscFree(aux_idx);CHKERRQ(ierr); 1443ef028eecSStefano Zampini /* Compute number of coarse dofs */ 1444674ae819SStefano Zampini ierr = PCBDDCSubsetNumbering(prec_comm,matis->mapping,pcbddc->local_primal_size,auxlocal_primal,NULL,&pcbddc->coarse_size,&pcbddc->local_primal_indices);CHKERRQ(ierr); 1445ef028eecSStefano Zampini 1446ef028eecSStefano Zampini if (dbg_flag) { 14472e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14482e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 14492e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Check coarse indices\n");CHKERRQ(ierr); 14502e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 14512e8d2280SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14522fa5cd67SKarl Rupp for (i=0;i<pcbddc->local_primal_size;i++) array[auxlocal_primal[i]]=1.0; 1453beed3852SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14542e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 1455da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1456da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1457da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1458da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1459da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14602e8d2280SStefano Zampini for (i=0;i<pcis->n;i++) { 14612e8d2280SStefano Zampini if (array[i] == 1.0) { 14622e8d2280SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,1,&i,&j);CHKERRQ(ierr); 14632e8d2280SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d: WRONG COARSE INDEX %d (local %d)\n",PetscGlobalRank,j,i);CHKERRQ(ierr); 14642e8d2280SStefano Zampini } 14652e8d2280SStefano Zampini } 14662e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14672e8d2280SStefano Zampini for (i=0;i<pcis->n;i++) { 14685b08dc53SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 14692e8d2280SStefano Zampini } 1470da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14712e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 1472da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1473da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1474da1bb401SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 14752e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem SHOULD be %lf\n",coarsesum);CHKERRQ(ierr); 14762e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14772e8d2280SStefano Zampini } 1478142dfd88SStefano Zampini ierr = PetscFree(auxlocal_primal);CHKERRQ(ierr); 14790bdf917eSStefano Zampini } 14800bdf917eSStefano Zampini 14812e8d2280SStefano Zampini if (dbg_flag) { 14827cf533a6SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem is %d\n",pcbddc->coarse_size);CHKERRQ(ierr); 14839d9e44b6SStefano Zampini if (dbg_flag > 1) { 1484674ae819SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 14852e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1486674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 1487674ae819SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 1488674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_primal_indices[%d]=%d \n",i,pcbddc->local_primal_indices[i]); 1489674ae819SStefano Zampini } 14902e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14912e8d2280SStefano Zampini } 14922e8d2280SStefano Zampini } 14932e8d2280SStefano Zampini 1494a929c220SStefano Zampini im_active = 0; 14952fa5cd67SKarl Rupp if (pcis->n) im_active = 1; 1496a929c220SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,prec_comm);CHKERRQ(ierr); 14970bdf917eSStefano Zampini 14980bdf917eSStefano Zampini /* adapt coarse problem type */ 14997cbb387bSStefano Zampini #if defined(PETSC_HAVE_METIS) 15004fad6a16SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 15014fad6a16SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 1502a929c220SStefano Zampini if ( (active_procs/pcbddc->coarsening_ratio) < 2 ) { 15030bdf917eSStefano Zampini if (dbg_flag) { 1504a929c220SStefano 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); 15050bdf917eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 15060bdf917eSStefano Zampini } 15070bdf917eSStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 1508142dfd88SStefano Zampini } 15094fad6a16SStefano Zampini } else { 15104fad6a16SStefano Zampini if (dbg_flag) { 1511a929c220SStefano 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); 15124fad6a16SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 15134fad6a16SStefano Zampini } 15144fad6a16SStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 15154fad6a16SStefano Zampini } 15164fad6a16SStefano Zampini } 15177cbb387bSStefano Zampini #else 15187cbb387bSStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 15197cbb387bSStefano Zampini #endif 1520beed3852SStefano Zampini 15210c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 15220c7d97c5SJed Brown 1523da1bb401SStefano Zampini case(MULTILEVEL_BDDC): /* we define a coarse mesh where subdomains are elements */ 15240c7d97c5SJed Brown { 15257cbb387bSStefano Zampini #if defined(PETSC_HAVE_METIS) 15260c7d97c5SJed Brown /* we need additional variables */ 15270c7d97c5SJed Brown MetisInt n_subdomains,n_parts,objval,ncon,faces_nvtxs; 15280c7d97c5SJed Brown MetisInt *metis_coarse_subdivision; 15290c7d97c5SJed Brown MetisInt options[METIS_NOPTIONS]; 15300c7d97c5SJed Brown PetscMPIInt size_coarse_comm,rank_coarse_comm; 15310c7d97c5SJed Brown PetscMPIInt procs_jumps_coarse_comm; 15320c7d97c5SJed Brown PetscMPIInt *coarse_subdivision; 15330c7d97c5SJed Brown PetscMPIInt *total_count_recv; 15340c7d97c5SJed Brown PetscMPIInt *total_ranks_recv; 15350c7d97c5SJed Brown PetscMPIInt *displacements_recv; 15360c7d97c5SJed Brown PetscMPIInt *my_faces_connectivity; 15370c7d97c5SJed Brown PetscMPIInt *petsc_faces_adjncy; 15380c7d97c5SJed Brown MetisInt *faces_adjncy; 15390c7d97c5SJed Brown MetisInt *faces_xadj; 15400c7d97c5SJed Brown PetscMPIInt *number_of_faces; 15410c7d97c5SJed Brown PetscMPIInt *faces_displacements; 15420c7d97c5SJed Brown PetscInt *array_int; 15430c7d97c5SJed Brown PetscMPIInt my_faces=0; 15440c7d97c5SJed Brown PetscMPIInt total_faces=0; 15453828260eSStefano Zampini PetscInt ranks_stretching_ratio; 15460c7d97c5SJed Brown 15470c7d97c5SJed Brown /* define some quantities */ 15480c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 15490c7d97c5SJed Brown coarse_mat_type = MATIS; 15500c7d97c5SJed Brown coarse_pc_type = PCBDDC; 1551142dfd88SStefano Zampini coarse_ksp_type = KSPRICHARDSON; 15520c7d97c5SJed Brown 15530c7d97c5SJed Brown /* details of coarse decomposition */ 1554a929c220SStefano Zampini n_subdomains = active_procs; 15550c7d97c5SJed Brown n_parts = n_subdomains/pcbddc->coarsening_ratio; 1556a929c220SStefano Zampini ranks_stretching_ratio = size_prec_comm/active_procs; 15573828260eSStefano Zampini procs_jumps_coarse_comm = pcbddc->coarsening_ratio*ranks_stretching_ratio; 15583828260eSStefano Zampini 1559a929c220SStefano Zampini #if 0 1560a929c220SStefano Zampini PetscMPIInt *old_ranks; 1561a929c220SStefano Zampini PetscInt *new_ranks,*jj,*ii; 1562a929c220SStefano Zampini MatPartitioning mat_part; 1563a929c220SStefano Zampini IS coarse_new_decomposition,is_numbering; 1564a929c220SStefano Zampini PetscViewer viewer_test; 1565a929c220SStefano Zampini MPI_Comm test_coarse_comm; 1566a929c220SStefano Zampini PetscMPIInt test_coarse_color; 1567a929c220SStefano Zampini Mat mat_adj; 1568a929c220SStefano Zampini /* Create new communicator for coarse problem splitting the old one */ 1569a929c220SStefano Zampini /* procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 1570a929c220SStefano Zampini key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator */ 1571a929c220SStefano Zampini test_coarse_color = ( im_active ? 0 : MPI_UNDEFINED ); 1572a929c220SStefano Zampini test_coarse_comm = MPI_COMM_NULL; 1573a929c220SStefano Zampini ierr = MPI_Comm_split(prec_comm,test_coarse_color,rank_prec_comm,&test_coarse_comm);CHKERRQ(ierr); 1574a929c220SStefano Zampini if (im_active) { 1575a929c220SStefano Zampini ierr = PetscMalloc(n_subdomains*sizeof(PetscMPIInt),&old_ranks); 1576a929c220SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscInt),&new_ranks); 1577a929c220SStefano Zampini ierr = MPI_Comm_rank(test_coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 1578a929c220SStefano Zampini ierr = MPI_Comm_size(test_coarse_comm,&j);CHKERRQ(ierr); 1579a929c220SStefano Zampini ierr = MPI_Allgather(&rank_prec_comm,1,MPIU_INT,old_ranks,1,MPIU_INT,test_coarse_comm);CHKERRQ(ierr); 1580674ae819SStefano Zampini for (i=0; i<size_prec_comm; i++) new_ranks[i] = -1; 1581674ae819SStefano Zampini for (i=0; i<n_subdomains; i++) new_ranks[old_ranks[i]] = i; 1582a929c220SStefano Zampini ierr = PetscViewerASCIIOpen(test_coarse_comm,"test_mat_part.out",&viewer_test);CHKERRQ(ierr); 1583a929c220SStefano Zampini k = pcis->n_neigh-1; 1584a929c220SStefano Zampini ierr = PetscMalloc(2*sizeof(PetscInt),&ii); 1585a929c220SStefano Zampini ii[0]=0; 1586a929c220SStefano Zampini ii[1]=k; 1587a929c220SStefano Zampini ierr = PetscMalloc(k*sizeof(PetscInt),&jj); 1588674ae819SStefano Zampini for (i=0; i<k; i++) jj[i]=new_ranks[pcis->neigh[i+1]]; 1589a929c220SStefano Zampini ierr = PetscSortInt(k,jj);CHKERRQ(ierr); 15900298fd71SBarry Smith ierr = MatCreateMPIAdj(test_coarse_comm,1,n_subdomains,ii,jj,NULL,&mat_adj);CHKERRQ(ierr); 1591a929c220SStefano Zampini ierr = MatView(mat_adj,viewer_test);CHKERRQ(ierr); 1592a929c220SStefano Zampini ierr = MatPartitioningCreate(test_coarse_comm,&mat_part);CHKERRQ(ierr); 1593a929c220SStefano Zampini ierr = MatPartitioningSetAdjacency(mat_part,mat_adj);CHKERRQ(ierr); 1594a929c220SStefano Zampini ierr = MatPartitioningSetFromOptions(mat_part);CHKERRQ(ierr); 1595a929c220SStefano Zampini printf("Setting Nparts %d\n",n_parts); 1596a929c220SStefano Zampini ierr = MatPartitioningSetNParts(mat_part,n_parts);CHKERRQ(ierr); 1597a929c220SStefano Zampini ierr = MatPartitioningView(mat_part,viewer_test);CHKERRQ(ierr); 1598a929c220SStefano Zampini ierr = MatPartitioningApply(mat_part,&coarse_new_decomposition);CHKERRQ(ierr); 1599a929c220SStefano Zampini ierr = ISView(coarse_new_decomposition,viewer_test);CHKERRQ(ierr); 1600a929c220SStefano Zampini ierr = ISPartitioningToNumbering(coarse_new_decomposition,&is_numbering);CHKERRQ(ierr); 1601a929c220SStefano Zampini ierr = ISView(is_numbering,viewer_test);CHKERRQ(ierr); 1602a929c220SStefano Zampini ierr = PetscViewerDestroy(&viewer_test);CHKERRQ(ierr); 1603a929c220SStefano Zampini ierr = ISDestroy(&coarse_new_decomposition);CHKERRQ(ierr); 1604a929c220SStefano Zampini ierr = ISDestroy(&is_numbering);CHKERRQ(ierr); 1605a929c220SStefano Zampini ierr = MatPartitioningDestroy(&mat_part);CHKERRQ(ierr); 1606a929c220SStefano Zampini ierr = PetscFree(old_ranks);CHKERRQ(ierr); 1607a929c220SStefano Zampini ierr = PetscFree(new_ranks);CHKERRQ(ierr); 1608a929c220SStefano Zampini ierr = MPI_Comm_free(&test_coarse_comm);CHKERRQ(ierr); 1609a929c220SStefano Zampini } 1610a929c220SStefano Zampini #endif 1611a929c220SStefano Zampini 16124fad6a16SStefano Zampini /* build CSR graph of subdomains' connectivity */ 16130c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&array_int);CHKERRQ(ierr); 16143828260eSStefano Zampini ierr = PetscMemzero(array_int,pcis->n*sizeof(PetscInt));CHKERRQ(ierr); 16150c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++){/* i=1 so I don't count myself -> faces nodes counts to 1 */ 16160c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++){ 16170c7d97c5SJed Brown array_int[ pcis->shared[i][j] ]+=1; 16180c7d97c5SJed Brown } 16190c7d97c5SJed Brown } 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++; 16240c7d97c5SJed Brown break; 16250c7d97c5SJed Brown } 16260c7d97c5SJed Brown } 16270c7d97c5SJed Brown } 16280c7d97c5SJed Brown 162953cdbc3dSStefano Zampini ierr = MPI_Reduce(&my_faces,&total_faces,1,MPIU_INT,MPI_SUM,master_proc,prec_comm);CHKERRQ(ierr); 16300c7d97c5SJed Brown ierr = PetscMalloc (my_faces*sizeof(PetscInt),&my_faces_connectivity);CHKERRQ(ierr); 16310c7d97c5SJed Brown my_faces=0; 16320c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++){ 16330c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++){ 16347cf533a6SStefano Zampini if (array_int[ pcis->shared[i][j] ] > 0 ){ 16350c7d97c5SJed Brown my_faces_connectivity[my_faces]=pcis->neigh[i]; 16360c7d97c5SJed Brown my_faces++; 16370c7d97c5SJed Brown break; 16380c7d97c5SJed Brown } 16390c7d97c5SJed Brown } 16400c7d97c5SJed Brown } 16410c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 16420c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(PetscMPIInt),&petsc_faces_adjncy);CHKERRQ(ierr); 16430c7d97c5SJed Brown ierr = PetscMalloc (size_prec_comm*sizeof(PetscMPIInt),&number_of_faces);CHKERRQ(ierr); 16440c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(MetisInt),&faces_adjncy);CHKERRQ(ierr); 16450c7d97c5SJed Brown ierr = PetscMalloc ((n_subdomains+1)*sizeof(MetisInt),&faces_xadj);CHKERRQ(ierr); 16460c7d97c5SJed Brown ierr = PetscMalloc ((size_prec_comm+1)*sizeof(PetscMPIInt),&faces_displacements);CHKERRQ(ierr); 16470c7d97c5SJed Brown } 164853cdbc3dSStefano Zampini ierr = MPI_Gather(&my_faces,1,MPIU_INT,&number_of_faces[0],1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 16490c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 16500c7d97c5SJed Brown faces_xadj[0]=0; 16510c7d97c5SJed Brown faces_displacements[0]=0; 16520c7d97c5SJed Brown j=0; 16530c7d97c5SJed Brown for (i=1;i<size_prec_comm+1;i++) { 16540c7d97c5SJed Brown faces_displacements[i]=faces_displacements[i-1]+number_of_faces[i-1]; 16550c7d97c5SJed Brown if (number_of_faces[i-1]) { 16560c7d97c5SJed Brown j++; 16570c7d97c5SJed Brown faces_xadj[j]=faces_xadj[j-1]+number_of_faces[i-1]; 16580c7d97c5SJed Brown } 16590c7d97c5SJed Brown } 16600c7d97c5SJed Brown } 166153cdbc3dSStefano 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); 16620c7d97c5SJed Brown ierr = PetscFree(my_faces_connectivity);CHKERRQ(ierr); 16630c7d97c5SJed Brown ierr = PetscFree(array_int);CHKERRQ(ierr); 16640c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 16653828260eSStefano Zampini for (i=0;i<total_faces;i++) faces_adjncy[i]=(MetisInt)(petsc_faces_adjncy[i]/ranks_stretching_ratio); /* cast to MetisInt */ 16660c7d97c5SJed Brown ierr = PetscFree(faces_displacements);CHKERRQ(ierr); 16670c7d97c5SJed Brown ierr = PetscFree(number_of_faces);CHKERRQ(ierr); 16680c7d97c5SJed Brown ierr = PetscFree(petsc_faces_adjncy);CHKERRQ(ierr); 16690c7d97c5SJed Brown } 16700c7d97c5SJed Brown 16710c7d97c5SJed Brown if ( rank_prec_comm == master_proc ) { 1672674ae819SStefano Zampini 16733828260eSStefano Zampini PetscInt heuristic_for_metis=3; 1674674ae819SStefano Zampini 16750c7d97c5SJed Brown ncon=1; 16760c7d97c5SJed Brown faces_nvtxs=n_subdomains; 16770c7d97c5SJed Brown /* partition graoh induced by face connectivity */ 16780c7d97c5SJed Brown ierr = PetscMalloc (n_subdomains*sizeof(MetisInt),&metis_coarse_subdivision);CHKERRQ(ierr); 16790c7d97c5SJed Brown ierr = METIS_SetDefaultOptions(options); 16800c7d97c5SJed Brown /* we need a contiguous partition of the coarse mesh */ 16810c7d97c5SJed Brown options[METIS_OPTION_CONTIG]=1; 16820c7d97c5SJed Brown options[METIS_OPTION_NITER]=30; 16834fad6a16SStefano Zampini if (pcbddc->coarsening_ratio > 1) { 16843828260eSStefano Zampini if (n_subdomains>n_parts*heuristic_for_metis) { 16853828260eSStefano Zampini options[METIS_OPTION_IPTYPE]=METIS_IPTYPE_EDGE; 16863828260eSStefano Zampini options[METIS_OPTION_OBJTYPE]=METIS_OBJTYPE_CUT; 16870c7d97c5SJed Brown ierr = METIS_PartGraphKway(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 1688674ae819SStefano 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); 16893828260eSStefano Zampini } else { 16903828260eSStefano Zampini ierr = METIS_PartGraphRecursive(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 1691674ae819SStefano 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); 16923828260eSStefano Zampini } 16934fad6a16SStefano Zampini } else { 16942fa5cd67SKarl Rupp for (i=0;i<n_subdomains;i++) metis_coarse_subdivision[i]=i; 16954fad6a16SStefano Zampini } 16960c7d97c5SJed Brown ierr = PetscFree(faces_xadj);CHKERRQ(ierr); 16970c7d97c5SJed Brown ierr = PetscFree(faces_adjncy);CHKERRQ(ierr); 16980bdf917eSStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&coarse_subdivision);CHKERRQ(ierr); 16992fa5cd67SKarl Rupp 17000c7d97c5SJed Brown /* copy/cast values avoiding possible type conflicts between PETSc, MPI and METIS */ 17012fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) coarse_subdivision[i]=MPI_PROC_NULL; 17022fa5cd67SKarl Rupp for (i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=(PetscInt)(metis_coarse_subdivision[i]); 17030c7d97c5SJed Brown ierr = PetscFree(metis_coarse_subdivision);CHKERRQ(ierr); 17040c7d97c5SJed Brown } 17050c7d97c5SJed Brown 17060c7d97c5SJed Brown /* Create new communicator for coarse problem splitting the old one */ 17070c7d97c5SJed Brown if ( !(rank_prec_comm%procs_jumps_coarse_comm) && rank_prec_comm < procs_jumps_coarse_comm*n_parts ){ 1708da1bb401SStefano Zampini coarse_color=0; /* for communicator splitting */ 1709da1bb401SStefano Zampini active_rank=rank_prec_comm; /* for insertion of matrix values */ 17100c7d97c5SJed Brown } 1711da1bb401SStefano Zampini /* procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 1712da1bb401SStefano Zampini key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator */ 171353cdbc3dSStefano Zampini ierr = MPI_Comm_split(prec_comm,coarse_color,rank_prec_comm,&coarse_comm);CHKERRQ(ierr); 17140c7d97c5SJed Brown 17150c7d97c5SJed Brown if ( coarse_color == 0 ) { 171653cdbc3dSStefano Zampini ierr = MPI_Comm_size(coarse_comm,&size_coarse_comm);CHKERRQ(ierr); 171753cdbc3dSStefano Zampini ierr = MPI_Comm_rank(coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 17180c7d97c5SJed Brown } else { 17190c7d97c5SJed Brown rank_coarse_comm = MPI_PROC_NULL; 17200c7d97c5SJed Brown } 17210c7d97c5SJed Brown 17227cf533a6SStefano Zampini /* master proc take care of arranging and distributing coarse information */ 17230c7d97c5SJed Brown if (rank_coarse_comm == master_proc) { 17240c7d97c5SJed Brown ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&displacements_recv);CHKERRQ(ierr); 17250bdf917eSStefano Zampini ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&total_count_recv);CHKERRQ(ierr); 17260bdf917eSStefano Zampini ierr = PetscMalloc (n_subdomains*sizeof(PetscMPIInt),&total_ranks_recv);CHKERRQ(ierr); 17270c7d97c5SJed Brown /* some initializations */ 17280c7d97c5SJed Brown displacements_recv[0]=0; 17290bdf917eSStefano Zampini ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 17300c7d97c5SJed Brown /* count from how many processes the j-th process of the coarse decomposition will receive data */ 17310bdf917eSStefano Zampini for (j=0;j<size_coarse_comm;j++) { 17320bdf917eSStefano Zampini for (i=0;i<size_prec_comm;i++) { 17332fa5cd67SKarl Rupp if (coarse_subdivision[i]==j) total_count_recv[j]++; 17340bdf917eSStefano Zampini } 17350bdf917eSStefano Zampini } 17360c7d97c5SJed Brown /* displacements needed for scatterv of total_ranks_recv */ 17372fa5cd67SKarl Rupp for (i=1; i<size_coarse_comm; i++) displacements_recv[i]=displacements_recv[i-1]+total_count_recv[i-1]; 17382fa5cd67SKarl Rupp 17390c7d97c5SJed Brown /* Now fill properly total_ranks_recv -> each coarse process will receive the ranks (in prec_comm communicator) of its friend (sending) processes */ 17400c7d97c5SJed Brown ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 17410c7d97c5SJed Brown for (j=0;j<size_coarse_comm;j++) { 17423828260eSStefano Zampini for (i=0;i<size_prec_comm;i++) { 17430c7d97c5SJed Brown if (coarse_subdivision[i]==j) { 17440c7d97c5SJed Brown total_ranks_recv[displacements_recv[j]+total_count_recv[j]]=i; 17453828260eSStefano Zampini total_count_recv[j]+=1; 17460c7d97c5SJed Brown } 17470c7d97c5SJed Brown } 17480c7d97c5SJed Brown } 1749da1bb401SStefano Zampini /*for (j=0;j<size_coarse_comm;j++) { 17503828260eSStefano Zampini printf("process %d in new rank will receive from %d processes (original ranks follows)\n",j,total_count_recv[j]); 17513828260eSStefano Zampini for (i=0;i<total_count_recv[j];i++) { 17523828260eSStefano Zampini printf("%d ",total_ranks_recv[displacements_recv[j]+i]); 17533828260eSStefano Zampini } 17543828260eSStefano Zampini printf("\n"); 1755da1bb401SStefano Zampini }*/ 17560c7d97c5SJed Brown 17570c7d97c5SJed Brown /* identify new decomposition in terms of ranks in the old communicator */ 17580bdf917eSStefano Zampini for (i=0;i<n_subdomains;i++) { 17590bdf917eSStefano Zampini coarse_subdivision[ranks_stretching_ratio*i]=coarse_subdivision[ranks_stretching_ratio*i]*procs_jumps_coarse_comm; 17600bdf917eSStefano Zampini } 1761da1bb401SStefano Zampini /*printf("coarse_subdivision in old end new ranks\n"); 1762674ae819SStefano Zampini for (i=0;i<size_prec_comm;i++) 17633828260eSStefano Zampini if (coarse_subdivision[i]!=MPI_PROC_NULL) { 17643828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]/procs_jumps_coarse_comm); 17653828260eSStefano Zampini } else { 17663828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]); 17673828260eSStefano Zampini } 1768da1bb401SStefano Zampini printf("\n");*/ 17690c7d97c5SJed Brown } 17700c7d97c5SJed Brown 17710c7d97c5SJed Brown /* Scatter new decomposition for send details */ 177253cdbc3dSStefano Zampini ierr = MPI_Scatter(&coarse_subdivision[0],1,MPIU_INT,&rank_coarse_proc_send_to,1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 17730c7d97c5SJed Brown /* Scatter receiving details to members of coarse decomposition */ 17740c7d97c5SJed Brown if ( coarse_color == 0) { 177553cdbc3dSStefano Zampini ierr = MPI_Scatter(&total_count_recv[0],1,MPIU_INT,&count_recv,1,MPIU_INT,master_proc,coarse_comm);CHKERRQ(ierr); 17760c7d97c5SJed Brown ierr = PetscMalloc (count_recv*sizeof(PetscMPIInt),&ranks_recv);CHKERRQ(ierr); 177753cdbc3dSStefano 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); 17780c7d97c5SJed Brown } 17790c7d97c5SJed Brown 1780da1bb401SStefano Zampini /*printf("I will send my matrix data to proc %d\n",rank_coarse_proc_send_to); 1781da1bb401SStefano Zampini if (coarse_color == 0) { 1782da1bb401SStefano Zampini printf("I will receive some matrix data from %d processes (ranks follows)\n",count_recv); 1783da1bb401SStefano Zampini for (i=0;i<count_recv;i++) 1784da1bb401SStefano Zampini printf("%d ",ranks_recv[i]); 1785da1bb401SStefano Zampini printf("\n"); 1786da1bb401SStefano Zampini }*/ 17870c7d97c5SJed Brown 17880c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 17890bdf917eSStefano Zampini ierr = PetscFree(coarse_subdivision);CHKERRQ(ierr); 1790da1bb401SStefano Zampini ierr = PetscFree(total_count_recv);CHKERRQ(ierr); 17910bdf917eSStefano Zampini ierr = PetscFree(total_ranks_recv);CHKERRQ(ierr); 17920c7d97c5SJed Brown ierr = PetscFree(displacements_recv);CHKERRQ(ierr); 17930c7d97c5SJed Brown } 17947cbb387bSStefano Zampini #endif 17950c7d97c5SJed Brown break; 17960c7d97c5SJed Brown } 17970c7d97c5SJed Brown 17980c7d97c5SJed Brown case(REPLICATED_BDDC): 17990c7d97c5SJed Brown 18000c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 18010c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 18020c7d97c5SJed Brown coarse_pc_type = PCLU; 180353cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 18040c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 18050c7d97c5SJed Brown active_rank = rank_prec_comm; 18060c7d97c5SJed Brown break; 18070c7d97c5SJed Brown 18080c7d97c5SJed Brown case(PARALLEL_BDDC): 18090c7d97c5SJed Brown 18100c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 1811674ae819SStefano Zampini coarse_mat_type = MATAIJ; 18120c7d97c5SJed Brown coarse_pc_type = PCREDUNDANT; 181353cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 18140c7d97c5SJed Brown coarse_comm = prec_comm; 18150c7d97c5SJed Brown active_rank = rank_prec_comm; 18160c7d97c5SJed Brown break; 18170c7d97c5SJed Brown 18180c7d97c5SJed Brown case(SEQUENTIAL_BDDC): 18190c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 1820674ae819SStefano Zampini coarse_mat_type = MATAIJ; 18210c7d97c5SJed Brown coarse_pc_type = PCLU; 182253cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 18230c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 18240c7d97c5SJed Brown active_rank = master_proc; 18250c7d97c5SJed Brown break; 18260c7d97c5SJed Brown } 18270c7d97c5SJed Brown 18280c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 18290c7d97c5SJed Brown 18300c7d97c5SJed Brown case(SCATTERS_BDDC): 18310c7d97c5SJed Brown { 18320c7d97c5SJed Brown if (pcbddc->coarse_problem_type==MULTILEVEL_BDDC) { 18330c7d97c5SJed Brown 18342e8d2280SStefano Zampini IS coarse_IS; 18352e8d2280SStefano Zampini 1836523858cfSStefano Zampini if(pcbddc->coarsening_ratio == 1) { 1837523858cfSStefano Zampini ins_local_primal_size = pcbddc->local_primal_size; 1838523858cfSStefano Zampini ins_local_primal_indices = pcbddc->local_primal_indices; 1839523858cfSStefano Zampini if (coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 1840523858cfSStefano Zampini /* nonzeros */ 1841523858cfSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&dnz);CHKERRQ(ierr); 1842523858cfSStefano Zampini ierr = PetscMemzero(dnz,ins_local_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 1843523858cfSStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 1844523858cfSStefano Zampini dnz[i] = ins_local_primal_size; 1845523858cfSStefano Zampini } 1846523858cfSStefano Zampini } else { 18470c7d97c5SJed Brown PetscMPIInt send_size; 1848ef028eecSStefano Zampini PetscMPIInt *send_buffer; 18490c7d97c5SJed Brown PetscInt *aux_ins_indices; 18500c7d97c5SJed Brown PetscInt ii,jj; 18510c7d97c5SJed Brown MPI_Request *requests; 1852ef028eecSStefano Zampini 1853523858cfSStefano Zampini ierr = PetscMalloc(count_recv*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 1854523858cfSStefano Zampini /* reusing pcbddc->local_primal_displacements and pcbddc->replicated_primal_size */ 1855523858cfSStefano Zampini ierr = PetscFree(pcbddc->local_primal_displacements);CHKERRQ(ierr); 1856523858cfSStefano Zampini ierr = PetscMalloc((count_recv+1)*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 1857523858cfSStefano Zampini pcbddc->replicated_primal_size = count_recv; 1858523858cfSStefano Zampini j = 0; 1859523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 1860523858cfSStefano Zampini pcbddc->local_primal_displacements[i] = j; 1861523858cfSStefano Zampini j += pcbddc->local_primal_sizes[ranks_recv[i]]; 1862523858cfSStefano Zampini } 1863523858cfSStefano Zampini pcbddc->local_primal_displacements[count_recv] = j; 1864523858cfSStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 18650c7d97c5SJed Brown /* allocate auxiliary space */ 1866523858cfSStefano Zampini ierr = PetscMalloc(count_recv*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 18670c7d97c5SJed Brown ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscInt),&aux_ins_indices);CHKERRQ(ierr); 18680c7d97c5SJed Brown ierr = PetscMemzero(aux_ins_indices,pcbddc->coarse_size*sizeof(PetscInt));CHKERRQ(ierr); 18690c7d97c5SJed Brown /* allocate stuffs for message massing */ 18700c7d97c5SJed Brown ierr = PetscMalloc((count_recv+1)*sizeof(MPI_Request),&requests);CHKERRQ(ierr); 1871523858cfSStefano Zampini for (i=0;i<count_recv+1;i++) { requests[i]=MPI_REQUEST_NULL; } 1872523858cfSStefano Zampini /* send indices to be inserted */ 1873523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 1874523858cfSStefano Zampini send_size = pcbddc->local_primal_sizes[ranks_recv[i]]; 1875523858cfSStefano 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); 1876523858cfSStefano Zampini } 1877523858cfSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 1878523858cfSStefano Zampini send_size = pcbddc->local_primal_size; 1879ef028eecSStefano Zampini ierr = PetscMalloc(send_size*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 1880ef028eecSStefano Zampini for (i=0;i<send_size;i++) { 1881ef028eecSStefano Zampini send_buffer[i]=(PetscMPIInt)pcbddc->local_primal_indices[i]; 1882ef028eecSStefano Zampini } 1883ef028eecSStefano Zampini ierr = MPI_Isend(send_buffer,send_size,MPIU_INT,rank_coarse_proc_send_to,999,prec_comm,&requests[count_recv]);CHKERRQ(ierr); 1884523858cfSStefano Zampini } 1885523858cfSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 1886ef028eecSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 1887ef028eecSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 1888ef028eecSStefano Zampini } 18890c7d97c5SJed Brown j = 0; 18900c7d97c5SJed Brown for (i=0;i<count_recv;i++) { 18912e8d2280SStefano Zampini ii = pcbddc->local_primal_displacements[i+1]-pcbddc->local_primal_displacements[i]; 18922e8d2280SStefano Zampini localsizes2[i] = ii*ii; 18930c7d97c5SJed Brown localdispl2[i] = j; 18940c7d97c5SJed Brown j += localsizes2[i]; 1895523858cfSStefano Zampini jj = pcbddc->local_primal_displacements[i]; 18964fad6a16SStefano Zampini /* it counts the coarse subdomains sharing the coarse node */ 18972e8d2280SStefano Zampini for (k=0;k<ii;k++) { 18984fad6a16SStefano Zampini aux_ins_indices[pcbddc->replicated_local_primal_indices[jj+k]] += 1; 18990c7d97c5SJed Brown } 19004fad6a16SStefano Zampini } 1901523858cfSStefano Zampini /* temp_coarse_mat_vals used to store matrix values to be received */ 19020c7d97c5SJed Brown ierr = PetscMalloc(j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 19030c7d97c5SJed Brown /* evaluate how many values I will insert in coarse mat */ 19040c7d97c5SJed Brown ins_local_primal_size = 0; 1905ea7e1babSStefano Zampini for (i=0;i<pcbddc->coarse_size;i++) { 1906ea7e1babSStefano Zampini if (aux_ins_indices[i]) { 19070c7d97c5SJed Brown ins_local_primal_size++; 1908ea7e1babSStefano Zampini } 1909ea7e1babSStefano Zampini } 19100c7d97c5SJed Brown /* evaluate indices I will insert in coarse mat */ 19110c7d97c5SJed Brown ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 19120c7d97c5SJed Brown j = 0; 1913ea7e1babSStefano Zampini for(i=0;i<pcbddc->coarse_size;i++) { 1914ea7e1babSStefano Zampini if(aux_ins_indices[i]) { 19152e8d2280SStefano Zampini ins_local_primal_indices[j] = i; 19162e8d2280SStefano Zampini j++; 1917ea7e1babSStefano Zampini } 1918ea7e1babSStefano Zampini } 1919523858cfSStefano Zampini /* processes partecipating in coarse problem receive matrix data from their friends */ 1920523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 1921523858cfSStefano Zampini ierr = MPI_Irecv(&temp_coarse_mat_vals[localdispl2[i]],localsizes2[i],MPIU_SCALAR,ranks_recv[i],666,prec_comm,&requests[i]);CHKERRQ(ierr); 1922523858cfSStefano Zampini } 1923523858cfSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 1924523858cfSStefano Zampini send_size = pcbddc->local_primal_size*pcbddc->local_primal_size; 1925523858cfSStefano 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); 1926523858cfSStefano Zampini } 1927523858cfSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 1928523858cfSStefano Zampini /* nonzeros */ 1929523858cfSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&dnz);CHKERRQ(ierr); 1930523858cfSStefano Zampini ierr = PetscMemzero(dnz,ins_local_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 19310c7d97c5SJed Brown /* use aux_ins_indices to realize a global to local mapping */ 19320c7d97c5SJed Brown j=0; 19330c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++){ 19340c7d97c5SJed Brown if(aux_ins_indices[i]==0){ 19350c7d97c5SJed Brown aux_ins_indices[i]=-1; 19360c7d97c5SJed Brown } else { 19370c7d97c5SJed Brown aux_ins_indices[i]=j; 19380c7d97c5SJed Brown j++; 19390c7d97c5SJed Brown } 19400c7d97c5SJed Brown } 19414fad6a16SStefano Zampini for (i=0;i<count_recv;i++) { 1942523858cfSStefano Zampini j = pcbddc->local_primal_sizes[ranks_recv[i]]; 1943523858cfSStefano Zampini for (k=0;k<j;k++) { 1944523858cfSStefano Zampini dnz[aux_ins_indices[pcbddc->replicated_local_primal_indices[pcbddc->local_primal_displacements[i]+k]]] += j; 19450c7d97c5SJed Brown } 19460c7d97c5SJed Brown } 1947523858cfSStefano Zampini /* check */ 1948523858cfSStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 1949523858cfSStefano Zampini if (dnz[i] > ins_local_primal_size) { 1950523858cfSStefano Zampini dnz[i] = ins_local_primal_size; 19510c7d97c5SJed Brown } 19520c7d97c5SJed Brown } 19530c7d97c5SJed Brown ierr = PetscFree(requests);CHKERRQ(ierr); 19540c7d97c5SJed Brown ierr = PetscFree(aux_ins_indices);CHKERRQ(ierr); 19550c7d97c5SJed Brown if (coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 19564fad6a16SStefano Zampini } 19570c7d97c5SJed Brown /* create local to global mapping needed by coarse MATIS */ 1958142dfd88SStefano Zampini if (coarse_comm != MPI_COMM_NULL ) {ierr = MPI_Comm_free(&coarse_comm);CHKERRQ(ierr);} 19590c7d97c5SJed Brown coarse_comm = prec_comm; 19600c7d97c5SJed Brown active_rank = rank_prec_comm; 19610c7d97c5SJed Brown ierr = ISCreateGeneral(coarse_comm,ins_local_primal_size,ins_local_primal_indices,PETSC_COPY_VALUES,&coarse_IS);CHKERRQ(ierr); 19620c7d97c5SJed Brown ierr = ISLocalToGlobalMappingCreateIS(coarse_IS,&coarse_ISLG);CHKERRQ(ierr); 19630c7d97c5SJed Brown ierr = ISDestroy(&coarse_IS);CHKERRQ(ierr); 19642e8d2280SStefano Zampini } else if (pcbddc->coarse_problem_type==PARALLEL_BDDC) { 19650c7d97c5SJed Brown /* arrays for values insertion */ 19660c7d97c5SJed Brown ins_local_primal_size = pcbddc->local_primal_size; 19672e8d2280SStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 19680c7d97c5SJed Brown ierr = PetscMalloc(ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 19690c7d97c5SJed Brown for (j=0;j<ins_local_primal_size;j++){ 19700c7d97c5SJed Brown ins_local_primal_indices[j]=pcbddc->local_primal_indices[j]; 19714fad6a16SStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 19724fad6a16SStefano Zampini ins_coarse_mat_vals[j*ins_local_primal_size+i]=coarse_submat_vals[j*ins_local_primal_size+i]; 19734fad6a16SStefano Zampini } 19740c7d97c5SJed Brown } 19750c7d97c5SJed Brown } 19760c7d97c5SJed Brown break; 1977674ae819SStefano Zampini 19780c7d97c5SJed Brown } 19790c7d97c5SJed Brown 19800c7d97c5SJed Brown case(GATHERS_BDDC): 19810c7d97c5SJed Brown { 1982674ae819SStefano Zampini 19830c7d97c5SJed Brown PetscMPIInt mysize,mysize2; 1984ef028eecSStefano Zampini PetscMPIInt *send_buffer; 19850c7d97c5SJed Brown 19860c7d97c5SJed Brown if (rank_prec_comm==active_rank) { 19870c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 19880bdf917eSStefano Zampini ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscScalar),&pcbddc->replicated_local_primal_values);CHKERRQ(ierr); 19890c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 19900c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 19910c7d97c5SJed Brown /* arrays for values insertion */ 19922fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) localsizes2[i]=pcbddc->local_primal_sizes[i]*pcbddc->local_primal_sizes[i]; 19930c7d97c5SJed Brown localdispl2[0]=0; 19942fa5cd67SKarl Rupp for (i=1;i<size_prec_comm;i++) localdispl2[i]=localsizes2[i-1]+localdispl2[i-1]; 19950c7d97c5SJed Brown j=0; 19962fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) j+=localsizes2[i]; 19970c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 19980c7d97c5SJed Brown } 19990c7d97c5SJed Brown 20000c7d97c5SJed Brown mysize=pcbddc->local_primal_size; 20010c7d97c5SJed Brown mysize2=pcbddc->local_primal_size*pcbddc->local_primal_size; 2002ef028eecSStefano Zampini ierr = PetscMalloc(mysize*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 20032fa5cd67SKarl Rupp for (i=0; i<mysize; i++) send_buffer[i]=(PetscMPIInt)pcbddc->local_primal_indices[i]; 20042fa5cd67SKarl Rupp 20050c7d97c5SJed Brown if (pcbddc->coarse_problem_type == SEQUENTIAL_BDDC){ 2006ef028eecSStefano 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); 200753cdbc3dSStefano 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); 20080c7d97c5SJed Brown } else { 2009ef028eecSStefano 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); 201053cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,prec_comm);CHKERRQ(ierr); 20110c7d97c5SJed Brown } 2012ef028eecSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 20130c7d97c5SJed Brown break; 2014da1bb401SStefano Zampini }/* switch on coarse problem and communications associated with finished */ 20150c7d97c5SJed Brown } 20160c7d97c5SJed Brown 20170c7d97c5SJed Brown /* Now create and fill up coarse matrix */ 20180c7d97c5SJed Brown if ( rank_prec_comm == active_rank ) { 2019142dfd88SStefano Zampini 2020142dfd88SStefano Zampini Mat matis_coarse_local_mat; 2021142dfd88SStefano Zampini 20220c7d97c5SJed Brown if (pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 20230c7d97c5SJed Brown ierr = MatCreate(coarse_comm,&pcbddc->coarse_mat);CHKERRQ(ierr); 20240c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_mat,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size);CHKERRQ(ierr); 20250c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_mat,coarse_mat_type);CHKERRQ(ierr); 2026674ae819SStefano Zampini ierr = MatSetOptionsPrefix(pcbddc->coarse_mat,"coarse_");CHKERRQ(ierr); 2027674ae819SStefano Zampini ierr = MatSetFromOptions(pcbddc->coarse_mat);CHKERRQ(ierr); 20283b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 2029da1bb401SStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 20303b03a366Sstefano_zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 20310c7d97c5SJed Brown } else { 20324fad6a16SStefano Zampini ierr = MatCreateIS(coarse_comm,1,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_ISLG,&pcbddc->coarse_mat);CHKERRQ(ierr); 20333b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 20340c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 2035674ae819SStefano Zampini ierr = MatSetOptionsPrefix(pcbddc->coarse_mat,"coarse_");CHKERRQ(ierr); 2036674ae819SStefano Zampini ierr = MatSetFromOptions(pcbddc->coarse_mat);CHKERRQ(ierr); 20373b03a366Sstefano_zampini ierr = MatSetUp(matis_coarse_local_mat);CHKERRQ(ierr); 2038da1bb401SStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 2039a0ba757dSStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 20400c7d97c5SJed Brown } 2041142dfd88SStefano Zampini /* preallocation */ 2042142dfd88SStefano Zampini if (pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 2043ef028eecSStefano Zampini 2044674ae819SStefano Zampini PetscInt lrows,lcols,bs; 2045ef028eecSStefano Zampini 2046142dfd88SStefano Zampini ierr = MatGetLocalSize(pcbddc->coarse_mat,&lrows,&lcols);CHKERRQ(ierr); 2047142dfd88SStefano Zampini ierr = MatPreallocateInitialize(coarse_comm,lrows,lcols,dnz,onz);CHKERRQ(ierr); 2048674ae819SStefano Zampini ierr = MatGetBlockSize(pcbddc->coarse_mat,&bs);CHKERRQ(ierr); 2049ef028eecSStefano Zampini 2050142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == PARALLEL_BDDC) { 2051ef028eecSStefano Zampini 2052ef028eecSStefano Zampini Vec vec_dnz,vec_onz; 2053ef028eecSStefano Zampini PetscScalar *my_dnz,*my_onz,*array; 2054ef028eecSStefano Zampini PetscInt *mat_ranges,*row_ownership; 2055ef028eecSStefano Zampini PetscInt coarse_index_row,coarse_index_col,owner; 2056ef028eecSStefano Zampini 2057ef028eecSStefano Zampini ierr = VecCreate(prec_comm,&vec_dnz);CHKERRQ(ierr); 2058674ae819SStefano Zampini ierr = VecSetBlockSize(vec_dnz,bs);CHKERRQ(ierr); 2059ef028eecSStefano Zampini ierr = VecSetSizes(vec_dnz,PETSC_DECIDE,pcbddc->coarse_size);CHKERRQ(ierr); 2060ef028eecSStefano Zampini ierr = VecSetType(vec_dnz,VECMPI);CHKERRQ(ierr); 2061ef028eecSStefano Zampini ierr = VecDuplicate(vec_dnz,&vec_onz);CHKERRQ(ierr); 2062ef028eecSStefano Zampini 2063ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscScalar),&my_dnz);CHKERRQ(ierr); 2064ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscScalar),&my_onz);CHKERRQ(ierr); 2065ef028eecSStefano Zampini ierr = PetscMemzero(my_dnz,pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 2066ef028eecSStefano Zampini ierr = PetscMemzero(my_onz,pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 2067ef028eecSStefano Zampini 2068ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscInt),&row_ownership);CHKERRQ(ierr); 2069ef028eecSStefano Zampini ierr = MatGetOwnershipRanges(pcbddc->coarse_mat,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 2070142dfd88SStefano Zampini for (i=0;i<size_prec_comm;i++) { 2071ef028eecSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 2072ef028eecSStefano Zampini row_ownership[j]=i; 2073142dfd88SStefano Zampini } 2074142dfd88SStefano Zampini } 2075ef028eecSStefano Zampini 2076ef028eecSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 2077ef028eecSStefano Zampini coarse_index_row = pcbddc->local_primal_indices[i]; 2078ef028eecSStefano Zampini owner = row_ownership[coarse_index_row]; 2079ef028eecSStefano Zampini for (j=i;j<pcbddc->local_primal_size;j++) { 2080ef028eecSStefano Zampini owner = row_ownership[coarse_index_row]; 2081ef028eecSStefano Zampini coarse_index_col = pcbddc->local_primal_indices[j]; 2082ef028eecSStefano Zampini if (coarse_index_col > mat_ranges[owner]-1 && coarse_index_col < mat_ranges[owner+1] ) { 2083ef028eecSStefano Zampini my_dnz[i] += 1.0; 2084142dfd88SStefano Zampini } else { 2085ef028eecSStefano Zampini my_onz[i] += 1.0; 2086142dfd88SStefano Zampini } 2087ef028eecSStefano Zampini if (i != j) { 2088ef028eecSStefano Zampini owner = row_ownership[coarse_index_col]; 2089ef028eecSStefano Zampini if (coarse_index_row > mat_ranges[owner]-1 && coarse_index_row < mat_ranges[owner+1] ) { 2090ef028eecSStefano Zampini my_dnz[j] += 1.0; 2091142dfd88SStefano Zampini } else { 2092ef028eecSStefano Zampini my_onz[j] += 1.0; 2093142dfd88SStefano Zampini } 2094142dfd88SStefano Zampini } 2095142dfd88SStefano Zampini } 2096142dfd88SStefano Zampini } 2097ef028eecSStefano Zampini ierr = VecSet(vec_dnz,0.0);CHKERRQ(ierr); 2098ef028eecSStefano Zampini ierr = VecSet(vec_onz,0.0);CHKERRQ(ierr); 2099a929c220SStefano Zampini if (pcbddc->local_primal_size) { 2100ef028eecSStefano Zampini ierr = VecSetValues(vec_dnz,pcbddc->local_primal_size,pcbddc->local_primal_indices,my_dnz,ADD_VALUES);CHKERRQ(ierr); 2101ef028eecSStefano Zampini ierr = VecSetValues(vec_onz,pcbddc->local_primal_size,pcbddc->local_primal_indices,my_onz,ADD_VALUES);CHKERRQ(ierr); 2102a929c220SStefano Zampini } 2103ef028eecSStefano Zampini ierr = VecAssemblyBegin(vec_dnz);CHKERRQ(ierr); 2104ef028eecSStefano Zampini ierr = VecAssemblyBegin(vec_onz);CHKERRQ(ierr); 2105ef028eecSStefano Zampini ierr = VecAssemblyEnd(vec_dnz);CHKERRQ(ierr); 2106ef028eecSStefano Zampini ierr = VecAssemblyEnd(vec_onz);CHKERRQ(ierr); 2107ef028eecSStefano Zampini j = mat_ranges[rank_prec_comm+1]-mat_ranges[rank_prec_comm]; 2108ef028eecSStefano Zampini ierr = VecGetArray(vec_dnz,&array);CHKERRQ(ierr); 21095b08dc53SStefano Zampini for (i=0; i<j; i++) dnz[i] = (PetscInt)PetscRealPart(array[i]); 21102fa5cd67SKarl Rupp 2111ef028eecSStefano Zampini ierr = VecRestoreArray(vec_dnz,&array);CHKERRQ(ierr); 2112ef028eecSStefano Zampini ierr = VecGetArray(vec_onz,&array);CHKERRQ(ierr); 21135b08dc53SStefano Zampini for (i=0;i<j;i++) onz[i] = (PetscInt)PetscRealPart(array[i]); 21142fa5cd67SKarl Rupp 2115ef028eecSStefano Zampini ierr = VecRestoreArray(vec_onz,&array);CHKERRQ(ierr); 2116ef028eecSStefano Zampini ierr = PetscFree(my_dnz);CHKERRQ(ierr); 2117ef028eecSStefano Zampini ierr = PetscFree(my_onz);CHKERRQ(ierr); 2118ef028eecSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 2119ef028eecSStefano Zampini ierr = VecDestroy(&vec_dnz);CHKERRQ(ierr); 2120ef028eecSStefano Zampini ierr = VecDestroy(&vec_onz);CHKERRQ(ierr); 2121142dfd88SStefano Zampini } else { 2122142dfd88SStefano Zampini for (k=0;k<size_prec_comm;k++){ 2123142dfd88SStefano Zampini offset=pcbddc->local_primal_displacements[k]; 2124142dfd88SStefano Zampini offset2=localdispl2[k]; 2125142dfd88SStefano Zampini ins_local_primal_size = pcbddc->local_primal_sizes[k]; 2126ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2127ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2128ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2129ef028eecSStefano Zampini } 2130142dfd88SStefano Zampini for (j=0;j<ins_local_primal_size;j++) { 2131142dfd88SStefano Zampini ierr = MatPreallocateSet(ins_local_primal_indices[j],ins_local_primal_size,ins_local_primal_indices,dnz,onz);CHKERRQ(ierr); 2132142dfd88SStefano Zampini } 2133ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2134142dfd88SStefano Zampini } 2135142dfd88SStefano Zampini } 21362fa5cd67SKarl Rupp 2137142dfd88SStefano Zampini /* check */ 2138142dfd88SStefano Zampini for (i=0;i<lrows;i++) { 21392fa5cd67SKarl Rupp if (dnz[i]>lcols) dnz[i]=lcols; 21402fa5cd67SKarl Rupp if (onz[i]>pcbddc->coarse_size-lcols) onz[i]=pcbddc->coarse_size-lcols; 2141142dfd88SStefano Zampini } 2142d9a4edebSJed Brown ierr = MatSeqAIJSetPreallocation(pcbddc->coarse_mat,0,dnz);CHKERRQ(ierr); 2143d9a4edebSJed Brown ierr = MatMPIAIJSetPreallocation(pcbddc->coarse_mat,0,dnz,0,onz);CHKERRQ(ierr); 2144142dfd88SStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 2145142dfd88SStefano Zampini } else { 2146523858cfSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis_coarse_local_mat,0,dnz);CHKERRQ(ierr); 2147523858cfSStefano Zampini ierr = PetscFree(dnz);CHKERRQ(ierr); 2148142dfd88SStefano Zampini } 2149142dfd88SStefano Zampini /* insert values */ 2150523858cfSStefano Zampini if (pcbddc->coarse_problem_type == PARALLEL_BDDC) { 21510c7d97c5SJed 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); 2152523858cfSStefano Zampini } else if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2153523858cfSStefano Zampini if (pcbddc->coarsening_ratio == 1) { 2154523858cfSStefano Zampini ins_coarse_mat_vals = coarse_submat_vals; 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,INSERT_VALUES);CHKERRQ(ierr); 2156523858cfSStefano Zampini } else { 2157523858cfSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2158523858cfSStefano Zampini for (k=0;k<pcbddc->replicated_primal_size;k++) { 2159523858cfSStefano Zampini offset = pcbddc->local_primal_displacements[k]; 2160523858cfSStefano Zampini offset2 = localdispl2[k]; 2161523858cfSStefano Zampini ins_local_primal_size = pcbddc->local_primal_displacements[k+1]-pcbddc->local_primal_displacements[k]; 2162ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2163ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2164ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2165ef028eecSStefano Zampini } 2166523858cfSStefano Zampini ins_coarse_mat_vals = &temp_coarse_mat_vals[offset2]; 2167523858cfSStefano 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); 2168ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2169523858cfSStefano Zampini } 2170523858cfSStefano Zampini } 2171523858cfSStefano Zampini ins_local_primal_indices = 0; 2172523858cfSStefano Zampini ins_coarse_mat_vals = 0; 2173ea7e1babSStefano Zampini } else { 2174ea7e1babSStefano Zampini for (k=0;k<size_prec_comm;k++){ 2175ea7e1babSStefano Zampini offset=pcbddc->local_primal_displacements[k]; 2176ea7e1babSStefano Zampini offset2=localdispl2[k]; 2177ea7e1babSStefano Zampini ins_local_primal_size = pcbddc->local_primal_sizes[k]; 2178ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2179ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2180ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2181ef028eecSStefano Zampini } 2182ea7e1babSStefano Zampini ins_coarse_mat_vals = &temp_coarse_mat_vals[offset2]; 2183ea7e1babSStefano 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); 2184ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2185ea7e1babSStefano Zampini } 2186ea7e1babSStefano Zampini ins_local_primal_indices = 0; 2187ea7e1babSStefano Zampini ins_coarse_mat_vals = 0; 2188ea7e1babSStefano Zampini } 21890c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 21900c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2191142dfd88SStefano Zampini /* symmetry of coarse matrix */ 2192142dfd88SStefano Zampini if (issym) { 2193142dfd88SStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 2194142dfd88SStefano Zampini } 21950c7d97c5SJed Brown ierr = MatGetVecs(pcbddc->coarse_mat,&pcbddc->coarse_vec,&pcbddc->coarse_rhs);CHKERRQ(ierr); 21960bdf917eSStefano Zampini } 21970bdf917eSStefano Zampini 21980bdf917eSStefano Zampini /* create loc to glob scatters if needed */ 21990bdf917eSStefano Zampini if (pcbddc->coarse_communications_type == SCATTERS_BDDC) { 22000bdf917eSStefano Zampini IS local_IS,global_IS; 22010bdf917eSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&local_IS);CHKERRQ(ierr); 22020bdf917eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_indices,PETSC_COPY_VALUES,&global_IS);CHKERRQ(ierr); 22030bdf917eSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,local_IS,pcbddc->coarse_vec,global_IS,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 22040bdf917eSStefano Zampini ierr = ISDestroy(&local_IS);CHKERRQ(ierr); 22050bdf917eSStefano Zampini ierr = ISDestroy(&global_IS);CHKERRQ(ierr); 22060bdf917eSStefano Zampini } 22070bdf917eSStefano Zampini 2208a929c220SStefano Zampini /* free memory no longer needed */ 2209a929c220SStefano Zampini if (coarse_ISLG) { ierr = ISLocalToGlobalMappingDestroy(&coarse_ISLG);CHKERRQ(ierr); } 2210a929c220SStefano Zampini if (ins_local_primal_indices) { ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); } 2211a929c220SStefano Zampini if (ins_coarse_mat_vals) { ierr = PetscFree(ins_coarse_mat_vals);CHKERRQ(ierr); } 2212a929c220SStefano Zampini if (localsizes2) { ierr = PetscFree(localsizes2);CHKERRQ(ierr); } 2213a929c220SStefano Zampini if (localdispl2) { ierr = PetscFree(localdispl2);CHKERRQ(ierr); } 2214a929c220SStefano Zampini if (temp_coarse_mat_vals) { ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr); } 2215a929c220SStefano Zampini 2216674ae819SStefano Zampini /* Compute coarse null space */ 2217674ae819SStefano Zampini CoarseNullSpace = 0; 22180bdf917eSStefano Zampini if (pcbddc->NullSpace) { 2219674ae819SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,&CoarseNullSpace);CHKERRQ(ierr); 22200bdf917eSStefano Zampini } 22210bdf917eSStefano Zampini 22220bdf917eSStefano Zampini /* KSP for coarse problem */ 22230bdf917eSStefano Zampini if (rank_prec_comm == active_rank) { 22242e8d2280SStefano Zampini PetscBool isbddc=PETSC_FALSE; 22250bdf917eSStefano Zampini 222653cdbc3dSStefano Zampini ierr = KSPCreate(coarse_comm,&pcbddc->coarse_ksp);CHKERRQ(ierr); 222753cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 222853cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 22293b03a366Sstefano_zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,max_it_coarse_ksp);CHKERRQ(ierr); 223053cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 223153cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 223253cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 22330c7d97c5SJed Brown /* Allow user's customization */ 2234da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,"coarse_");CHKERRQ(ierr); 22350c7d97c5SJed Brown /* Set Up PC for coarse problem BDDC */ 223653cdbc3dSStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 22374fad6a16SStefano Zampini i = pcbddc->current_level+1; 22384fad6a16SStefano Zampini ierr = PCBDDCSetLevel(pc_temp,i);CHKERRQ(ierr); 22394fad6a16SStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 22404fad6a16SStefano Zampini ierr = PCBDDCSetMaxLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 224153cdbc3dSStefano Zampini ierr = PCBDDCSetCoarseProblemType(pc_temp,MULTILEVEL_BDDC);CHKERRQ(ierr); 2242674ae819SStefano Zampini if (CoarseNullSpace) { 2243674ae819SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 2244674ae819SStefano Zampini } 22454fad6a16SStefano Zampini if (dbg_flag) { 22464fad6a16SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------Level %d: Setting up level %d---------------\n",pcbddc->current_level,i);CHKERRQ(ierr); 22474fad6a16SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 224853cdbc3dSStefano Zampini } 2249674ae819SStefano Zampini } else { 2250674ae819SStefano Zampini if (CoarseNullSpace) { 2251674ae819SStefano Zampini ierr = KSPSetNullSpace(pcbddc->coarse_ksp,CoarseNullSpace);CHKERRQ(ierr); 2252674ae819SStefano Zampini } 22534fad6a16SStefano Zampini } 22544fad6a16SStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 225553cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 2256142dfd88SStefano Zampini 22570298fd71SBarry Smith ierr = KSPGetTolerances(pcbddc->coarse_ksp,NULL,NULL,NULL,&j);CHKERRQ(ierr); 22582e8d2280SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 22592e8d2280SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 22602e8d2280SStefano Zampini if (j == 1) { 22612e8d2280SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 22622e8d2280SStefano Zampini if (isbddc) { 22632e8d2280SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc_temp,PETSC_FALSE);CHKERRQ(ierr); 22645619798eSStefano Zampini } 22655619798eSStefano Zampini } 22660c7d97c5SJed Brown } 2267a929c220SStefano Zampini /* Check coarse problem if requested */ 2268142dfd88SStefano Zampini if ( dbg_flag && rank_prec_comm == active_rank ) { 2269142dfd88SStefano Zampini KSP check_ksp; 2270142dfd88SStefano Zampini PC check_pc; 2271142dfd88SStefano Zampini Vec check_vec; 2272142dfd88SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min,lambda_max; 227319fd82e9SBarry Smith KSPType check_ksp_type; 22740c7d97c5SJed Brown 2275142dfd88SStefano Zampini /* Create ksp object suitable for extreme eigenvalues' estimation */ 2276142dfd88SStefano Zampini ierr = KSPCreate(coarse_comm,&check_ksp);CHKERRQ(ierr); 2277142dfd88SStefano Zampini ierr = KSPSetOperators(check_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 22780bdf917eSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 2279142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 22802fa5cd67SKarl Rupp if (issym) check_ksp_type = KSPCG; 22812fa5cd67SKarl Rupp else check_ksp_type = KSPGMRES; 2282142dfd88SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,PETSC_TRUE);CHKERRQ(ierr); 2283142dfd88SStefano Zampini } else { 2284142dfd88SStefano Zampini check_ksp_type = KSPPREONLY; 2285142dfd88SStefano Zampini } 2286142dfd88SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 2287142dfd88SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 2288142dfd88SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 2289142dfd88SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 2290142dfd88SStefano Zampini /* create random vec */ 2291142dfd88SStefano Zampini ierr = VecDuplicate(pcbddc->coarse_vec,&check_vec);CHKERRQ(ierr); 22920298fd71SBarry Smith ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 2293674ae819SStefano Zampini if (CoarseNullSpace) { 22941cb54aadSJed Brown ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 2295674ae819SStefano Zampini } 2296142dfd88SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,check_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 2297142dfd88SStefano Zampini /* solve coarse problem */ 2298142dfd88SStefano Zampini ierr = KSPSolve(check_ksp,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 2299674ae819SStefano Zampini if (CoarseNullSpace) { 23001cb54aadSJed Brown ierr = MatNullSpaceRemove(CoarseNullSpace,pcbddc->coarse_vec);CHKERRQ(ierr); 2301674ae819SStefano Zampini } 2302142dfd88SStefano Zampini /* check coarse problem residual error */ 2303142dfd88SStefano Zampini ierr = VecAXPY(check_vec,-1.0,pcbddc->coarse_vec);CHKERRQ(ierr); 2304142dfd88SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 2305142dfd88SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,check_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 2306142dfd88SStefano Zampini ierr = VecNorm(pcbddc->coarse_rhs,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 2307142dfd88SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 2308142dfd88SStefano Zampini /* get eigenvalue estimation if inexact */ 2309142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2310142dfd88SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); 2311142dfd88SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&k);CHKERRQ(ierr); 2312142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues estimated with %d iterations of %s.\n",k,check_ksp_type);CHKERRQ(ierr); 2313e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues: % 1.14e %1.14e\n",lambda_min,lambda_max);CHKERRQ(ierr); 23143b03a366Sstefano_zampini } 2315142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem exact infty_error : %1.14e\n",infty_error);CHKERRQ(ierr); 2316142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem residual infty_error: %1.14e\n",abs_infty_error);CHKERRQ(ierr); 2317142dfd88SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 231853cdbc3dSStefano Zampini } 2319674ae819SStefano Zampini if (dbg_flag) { 2320da1bb401SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2321da1bb401SStefano Zampini } 2322674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 2323a0ba757dSStefano Zampini 23240c7d97c5SJed Brown PetscFunctionReturn(0); 23250c7d97c5SJed Brown } 23260c7d97c5SJed Brown 2327