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 PCBDDCSetUseExactDirichlet(PC,PetscBool); 28674ae819SStefano Zampini static PetscErrorCode PCBDDCSetLevel(PC,PetscInt); 29674ae819SStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC); 30674ae819SStefano Zampini static PetscErrorCode PCBDDCSetUpCoarseEnvironment(PC,PetscScalar*); 31674ae819SStefano Zampini 320c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 330c7d97c5SJed Brown #undef __FUNCT__ 340c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC" 350c7d97c5SJed Brown PetscErrorCode PCSetFromOptions_BDDC(PC pc) 360c7d97c5SJed Brown { 370c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 380c7d97c5SJed Brown PetscErrorCode ierr; 390c7d97c5SJed Brown 400c7d97c5SJed Brown PetscFunctionBegin; 410c7d97c5SJed Brown ierr = PetscOptionsHead("BDDC options");CHKERRQ(ierr); 420c7d97c5SJed Brown /* Verbose debugging of main data structures */ 430298fd71SBarry Smith ierr = PetscOptionsBool("-pc_bddc_check_all" ,"Verbose (debugging) output for PCBDDC" ,"none",pcbddc->dbg_flag ,&pcbddc->dbg_flag ,NULL);CHKERRQ(ierr); 440c7d97c5SJed Brown /* Some customization for default primal space */ 450298fd71SBarry 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); 460298fd71SBarry 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); 470298fd71SBarry 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); 480298fd71SBarry 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); 490c7d97c5SJed Brown /* Coarse solver context */ 506c667b0aSStefano 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 */ 510298fd71SBarry 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); 520c7d97c5SJed Brown /* Two different application of BDDC to the whole set of dofs, internal and interface */ 530298fd71SBarry 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); 54674ae819SStefano 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); 55674ae819SStefano 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); 56674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 57674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 58674ae819SStefano Zampini } 590298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr); 600298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_max_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr); 61674ae819SStefano 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); 620c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 630c7d97c5SJed Brown PetscFunctionReturn(0); 640c7d97c5SJed Brown } 650c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 66674ae819SStefano Zampini #undef __FUNCT__ 67674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS_BDDC" 68674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 69674ae819SStefano Zampini { 70674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 71674ae819SStefano Zampini PetscErrorCode ierr; 721e6b0712SBarry Smith 73674ae819SStefano Zampini PetscFunctionBegin; 74674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 75674ae819SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 76674ae819SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 77674ae819SStefano Zampini PetscFunctionReturn(0); 78674ae819SStefano Zampini } 79674ae819SStefano Zampini #undef __FUNCT__ 80674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS" 81674ae819SStefano Zampini /*@ 82674ae819SStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set user defined primal vertices in PCBDDC. 83674ae819SStefano Zampini 84674ae819SStefano Zampini Not collective 85674ae819SStefano Zampini 86674ae819SStefano Zampini Input Parameters: 87674ae819SStefano Zampini + pc - the preconditioning context 88674ae819SStefano Zampini - PrimalVertices - index sets of primal vertices in local numbering 89674ae819SStefano Zampini 90674ae819SStefano Zampini Level: intermediate 91674ae819SStefano Zampini 92674ae819SStefano Zampini Notes: 93674ae819SStefano Zampini 94674ae819SStefano Zampini .seealso: PCBDDC 95674ae819SStefano Zampini @*/ 96674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 97674ae819SStefano Zampini { 98674ae819SStefano Zampini PetscErrorCode ierr; 99674ae819SStefano Zampini 100674ae819SStefano Zampini PetscFunctionBegin; 101674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 102674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 103674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 104674ae819SStefano Zampini PetscFunctionReturn(0); 105674ae819SStefano Zampini } 106674ae819SStefano Zampini /* -------------------------------------------------------------------------- */ 1070c7d97c5SJed Brown #undef __FUNCT__ 1080c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType_BDDC" 10953cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetCoarseProblemType_BDDC(PC pc, CoarseProblemType CPT) 1100c7d97c5SJed Brown { 1110c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1120c7d97c5SJed Brown 1130c7d97c5SJed Brown PetscFunctionBegin; 1140c7d97c5SJed Brown pcbddc->coarse_problem_type = CPT; 1150c7d97c5SJed Brown PetscFunctionReturn(0); 1160c7d97c5SJed Brown } 1171e6b0712SBarry Smith 1180c7d97c5SJed Brown #undef __FUNCT__ 1190c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType" 12053cdbc3dSStefano Zampini /*@ 1219c0446d6SStefano Zampini PCBDDCSetCoarseProblemType - Set coarse problem type in PCBDDC. 12253cdbc3dSStefano Zampini 1239c0446d6SStefano Zampini Not collective 12453cdbc3dSStefano Zampini 12553cdbc3dSStefano Zampini Input Parameters: 12653cdbc3dSStefano Zampini + pc - the preconditioning context 12753cdbc3dSStefano Zampini - CoarseProblemType - pick a better name and explain what this is 12853cdbc3dSStefano Zampini 12953cdbc3dSStefano Zampini Level: intermediate 13053cdbc3dSStefano Zampini 13153cdbc3dSStefano Zampini Notes: 132da1bb401SStefano Zampini Not collective but all procs must call with same arguments. 13353cdbc3dSStefano Zampini 13453cdbc3dSStefano Zampini .seealso: PCBDDC 13553cdbc3dSStefano Zampini @*/ 1360c7d97c5SJed Brown PetscErrorCode PCBDDCSetCoarseProblemType(PC pc, CoarseProblemType CPT) 1370c7d97c5SJed Brown { 1380c7d97c5SJed Brown PetscErrorCode ierr; 1390c7d97c5SJed Brown 1400c7d97c5SJed Brown PetscFunctionBegin; 1410c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1420c7d97c5SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetCoarseProblemType_C",(PC,CoarseProblemType),(pc,CPT));CHKERRQ(ierr); 1430c7d97c5SJed Brown PetscFunctionReturn(0); 1440c7d97c5SJed Brown } 1450c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1460c7d97c5SJed Brown #undef __FUNCT__ 1474fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio_BDDC" 1484fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 1494fad6a16SStefano Zampini { 1504fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1514fad6a16SStefano Zampini 1524fad6a16SStefano Zampini PetscFunctionBegin; 1534fad6a16SStefano Zampini pcbddc->coarsening_ratio=k; 1544fad6a16SStefano Zampini PetscFunctionReturn(0); 1554fad6a16SStefano Zampini } 1561e6b0712SBarry Smith 1574fad6a16SStefano Zampini #undef __FUNCT__ 1584fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio" 1594fad6a16SStefano Zampini /*@ 1604fad6a16SStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel coarsening 1614fad6a16SStefano Zampini 1624fad6a16SStefano Zampini Logically collective on PC 1634fad6a16SStefano Zampini 1644fad6a16SStefano Zampini Input Parameters: 1654fad6a16SStefano Zampini + pc - the preconditioning context 1664fad6a16SStefano Zampini - k - coarsening ratio 1674fad6a16SStefano Zampini 1684fad6a16SStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level. 1694fad6a16SStefano Zampini 1704fad6a16SStefano Zampini Level: intermediate 1714fad6a16SStefano Zampini 1724fad6a16SStefano Zampini Notes: 1734fad6a16SStefano Zampini 1744fad6a16SStefano Zampini .seealso: PCBDDC 1754fad6a16SStefano Zampini @*/ 1764fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 1774fad6a16SStefano Zampini { 1784fad6a16SStefano Zampini PetscErrorCode ierr; 1794fad6a16SStefano Zampini 1804fad6a16SStefano Zampini PetscFunctionBegin; 1814fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1824fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 1834fad6a16SStefano Zampini PetscFunctionReturn(0); 1844fad6a16SStefano Zampini } 1854fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 1861e6b0712SBarry Smith 1874fad6a16SStefano Zampini #undef __FUNCT__ 1884fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetMaxLevels_BDDC" 1894fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetMaxLevels_BDDC(PC pc,PetscInt max_levels) 1904fad6a16SStefano Zampini { 1914fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1924fad6a16SStefano Zampini 1934fad6a16SStefano Zampini PetscFunctionBegin; 1944fad6a16SStefano Zampini pcbddc->max_levels=max_levels; 1954fad6a16SStefano Zampini PetscFunctionReturn(0); 1964fad6a16SStefano Zampini } 1971e6b0712SBarry Smith 1984fad6a16SStefano Zampini #undef __FUNCT__ 1994fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetMaxLevels" 2004fad6a16SStefano Zampini /*@ 2014fad6a16SStefano Zampini PCBDDCSetMaxLevels - Sets the maximum number of levels within the multilevel approach. 2024fad6a16SStefano Zampini 2034fad6a16SStefano Zampini Logically collective on PC 2044fad6a16SStefano Zampini 2054fad6a16SStefano Zampini Input Parameters: 2064fad6a16SStefano Zampini + pc - the preconditioning context 2074fad6a16SStefano Zampini - max_levels - the maximum number of levels 2084fad6a16SStefano Zampini 2094fad6a16SStefano Zampini Default value is 1, i.e. coarse problem will be solved inexactly with one application 2104fad6a16SStefano Zampini of PCBDDC preconditioner if the multilevel approach is requested. 2114fad6a16SStefano Zampini 2124fad6a16SStefano Zampini Level: intermediate 2134fad6a16SStefano Zampini 2144fad6a16SStefano Zampini Notes: 2154fad6a16SStefano Zampini 2164fad6a16SStefano Zampini .seealso: PCBDDC 2174fad6a16SStefano Zampini @*/ 2184fad6a16SStefano Zampini PetscErrorCode PCBDDCSetMaxLevels(PC pc,PetscInt max_levels) 2194fad6a16SStefano Zampini { 2204fad6a16SStefano Zampini PetscErrorCode ierr; 2214fad6a16SStefano Zampini 2224fad6a16SStefano Zampini PetscFunctionBegin; 2234fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2244fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetMaxLevels_C",(PC,PetscInt),(pc,max_levels));CHKERRQ(ierr); 2254fad6a16SStefano Zampini PetscFunctionReturn(0); 2264fad6a16SStefano Zampini } 2274fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 2281e6b0712SBarry Smith 2294fad6a16SStefano Zampini #undef __FUNCT__ 2300bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace_BDDC" 2310bdf917eSStefano Zampini static PetscErrorCode PCBDDCSetNullSpace_BDDC(PC pc,MatNullSpace NullSpace) 2320bdf917eSStefano Zampini { 2330bdf917eSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2340bdf917eSStefano Zampini PetscErrorCode ierr; 2350bdf917eSStefano Zampini 2360bdf917eSStefano Zampini PetscFunctionBegin; 2370bdf917eSStefano Zampini ierr = PetscObjectReference((PetscObject)NullSpace);CHKERRQ(ierr); 2380bdf917eSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 2390bdf917eSStefano Zampini pcbddc->NullSpace=NullSpace; 2400bdf917eSStefano Zampini PetscFunctionReturn(0); 2410bdf917eSStefano Zampini } 2421e6b0712SBarry Smith 2430bdf917eSStefano Zampini #undef __FUNCT__ 2440bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace" 2450bdf917eSStefano Zampini /*@ 2460bdf917eSStefano Zampini PCBDDCSetNullSpace - Set NullSpace of global operator of BDDC preconditioned mat. 2470bdf917eSStefano Zampini 2480bdf917eSStefano Zampini Logically collective on PC and MatNullSpace 2490bdf917eSStefano Zampini 2500bdf917eSStefano Zampini Input Parameters: 2510bdf917eSStefano Zampini + pc - the preconditioning context 2520bdf917eSStefano Zampini - NullSpace - Null space of the linear operator to be preconditioned. 2530bdf917eSStefano Zampini 2540bdf917eSStefano Zampini Level: intermediate 2550bdf917eSStefano Zampini 2560bdf917eSStefano Zampini Notes: 2570bdf917eSStefano Zampini 2580bdf917eSStefano Zampini .seealso: PCBDDC 2590bdf917eSStefano Zampini @*/ 2600bdf917eSStefano Zampini PetscErrorCode PCBDDCSetNullSpace(PC pc,MatNullSpace NullSpace) 2610bdf917eSStefano Zampini { 2620bdf917eSStefano Zampini PetscErrorCode ierr; 2630bdf917eSStefano Zampini 2640bdf917eSStefano Zampini PetscFunctionBegin; 2650bdf917eSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 266674ae819SStefano Zampini PetscValidHeaderSpecific(NullSpace,MAT_NULLSPACE_CLASSID,2); 2670bdf917eSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNullSpace_C",(PC,MatNullSpace),(pc,NullSpace));CHKERRQ(ierr); 2680bdf917eSStefano Zampini PetscFunctionReturn(0); 2690bdf917eSStefano Zampini } 2700bdf917eSStefano Zampini /* -------------------------------------------------------------------------- */ 2711e6b0712SBarry Smith 2720bdf917eSStefano Zampini #undef __FUNCT__ 2733b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC" 2743b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 2753b03a366Sstefano_zampini { 2763b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2773b03a366Sstefano_zampini PetscErrorCode ierr; 2783b03a366Sstefano_zampini 2793b03a366Sstefano_zampini PetscFunctionBegin; 2803b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 28136e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 28236e030ebSStefano Zampini pcbddc->DirichletBoundaries=DirichletBoundaries; 2833b03a366Sstefano_zampini PetscFunctionReturn(0); 2843b03a366Sstefano_zampini } 2851e6b0712SBarry Smith 2863b03a366Sstefano_zampini #undef __FUNCT__ 2873b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries" 2883b03a366Sstefano_zampini /*@ 289da1bb401SStefano Zampini PCBDDCSetDirichletBoundaries - Set index set defining subdomain part (in local ordering) 290da1bb401SStefano Zampini of Dirichlet boundaries for the global problem. 2913b03a366Sstefano_zampini 2923b03a366Sstefano_zampini Not collective 2933b03a366Sstefano_zampini 2943b03a366Sstefano_zampini Input Parameters: 2953b03a366Sstefano_zampini + pc - the preconditioning context 2960298fd71SBarry Smith - DirichletBoundaries - sequential index set defining the subdomain part of Dirichlet boundaries (can be NULL) 2973b03a366Sstefano_zampini 2983b03a366Sstefano_zampini Level: intermediate 2993b03a366Sstefano_zampini 3003b03a366Sstefano_zampini Notes: 3013b03a366Sstefano_zampini 3023b03a366Sstefano_zampini .seealso: PCBDDC 3033b03a366Sstefano_zampini @*/ 3043b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 3053b03a366Sstefano_zampini { 3063b03a366Sstefano_zampini PetscErrorCode ierr; 3073b03a366Sstefano_zampini 3083b03a366Sstefano_zampini PetscFunctionBegin; 3093b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 310674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 3113b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 3123b03a366Sstefano_zampini PetscFunctionReturn(0); 3133b03a366Sstefano_zampini } 3143b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 3151e6b0712SBarry Smith 3163b03a366Sstefano_zampini #undef __FUNCT__ 3170c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 31853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 3190c7d97c5SJed Brown { 3200c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 32153cdbc3dSStefano Zampini PetscErrorCode ierr; 3220c7d97c5SJed Brown 3230c7d97c5SJed Brown PetscFunctionBegin; 32453cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 32536e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 32636e030ebSStefano Zampini pcbddc->NeumannBoundaries=NeumannBoundaries; 3270c7d97c5SJed Brown PetscFunctionReturn(0); 3280c7d97c5SJed Brown } 3291e6b0712SBarry Smith 3300c7d97c5SJed Brown #undef __FUNCT__ 3310c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 33257527edcSJed Brown /*@ 333da1bb401SStefano Zampini PCBDDCSetNeumannBoundaries - Set index set defining subdomain part (in local ordering) 334da1bb401SStefano Zampini of Neumann boundaries for the global problem. 33557527edcSJed Brown 3369c0446d6SStefano Zampini Not collective 33757527edcSJed Brown 33857527edcSJed Brown Input Parameters: 33957527edcSJed Brown + pc - the preconditioning context 3400298fd71SBarry Smith - NeumannBoundaries - sequential index set defining the subdomain part of Neumann boundaries (can be NULL) 34157527edcSJed Brown 34257527edcSJed Brown Level: intermediate 34357527edcSJed Brown 34457527edcSJed Brown Notes: 34557527edcSJed Brown 34657527edcSJed Brown .seealso: PCBDDC 34757527edcSJed Brown @*/ 34853cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 3490c7d97c5SJed Brown { 3500c7d97c5SJed Brown PetscErrorCode ierr; 3510c7d97c5SJed Brown 3520c7d97c5SJed Brown PetscFunctionBegin; 3530c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 354674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 35553cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 35653cdbc3dSStefano Zampini PetscFunctionReturn(0); 35753cdbc3dSStefano Zampini } 35853cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 3591e6b0712SBarry Smith 36053cdbc3dSStefano Zampini #undef __FUNCT__ 361da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC" 362da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 363da1bb401SStefano Zampini { 364da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 365da1bb401SStefano Zampini 366da1bb401SStefano Zampini PetscFunctionBegin; 367da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 368da1bb401SStefano Zampini PetscFunctionReturn(0); 369da1bb401SStefano Zampini } 3701e6b0712SBarry Smith 371da1bb401SStefano Zampini #undef __FUNCT__ 372da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries" 373da1bb401SStefano Zampini /*@ 374da1bb401SStefano Zampini PCBDDCGetDirichletBoundaries - Get index set defining subdomain part (in local ordering) 375da1bb401SStefano Zampini of Dirichlet boundaries for the global problem. 376da1bb401SStefano Zampini 377da1bb401SStefano Zampini Not collective 378da1bb401SStefano Zampini 379da1bb401SStefano Zampini Input Parameters: 380da1bb401SStefano Zampini + pc - the preconditioning context 381da1bb401SStefano Zampini 382da1bb401SStefano Zampini Output Parameters: 383da1bb401SStefano Zampini + DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 384da1bb401SStefano Zampini 385da1bb401SStefano Zampini Level: intermediate 386da1bb401SStefano Zampini 387da1bb401SStefano Zampini Notes: 388da1bb401SStefano Zampini 389da1bb401SStefano Zampini .seealso: PCBDDC 390da1bb401SStefano Zampini @*/ 391da1bb401SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 392da1bb401SStefano Zampini { 393da1bb401SStefano Zampini PetscErrorCode ierr; 394da1bb401SStefano Zampini 395da1bb401SStefano Zampini PetscFunctionBegin; 396da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 397da1bb401SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 398da1bb401SStefano Zampini PetscFunctionReturn(0); 399da1bb401SStefano Zampini } 400da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 4011e6b0712SBarry Smith 402da1bb401SStefano Zampini #undef __FUNCT__ 40353cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 40453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 40553cdbc3dSStefano Zampini { 40653cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 40753cdbc3dSStefano Zampini 40853cdbc3dSStefano Zampini PetscFunctionBegin; 40953cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 41053cdbc3dSStefano Zampini PetscFunctionReturn(0); 41153cdbc3dSStefano Zampini } 4121e6b0712SBarry Smith 41353cdbc3dSStefano Zampini #undef __FUNCT__ 41453cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 41553cdbc3dSStefano Zampini /*@ 416da1bb401SStefano Zampini PCBDDCGetNeumannBoundaries - Get index set defining subdomain part (in local ordering) 417da1bb401SStefano Zampini of Neumann boundaries for the global problem. 41853cdbc3dSStefano Zampini 4199c0446d6SStefano Zampini Not collective 42053cdbc3dSStefano Zampini 42153cdbc3dSStefano Zampini Input Parameters: 42253cdbc3dSStefano Zampini + pc - the preconditioning context 42353cdbc3dSStefano Zampini 42453cdbc3dSStefano Zampini Output Parameters: 42553cdbc3dSStefano Zampini + NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 42653cdbc3dSStefano Zampini 42753cdbc3dSStefano Zampini Level: intermediate 42853cdbc3dSStefano Zampini 42953cdbc3dSStefano Zampini Notes: 43053cdbc3dSStefano Zampini 43153cdbc3dSStefano Zampini .seealso: PCBDDC 43253cdbc3dSStefano Zampini @*/ 43353cdbc3dSStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 43453cdbc3dSStefano Zampini { 43553cdbc3dSStefano Zampini PetscErrorCode ierr; 43653cdbc3dSStefano Zampini 43753cdbc3dSStefano Zampini PetscFunctionBegin; 43853cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 43953cdbc3dSStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 4400c7d97c5SJed Brown PetscFunctionReturn(0); 4410c7d97c5SJed Brown } 44236e030ebSStefano Zampini /* -------------------------------------------------------------------------- */ 4431e6b0712SBarry Smith 44436e030ebSStefano Zampini #undef __FUNCT__ 445da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC" 4461a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 44736e030ebSStefano Zampini { 44836e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 449da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 450da1bb401SStefano Zampini PetscErrorCode ierr; 45136e030ebSStefano Zampini 45236e030ebSStefano Zampini PetscFunctionBegin; 453674ae819SStefano Zampini /* free old CSR */ 454674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 455674ae819SStefano Zampini /* get CSR into graph structure */ 456da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 457674ae819SStefano Zampini ierr = PetscMalloc((nvtxs+1)*sizeof(PetscInt),&mat_graph->xadj);CHKERRQ(ierr); 458674ae819SStefano Zampini ierr = PetscMalloc(xadj[nvtxs]*sizeof(PetscInt),&mat_graph->adjncy);CHKERRQ(ierr); 459674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 460674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 461da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 4621a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 4631a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 464674ae819SStefano Zampini } 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 { 490da1bb401SStefano Zampini PetscInt nrows,ncols; 491da1bb401SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 49236e030ebSStefano Zampini PetscErrorCode ierr; 49336e030ebSStefano Zampini 49436e030ebSStefano Zampini PetscFunctionBegin; 49536e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 496674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 497674ae819SStefano Zampini PetscValidIntPointer(xadj,4); 498674ae819SStefano Zampini if (copymode != PETSC_COPY_VALUES && copymode != PETSC_OWN_POINTER) { 499674ae819SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d in %s\n",copymode,__FUNCT__); 500da1bb401SStefano Zampini } 501674ae819SStefano Zampini /* pcis info could not be available at this point */ 502674ae819SStefano Zampini ierr = MatGetSize(matis->A,&nrows,&ncols);CHKERRQ(ierr); 503674ae819SStefano Zampini if (nvtxs != nrows) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local adjacency size %d passed in %s differs from local problem size %d!\n",nvtxs,__FUNCT__,nrows); 504674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 50536e030ebSStefano Zampini PetscFunctionReturn(0); 50636e030ebSStefano Zampini } 5079c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 5081e6b0712SBarry Smith 5099c0446d6SStefano Zampini #undef __FUNCT__ 5109c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 5119c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 5129c0446d6SStefano Zampini { 5139c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5149c0446d6SStefano Zampini PetscInt i; 5159c0446d6SStefano Zampini PetscErrorCode ierr; 5169c0446d6SStefano Zampini 5179c0446d6SStefano Zampini PetscFunctionBegin; 518da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 5199c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 5209c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 5219c0446d6SStefano Zampini } 522d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 523da1bb401SStefano Zampini /* allocate space then set */ 5249c0446d6SStefano Zampini ierr = PetscMalloc(n_is*sizeof(IS),&pcbddc->ISForDofs);CHKERRQ(ierr); 5259c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 526da1bb401SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 527da1bb401SStefano Zampini pcbddc->ISForDofs[i]=ISForDofs[i]; 5289c0446d6SStefano Zampini } 5299c0446d6SStefano Zampini pcbddc->n_ISForDofs=n_is; 5309c0446d6SStefano Zampini PetscFunctionReturn(0); 5319c0446d6SStefano Zampini } 5321e6b0712SBarry Smith 5339c0446d6SStefano Zampini #undef __FUNCT__ 5349c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 5359c0446d6SStefano Zampini /*@ 536da1bb401SStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of local mat. 5379c0446d6SStefano Zampini 5389c0446d6SStefano Zampini Not collective 5399c0446d6SStefano Zampini 5409c0446d6SStefano Zampini Input Parameters: 5419c0446d6SStefano Zampini + pc - the preconditioning context 542da1bb401SStefano Zampini - n - number of index sets defining the fields 543da1bb401SStefano Zampini - IS[] - array of IS describing the fields 5449c0446d6SStefano Zampini 5459c0446d6SStefano Zampini Level: intermediate 5469c0446d6SStefano Zampini 5479c0446d6SStefano Zampini Notes: 5489c0446d6SStefano Zampini 5499c0446d6SStefano Zampini .seealso: PCBDDC 5509c0446d6SStefano Zampini @*/ 5519c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 5529c0446d6SStefano Zampini { 5539c0446d6SStefano Zampini PetscErrorCode ierr; 5549c0446d6SStefano Zampini 5559c0446d6SStefano Zampini PetscFunctionBegin; 5569c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5579c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 5589c0446d6SStefano Zampini PetscFunctionReturn(0); 5599c0446d6SStefano Zampini } 560da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 561534831adSStefano Zampini #undef __FUNCT__ 562534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC" 563534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 564534831adSStefano Zampini /* 565534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 566534831adSStefano Zampini guess if a transformation of basis approach has been selected. 5679c0446d6SStefano Zampini 568534831adSStefano Zampini Input Parameter: 569534831adSStefano Zampini + pc - the preconditioner contex 570534831adSStefano Zampini 571534831adSStefano Zampini Application Interface Routine: PCPreSolve() 572534831adSStefano Zampini 573534831adSStefano Zampini Notes: 574534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 575534831adSStefano Zampini the user, but instead is called by KSPSolve(). 576534831adSStefano Zampini */ 577534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 578534831adSStefano Zampini { 579534831adSStefano Zampini PetscErrorCode ierr; 580534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 581534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 582534831adSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 583534831adSStefano Zampini Mat temp_mat; 5843972b0daSStefano Zampini IS dirIS; 5853972b0daSStefano Zampini PetscInt dirsize,i,*is_indices; 5863972b0daSStefano Zampini PetscScalar *array_x,*array_diagonal; 5873972b0daSStefano Zampini Vec used_vec; 5883972b0daSStefano Zampini PetscBool guess_nonzero; 589534831adSStefano Zampini 590534831adSStefano Zampini PetscFunctionBegin; 5913972b0daSStefano Zampini if (x) { 5923972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 5933972b0daSStefano Zampini used_vec = x; 5943972b0daSStefano Zampini } else { 5953972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 5963972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 5973972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 5983972b0daSStefano Zampini } 5993972b0daSStefano Zampini /* hack into ksp data structure PCPreSolve comes earlier in src/ksp/ksp/interface/itfunc.c */ 6003972b0daSStefano Zampini if (ksp) { 6013972b0daSStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&guess_nonzero);CHKERRQ(ierr); 6023972b0daSStefano Zampini if ( !guess_nonzero ) { 6033972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 6043972b0daSStefano Zampini } 6053972b0daSStefano Zampini } 6063972b0daSStefano Zampini /* store the original rhs */ 6073972b0daSStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 6083972b0daSStefano Zampini 6093972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 6103972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 6113972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 6123972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6133972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6143972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6153972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6163972b0daSStefano Zampini ierr = PCBDDCGetDirichletBoundaries(pc,&dirIS);CHKERRQ(ierr); 6173972b0daSStefano Zampini if (dirIS) { 6183972b0daSStefano Zampini ierr = ISGetSize(dirIS,&dirsize);CHKERRQ(ierr); 6193972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 6203972b0daSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 6213972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6222fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 6233972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6243972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 6253972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 6263972b0daSStefano Zampini } 6273972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6283972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 629b76ba322SStefano Zampini 6303972b0daSStefano Zampini /* remove the computed solution from the rhs */ 6313972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 6323972b0daSStefano Zampini ierr = MatMultAdd(pc->pmat,used_vec,rhs,rhs);CHKERRQ(ierr); 6333972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 634b76ba322SStefano Zampini 635b76ba322SStefano Zampini /* store partially computed solution and set initial guess */ 6363972b0daSStefano Zampini if (x) { 6373972b0daSStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 6383972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 639b76ba322SStefano Zampini if (pcbddc->use_exact_dirichlet) { 640b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 641b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 642b76ba322SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 643b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 644b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 645b76ba322SStefano Zampini if (ksp) { 646b76ba322SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 647b76ba322SStefano Zampini } 648b76ba322SStefano Zampini } 6493972b0daSStefano Zampini } 650b76ba322SStefano Zampini 651b76ba322SStefano Zampini /* rhs change of basis */ 652674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 653b76ba322SStefano Zampini /* swap pointers for local matrices */ 654b76ba322SStefano Zampini temp_mat = matis->A; 655b76ba322SStefano Zampini matis->A = pcbddc->local_mat; 656b76ba322SStefano Zampini pcbddc->local_mat = temp_mat; 657b76ba322SStefano Zampini /* Get local rhs and apply transformation of basis */ 658b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 659b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 660b76ba322SStefano Zampini /* from original basis to modified basis */ 661b76ba322SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 662b76ba322SStefano Zampini /* put back modified values into the global vec using INSERT_VALUES copy mode */ 663b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 664b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 665674ae819SStefano Zampini } 6660bdf917eSStefano Zampini if (ksp && pcbddc->NullSpace) { 6670298fd71SBarry Smith ierr = MatNullSpaceRemove(pcbddc->NullSpace,used_vec,NULL);CHKERRQ(ierr); 6680298fd71SBarry Smith ierr = MatNullSpaceRemove(pcbddc->NullSpace,rhs,NULL);CHKERRQ(ierr); 669b76ba322SStefano Zampini } 6700bdf917eSStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 671534831adSStefano Zampini PetscFunctionReturn(0); 672534831adSStefano Zampini } 673534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 674534831adSStefano Zampini #undef __FUNCT__ 675534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC" 676534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 677534831adSStefano Zampini /* 678534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 679534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 680534831adSStefano Zampini 681534831adSStefano Zampini Input Parameter: 682534831adSStefano Zampini + pc - the preconditioner contex 683534831adSStefano Zampini 684534831adSStefano Zampini Application Interface Routine: PCPostSolve() 685534831adSStefano Zampini 686534831adSStefano Zampini Notes: 687534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 688534831adSStefano Zampini the user, but instead is called by KSPSolve(). 689534831adSStefano Zampini */ 690534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 691534831adSStefano Zampini { 692534831adSStefano Zampini PetscErrorCode ierr; 693534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 694534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 695534831adSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 696534831adSStefano Zampini Mat temp_mat; 697534831adSStefano Zampini 698534831adSStefano Zampini PetscFunctionBegin; 699674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 700534831adSStefano Zampini /* swap pointers for local matrices */ 701534831adSStefano Zampini temp_mat = matis->A; 702534831adSStefano Zampini matis->A = pcbddc->local_mat; 703534831adSStefano Zampini pcbddc->local_mat = temp_mat; 704534831adSStefano Zampini /* restore rhs to its original state */ 7053425bc38SStefano Zampini if (rhs) { 7063425bc38SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,rhs);CHKERRQ(ierr); 7073425bc38SStefano Zampini } 708534831adSStefano Zampini /* Get Local boundary and apply transformation of basis to solution vector */ 709534831adSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 710534831adSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 711534831adSStefano Zampini /* from modified basis to original basis */ 712534831adSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 713534831adSStefano Zampini /* put back modified values into the global vec using INSERT_VALUES copy mode */ 714534831adSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 715534831adSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 716534831adSStefano Zampini } 7173972b0daSStefano Zampini /* add solution removed in presolve */ 7183425bc38SStefano Zampini if (x) { 7193425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 7203425bc38SStefano Zampini } 721534831adSStefano Zampini PetscFunctionReturn(0); 722534831adSStefano Zampini } 723534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 72453cdbc3dSStefano Zampini #undef __FUNCT__ 72553cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 7260c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 7270c7d97c5SJed Brown /* 7280c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 7290c7d97c5SJed Brown by setting data structures and options. 7300c7d97c5SJed Brown 7310c7d97c5SJed Brown Input Parameter: 73253cdbc3dSStefano Zampini + pc - the preconditioner context 7330c7d97c5SJed Brown 7340c7d97c5SJed Brown Application Interface Routine: PCSetUp() 7350c7d97c5SJed Brown 7360c7d97c5SJed Brown Notes: 7370c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 7380c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 7390c7d97c5SJed Brown */ 74053cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 7410c7d97c5SJed Brown { 7420c7d97c5SJed Brown PetscErrorCode ierr; 7430c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 744674ae819SStefano Zampini MatStructure flag; 745674ae819SStefano Zampini PetscBool computeis,computetopography,computesolvers; 7460c7d97c5SJed Brown 7470c7d97c5SJed Brown PetscFunctionBegin; 748674ae819SStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other nonoverlapping preconditioners */ 7493b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 7509c0446d6SStefano Zampini So, we set to pcnone the Neumann problem of pcis in order to avoid unneeded computation 7510c7d97c5SJed Brown Also, we decide to directly build the (same) Dirichlet problem */ 7520c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localN_pc_type","none");CHKERRQ(ierr); 7530c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localD_pc_type","none");CHKERRQ(ierr); 7543b03a366Sstefano_zampini /* Get stdout for dbg */ 755674ae819SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->dbg_viewer) { 756ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pc),&pcbddc->dbg_viewer);CHKERRQ(ierr); 757e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 758e269702eSStefano Zampini } 759674ae819SStefano Zampini /* first attempt to split work */ 760674ae819SStefano Zampini if (pc->setupcalled) { 761674ae819SStefano Zampini computeis = PETSC_FALSE; 762674ae819SStefano Zampini ierr = PCGetOperators(pc,NULL,NULL,&flag);CHKERRQ(ierr); 763674ae819SStefano Zampini if (flag == SAME_PRECONDITIONER) { 764674ae819SStefano Zampini computetopography = PETSC_FALSE; 765674ae819SStefano Zampini computesolvers = PETSC_FALSE; 766674ae819SStefano Zampini } else if (flag == SAME_NONZERO_PATTERN) { 767674ae819SStefano Zampini computetopography = PETSC_FALSE; 768674ae819SStefano Zampini computesolvers = PETSC_TRUE; 769674ae819SStefano Zampini } else { /* DIFFERENT_NONZERO_PATTERN */ 770674ae819SStefano Zampini computetopography = PETSC_TRUE; 771674ae819SStefano Zampini computesolvers = PETSC_TRUE; 772674ae819SStefano Zampini } 773674ae819SStefano Zampini } else { 774674ae819SStefano Zampini computeis = PETSC_TRUE; 775674ae819SStefano Zampini computetopography = PETSC_TRUE; 776674ae819SStefano Zampini computesolvers = PETSC_TRUE; 777674ae819SStefano Zampini } 778674ae819SStefano Zampini /* Set up all the "iterative substructuring" common block */ 779674ae819SStefano Zampini if (computeis) { 780674ae819SStefano Zampini ierr = PCISSetUp(pc);CHKERRQ(ierr); 781674ae819SStefano Zampini } 782674ae819SStefano Zampini /* Analyze interface and set up local constraint and change of basis matrices */ 783674ae819SStefano Zampini if (computetopography) { 784674ae819SStefano Zampini /* reset data */ 785674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 786674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 787674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 788674ae819SStefano Zampini } 789674ae819SStefano Zampini if (computesolvers) { 790674ae819SStefano Zampini /* reset data */ 791674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 792674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 7930c7d97c5SJed Brown /* Create coarse and local stuffs used for evaluating action of preconditioner */ 7940c7d97c5SJed Brown ierr = PCBDDCCoarseSetUp(pc);CHKERRQ(ierr); 795674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 7960c7d97c5SJed Brown } 7970c7d97c5SJed Brown PetscFunctionReturn(0); 7980c7d97c5SJed Brown } 7990c7d97c5SJed Brown 8000c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 8010c7d97c5SJed Brown /* 8020c7d97c5SJed Brown PCApply_BDDC - Applies the BDDC preconditioner to a vector. 8030c7d97c5SJed Brown 8040c7d97c5SJed Brown Input Parameters: 8050c7d97c5SJed Brown . pc - the preconditioner context 8060c7d97c5SJed Brown . r - input vector (global) 8070c7d97c5SJed Brown 8080c7d97c5SJed Brown Output Parameter: 8090c7d97c5SJed Brown . z - output vector (global) 8100c7d97c5SJed Brown 8110c7d97c5SJed Brown Application Interface Routine: PCApply() 8120c7d97c5SJed Brown */ 8130c7d97c5SJed Brown #undef __FUNCT__ 8140c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 81553cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 8160c7d97c5SJed Brown { 8170c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 8180c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 8190c7d97c5SJed Brown PetscErrorCode ierr; 8203b03a366Sstefano_zampini const PetscScalar one = 1.0; 8213b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 8222617d88aSStefano Zampini const PetscScalar zero = 0.0; 8230c7d97c5SJed Brown 8240c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 8250c7d97c5SJed Brown NN interface preconditioner changed to BDDC 82629622bf0SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->inexact_prec_type = PETSC_TRUE) */ 8270c7d97c5SJed Brown 8280c7d97c5SJed Brown PetscFunctionBegin; 829b76ba322SStefano Zampini if (!pcbddc->use_exact_dirichlet) { 8300c7d97c5SJed Brown /* First Dirichlet solve */ 8310c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8320c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 83353cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 8340c7d97c5SJed Brown /* 8350c7d97c5SJed Brown Assembling right hand side for BDDC operator 836674ae819SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE) 837674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 8380c7d97c5SJed Brown */ 8390c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 8400c7d97c5SJed Brown ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 84129622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 8420c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 8430c7d97c5SJed Brown ierr = VecCopy(r,z);CHKERRQ(ierr); 8440c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8450c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 846674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 847b76ba322SStefano Zampini } else { 8480bdf917eSStefano Zampini ierr = VecSet(pcis->vec1_D,zero);CHKERRQ(ierr); 849b76ba322SStefano Zampini ierr = VecSet(pcis->vec2_D,zero);CHKERRQ(ierr); 850674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 851b76ba322SStefano Zampini } 852b76ba322SStefano Zampini 8532617d88aSStefano Zampini /* Apply interface preconditioner 8542617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 8552617d88aSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc);CHKERRQ(ierr); 8562617d88aSStefano Zampini 857674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 858674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 8590c7d97c5SJed Brown 8603b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 8610c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8620c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8630c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 86429622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 86553cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr); 8660c7d97c5SJed Brown ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr); 86729622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); } 8680c7d97c5SJed Brown ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr); 8690c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8700c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8710c7d97c5SJed Brown PetscFunctionReturn(0); 8720c7d97c5SJed Brown } 873da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 874674ae819SStefano Zampini 875da1bb401SStefano Zampini #undef __FUNCT__ 876da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC" 877da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 878da1bb401SStefano Zampini { 879da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 880da1bb401SStefano Zampini PetscErrorCode ierr; 881da1bb401SStefano Zampini 882da1bb401SStefano Zampini PetscFunctionBegin; 883da1bb401SStefano Zampini /* free data created by PCIS */ 884da1bb401SStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 885674ae819SStefano Zampini /* free BDDC custom data */ 886674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 887674ae819SStefano Zampini /* destroy objects related to topography */ 888674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 889674ae819SStefano Zampini /* free allocated graph structure */ 890da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr); 891674ae819SStefano Zampini /* free data for scaling operator */ 892674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 893674ae819SStefano Zampini /* free solvers stuff */ 894674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 8953425bc38SStefano Zampini /* remove functions */ 896674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 897bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 898bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetMaxLevels_C",NULL);CHKERRQ(ierr); 899bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",NULL);CHKERRQ(ierr); 900bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 901bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 902bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 903bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 904bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseProblemType_C",NULL);CHKERRQ(ierr); 905bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 906bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 907bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 908bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 909bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 910674ae819SStefano Zampini /* Free the private data structure */ 911674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 912da1bb401SStefano Zampini PetscFunctionReturn(0); 913da1bb401SStefano Zampini } 9143425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 9151e6b0712SBarry Smith 9163425bc38SStefano Zampini #undef __FUNCT__ 9173425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC" 9183425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 9193425bc38SStefano Zampini { 920674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 9213425bc38SStefano Zampini PC_IS* pcis; 9223425bc38SStefano Zampini PC_BDDC* pcbddc; 9233425bc38SStefano Zampini PetscErrorCode ierr; 9240c7d97c5SJed Brown 9253425bc38SStefano Zampini PetscFunctionBegin; 9263425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 9273425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 9283425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 9293425bc38SStefano Zampini 9303425bc38SStefano Zampini /* change of basis for physical rhs if needed 9313425bc38SStefano Zampini It also changes the rhs in case of dirichlet boundaries */ 9320298fd71SBarry Smith (*mat_ctx->pc->ops->presolve)(mat_ctx->pc,NULL,standard_rhs,NULL); 9333425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 9343425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9353425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 936674ae819SStefano Zampini /* scale rhs since it should be unassembled : TODO use counter scaling? (also below) */ 9373425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9383425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 939674ae819SStefano Zampini /* Apply partition of unity */ 9403425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 941674ae819SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 94229622bf0SStefano Zampini if (!pcbddc->inexact_prec_type) { 9433425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 9443425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 9453425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 9463425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 9473425bc38SStefano Zampini ierr = VecSet(standard_rhs,0.0);CHKERRQ(ierr); 9483425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9493425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 950674ae819SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 9513425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9523425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9533425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 9543425bc38SStefano Zampini } 9553425bc38SStefano Zampini /* BDDC rhs */ 9563425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 95729622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { 9583425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 9593425bc38SStefano Zampini } 9603425bc38SStefano Zampini /* apply BDDC */ 9613425bc38SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr); 9623425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 9633425bc38SStefano Zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 9643425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 9653425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9663425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9673425bc38SStefano Zampini /* restore original rhs */ 9683425bc38SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,standard_rhs);CHKERRQ(ierr); 9693425bc38SStefano Zampini PetscFunctionReturn(0); 9703425bc38SStefano Zampini } 9711e6b0712SBarry Smith 9723425bc38SStefano Zampini #undef __FUNCT__ 9733425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS" 9743425bc38SStefano Zampini /*@ 9753425bc38SStefano Zampini PCBDDCMatFETIDPGetRHS - Get rhs for FETIDP linear system. 9763425bc38SStefano Zampini 9773425bc38SStefano Zampini Collective 9783425bc38SStefano Zampini 9793425bc38SStefano Zampini Input Parameters: 9803425bc38SStefano Zampini + fetidp_mat - the FETIDP mat obtained by a call to PCBDDCCreateFETIDPOperators 9813425bc38SStefano Zampini + standard_rhs - the rhs of your linear system 9823425bc38SStefano Zampini 9833425bc38SStefano Zampini Output Parameters: 9843425bc38SStefano Zampini + fetidp_flux_rhs - the rhs of the FETIDP linear system 9853425bc38SStefano Zampini 9863425bc38SStefano Zampini Level: developer 9873425bc38SStefano Zampini 9883425bc38SStefano Zampini Notes: 9893425bc38SStefano Zampini 9903425bc38SStefano Zampini .seealso: PCBDDC 9913425bc38SStefano Zampini @*/ 9923425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 9933425bc38SStefano Zampini { 994674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 9953425bc38SStefano Zampini PetscErrorCode ierr; 9963425bc38SStefano Zampini 9973425bc38SStefano Zampini PetscFunctionBegin; 9983425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 9993425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 10003425bc38SStefano Zampini PetscFunctionReturn(0); 10013425bc38SStefano Zampini } 10023425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 10031e6b0712SBarry Smith 10043425bc38SStefano Zampini #undef __FUNCT__ 10053425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC" 10063425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 10073425bc38SStefano Zampini { 1008674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 10093425bc38SStefano Zampini PC_IS* pcis; 10103425bc38SStefano Zampini PC_BDDC* pcbddc; 10113425bc38SStefano Zampini PetscErrorCode ierr; 10123425bc38SStefano Zampini 10133425bc38SStefano Zampini PetscFunctionBegin; 10143425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10153425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 10163425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 10173425bc38SStefano Zampini 10183425bc38SStefano Zampini /* apply B_delta^T */ 10193425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10203425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10213425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 10223425bc38SStefano Zampini /* compute rhs for BDDC application */ 10233425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 102429622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { 10253425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 10263425bc38SStefano Zampini } 10273425bc38SStefano Zampini /* apply BDDC */ 10283425bc38SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr); 10293425bc38SStefano Zampini /* put values into standard global vector */ 10303425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10313425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 103229622bf0SStefano Zampini if (!pcbddc->inexact_prec_type) { 10333425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 10343425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 10353425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_D,-1.0,pcis->vec1_D);CHKERRQ(ierr); 10363425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 10373425bc38SStefano Zampini } 10383425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10393425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10403425bc38SStefano Zampini /* final change of basis if needed 10413425bc38SStefano Zampini Is also sums the dirichlet part removed during RHS assembling */ 10420298fd71SBarry Smith (*mat_ctx->pc->ops->postsolve)(mat_ctx->pc,NULL,NULL,standard_sol); 10433425bc38SStefano Zampini PetscFunctionReturn(0); 10443425bc38SStefano Zampini 10453425bc38SStefano Zampini } 10461e6b0712SBarry Smith 10473425bc38SStefano Zampini #undef __FUNCT__ 10483425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution" 10493425bc38SStefano Zampini /*@ 10503425bc38SStefano Zampini PCBDDCMatFETIDPGetSolution - Get Solution for FETIDP linear system. 10513425bc38SStefano Zampini 10523425bc38SStefano Zampini Collective 10533425bc38SStefano Zampini 10543425bc38SStefano Zampini Input Parameters: 10553425bc38SStefano Zampini + fetidp_mat - the FETIDP mat obtained by a call to PCBDDCCreateFETIDPOperators 10563425bc38SStefano Zampini + fetidp_flux_sol - the solution of the FETIDP linear system 10573425bc38SStefano Zampini 10583425bc38SStefano Zampini Output Parameters: 10593425bc38SStefano Zampini + standard_sol - the solution on the global domain 10603425bc38SStefano Zampini 10613425bc38SStefano Zampini Level: developer 10623425bc38SStefano Zampini 10633425bc38SStefano Zampini Notes: 10643425bc38SStefano Zampini 10653425bc38SStefano Zampini .seealso: PCBDDC 10663425bc38SStefano Zampini @*/ 10673425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 10683425bc38SStefano Zampini { 1069674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 10703425bc38SStefano Zampini PetscErrorCode ierr; 10713425bc38SStefano Zampini 10723425bc38SStefano Zampini PetscFunctionBegin; 10733425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10743425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 10753425bc38SStefano Zampini PetscFunctionReturn(0); 10763425bc38SStefano Zampini } 10773425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 10781e6b0712SBarry Smith 1079f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec); 1080f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat); 1081f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec); 1082f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC); 1083674ae819SStefano Zampini 10843425bc38SStefano Zampini #undef __FUNCT__ 10853425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC" 10863425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 10873425bc38SStefano Zampini { 1088674ae819SStefano Zampini 1089674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 10903425bc38SStefano Zampini Mat newmat; 1091674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 10923425bc38SStefano Zampini PC newpc; 1093ce94432eSBarry Smith MPI_Comm comm; 10943425bc38SStefano Zampini PetscErrorCode ierr; 10953425bc38SStefano Zampini 10963425bc38SStefano Zampini PetscFunctionBegin; 1097ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 10983425bc38SStefano Zampini /* FETIDP linear matrix */ 10993425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 11003425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 11013425bc38SStefano Zampini ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 11023425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 11033425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 11043425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 11053425bc38SStefano Zampini /* FETIDP preconditioner */ 11063425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 11073425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 11083425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 11093425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 11103425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 11113425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 11123425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 11133425bc38SStefano Zampini ierr = PCSetOperators(newpc,newmat,newmat,SAME_PRECONDITIONER);CHKERRQ(ierr); 11143425bc38SStefano Zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 11153425bc38SStefano Zampini /* return pointers for objects created */ 11163425bc38SStefano Zampini *fetidp_mat=newmat; 11173425bc38SStefano Zampini *fetidp_pc=newpc; 11183425bc38SStefano Zampini PetscFunctionReturn(0); 11193425bc38SStefano Zampini } 11201e6b0712SBarry Smith 11213425bc38SStefano Zampini #undef __FUNCT__ 11223425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators" 11233425bc38SStefano Zampini /*@ 11243425bc38SStefano Zampini PCBDDCCreateFETIDPOperators - Create operators for FETIDP. 11253425bc38SStefano Zampini 11263425bc38SStefano Zampini Collective 11273425bc38SStefano Zampini 11283425bc38SStefano Zampini Input Parameters: 11293425bc38SStefano Zampini + pc - the BDDC preconditioning context (setup must be already called) 11303425bc38SStefano Zampini 11313425bc38SStefano Zampini Level: developer 11323425bc38SStefano Zampini 11333425bc38SStefano Zampini Notes: 11343425bc38SStefano Zampini 11353425bc38SStefano Zampini .seealso: PCBDDC 11363425bc38SStefano Zampini @*/ 11373425bc38SStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 11383425bc38SStefano Zampini { 11393425bc38SStefano Zampini PetscErrorCode ierr; 11403425bc38SStefano Zampini 11413425bc38SStefano Zampini PetscFunctionBegin; 11423425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 11433425bc38SStefano Zampini if (pc->setupcalled) { 11443425bc38SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,Mat*,PC*),(pc,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 1145f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n"); 11463425bc38SStefano Zampini PetscFunctionReturn(0); 11473425bc38SStefano Zampini } 11480c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1149da1bb401SStefano Zampini /*MC 1150da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 11510c7d97c5SJed Brown 1152da1bb401SStefano Zampini Options Database Keys: 1153da1bb401SStefano Zampini . -pcbddc ??? - 1154da1bb401SStefano Zampini 1155da1bb401SStefano Zampini Level: intermediate 1156da1bb401SStefano Zampini 1157da1bb401SStefano Zampini Notes: The matrix used with this preconditioner must be of type MATIS 1158da1bb401SStefano Zampini 1159da1bb401SStefano Zampini Unlike more 'conventional' interface preconditioners, this iterates over ALL the 1160da1bb401SStefano Zampini degrees of freedom, NOT just those on the interface (this allows the use of approximate solvers 1161da1bb401SStefano Zampini on the subdomains). 1162da1bb401SStefano Zampini 1163da1bb401SStefano Zampini Options for the coarse grid preconditioner can be set with - 1164da1bb401SStefano Zampini Options for the Dirichlet subproblem can be set with - 1165da1bb401SStefano Zampini Options for the Neumann subproblem can be set with - 1166da1bb401SStefano Zampini 1167da1bb401SStefano Zampini Contributed by Stefano Zampini 1168da1bb401SStefano Zampini 1169da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 1170da1bb401SStefano Zampini M*/ 1171b2573a8aSBarry Smith 1172da1bb401SStefano Zampini #undef __FUNCT__ 1173da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC" 11748cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 1175da1bb401SStefano Zampini { 1176da1bb401SStefano Zampini PetscErrorCode ierr; 1177da1bb401SStefano Zampini PC_BDDC *pcbddc; 1178da1bb401SStefano Zampini 1179da1bb401SStefano Zampini PetscFunctionBegin; 1180da1bb401SStefano Zampini /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 1181da1bb401SStefano Zampini ierr = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr); 1182da1bb401SStefano Zampini pc->data = (void*)pcbddc; 1183da1bb401SStefano Zampini 1184da1bb401SStefano Zampini /* create PCIS data structure */ 1185da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 1186da1bb401SStefano Zampini 1187da1bb401SStefano Zampini /* BDDC specific */ 1188674ae819SStefano Zampini pcbddc->user_primal_vertices = 0; 11890bdf917eSStefano Zampini pcbddc->NullSpace = 0; 11903972b0daSStefano Zampini pcbddc->temp_solution = 0; 1191534831adSStefano Zampini pcbddc->original_rhs = 0; 1192534831adSStefano Zampini pcbddc->local_mat = 0; 1193534831adSStefano Zampini pcbddc->ChangeOfBasisMatrix = 0; 1194674ae819SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 1195674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 1196da1bb401SStefano Zampini pcbddc->coarse_vec = 0; 1197da1bb401SStefano Zampini pcbddc->coarse_rhs = 0; 1198da1bb401SStefano Zampini pcbddc->coarse_ksp = 0; 1199da1bb401SStefano Zampini pcbddc->coarse_phi_B = 0; 1200da1bb401SStefano Zampini pcbddc->coarse_phi_D = 0; 1201da1bb401SStefano Zampini pcbddc->vec1_P = 0; 1202da1bb401SStefano Zampini pcbddc->vec1_R = 0; 1203da1bb401SStefano Zampini pcbddc->vec2_R = 0; 1204da1bb401SStefano Zampini pcbddc->local_auxmat1 = 0; 1205da1bb401SStefano Zampini pcbddc->local_auxmat2 = 0; 1206da1bb401SStefano Zampini pcbddc->R_to_B = 0; 1207da1bb401SStefano Zampini pcbddc->R_to_D = 0; 1208da1bb401SStefano Zampini pcbddc->ksp_D = 0; 1209da1bb401SStefano Zampini pcbddc->ksp_R = 0; 1210da1bb401SStefano Zampini pcbddc->local_primal_indices = 0; 121129622bf0SStefano Zampini pcbddc->inexact_prec_type = PETSC_FALSE; 1212da1bb401SStefano Zampini pcbddc->NeumannBoundaries = 0; 1213da1bb401SStefano Zampini pcbddc->ISForDofs = 0; 1214da1bb401SStefano Zampini pcbddc->ConstraintMatrix = 0; 1215da1bb401SStefano Zampini pcbddc->use_nnsp_true = PETSC_FALSE; 1216da1bb401SStefano Zampini pcbddc->local_primal_sizes = 0; 1217da1bb401SStefano Zampini pcbddc->local_primal_displacements = 0; 1218da1bb401SStefano Zampini pcbddc->coarse_loc_to_glob = 0; 1219da1bb401SStefano Zampini pcbddc->dbg_flag = PETSC_FALSE; 1220da1bb401SStefano Zampini pcbddc->coarsening_ratio = 8; 1221b76ba322SStefano Zampini pcbddc->use_exact_dirichlet = PETSC_TRUE; 12224fad6a16SStefano Zampini pcbddc->current_level = 0; 12234fad6a16SStefano Zampini pcbddc->max_levels = 1; 1224674ae819SStefano Zampini pcbddc->replicated_local_primal_indices = 0; 1225674ae819SStefano Zampini pcbddc->replicated_local_primal_values = 0; 1226da1bb401SStefano Zampini 1227674ae819SStefano Zampini /* create local graph structure */ 1228674ae819SStefano Zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 1229674ae819SStefano Zampini 1230674ae819SStefano Zampini /* scaling */ 1231674ae819SStefano Zampini pcbddc->use_deluxe_scaling = PETSC_FALSE; 1232674ae819SStefano Zampini pcbddc->work_scaling = 0; 1233da1bb401SStefano Zampini 1234da1bb401SStefano Zampini /* function pointers */ 1235da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 1236da1bb401SStefano Zampini pc->ops->applytranspose = 0; 1237da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 1238da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 1239da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 1240da1bb401SStefano Zampini pc->ops->view = 0; 1241da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 1242da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 1243da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 1244534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 1245534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 1246da1bb401SStefano Zampini 1247da1bb401SStefano Zampini /* composing function */ 1248674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 1249bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 1250bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetMaxLevels_C",PCBDDCSetMaxLevels_BDDC);CHKERRQ(ierr); 1251bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",PCBDDCSetNullSpace_BDDC);CHKERRQ(ierr); 1252bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 1253bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 1254bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 1255bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 1256bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseProblemType_C",PCBDDCSetCoarseProblemType_BDDC);CHKERRQ(ierr); 1257bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 1258bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 1259bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 1260bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 1261bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 1262da1bb401SStefano Zampini PetscFunctionReturn(0); 1263da1bb401SStefano Zampini } 12643425bc38SStefano Zampini 1265da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 1266da1bb401SStefano Zampini /* All static functions from now on */ 1267da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 126829622bf0SStefano Zampini 126929622bf0SStefano Zampini #undef __FUNCT__ 12702e8d2280SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet" 12712e8d2280SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool use) 12722e8d2280SStefano Zampini { 12732e8d2280SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 12742e8d2280SStefano Zampini 12752e8d2280SStefano Zampini PetscFunctionBegin; 12762e8d2280SStefano Zampini pcbddc->use_exact_dirichlet=use; 12772e8d2280SStefano Zampini PetscFunctionReturn(0); 12782e8d2280SStefano Zampini } 12792e8d2280SStefano Zampini 12802e8d2280SStefano Zampini #undef __FUNCT__ 12814fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel" 12824fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 12834fad6a16SStefano Zampini { 12844fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 12854fad6a16SStefano Zampini 12864fad6a16SStefano Zampini PetscFunctionBegin; 12874fad6a16SStefano Zampini pcbddc->current_level=level; 12884fad6a16SStefano Zampini PetscFunctionReturn(0); 12894fad6a16SStefano Zampini } 12903425bc38SStefano Zampini 12913b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 12920c7d97c5SJed Brown #undef __FUNCT__ 12930c7d97c5SJed Brown #define __FUNCT__ "PCBDDCCoarseSetUp" 129453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC pc) 12950c7d97c5SJed Brown { 12960c7d97c5SJed Brown PetscErrorCode ierr; 1297674ae819SStefano Zampini 12980c7d97c5SJed Brown PC_IS* pcis = (PC_IS*)(pc->data); 12990c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 13000c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1301534831adSStefano Zampini Mat change_mat_all; 13020c7d97c5SJed Brown IS is_R_local; 13030c7d97c5SJed Brown IS is_V_local; 13040c7d97c5SJed Brown IS is_C_local; 13050c7d97c5SJed Brown IS is_aux1; 13060c7d97c5SJed Brown IS is_aux2; 130719fd82e9SBarry Smith VecType impVecType; 130819fd82e9SBarry Smith MatType impMatType; 13090c7d97c5SJed Brown PetscInt n_R=0; 13100c7d97c5SJed Brown PetscInt n_D=0; 13110c7d97c5SJed Brown PetscInt n_B=0; 13120c7d97c5SJed Brown PetscScalar zero=0.0; 13130c7d97c5SJed Brown PetscScalar one=1.0; 13140c7d97c5SJed Brown PetscScalar m_one=-1.0; 13150c7d97c5SJed Brown PetscScalar* array; 13160c7d97c5SJed Brown PetscScalar *coarse_submat_vals; 13170c7d97c5SJed Brown PetscInt *idx_R_local; 13180c7d97c5SJed Brown PetscInt *idx_V_B; 13190c7d97c5SJed Brown PetscScalar *coarsefunctions_errors; 13200c7d97c5SJed Brown PetscScalar *constraints_errors; 13210c7d97c5SJed Brown /* auxiliary indices */ 1322534831adSStefano Zampini PetscInt i,j,k; 1323e269702eSStefano Zampini /* for verbose output of bddc */ 1324e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 1325e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 1326a0ba757dSStefano Zampini /* for counting coarse dofs */ 1327534831adSStefano Zampini PetscInt n_vertices,n_constraints; 13283b03a366Sstefano_zampini PetscInt size_of_constraint; 13293b03a366Sstefano_zampini PetscInt *row_cmat_indices; 13303b03a366Sstefano_zampini PetscScalar *row_cmat_values; 1331534831adSStefano Zampini PetscInt *vertices,*nnz,*is_indices,*temp_indices; 1332674ae819SStefano Zampini ISLocalToGlobalMapping BtoNmap; 13330c7d97c5SJed Brown 13340c7d97c5SJed Brown PetscFunctionBegin; 13350c7d97c5SJed Brown /* Set Non-overlapping dimensions */ 13360c7d97c5SJed Brown n_B = pcis->n_B; n_D = pcis->n - n_B; 1337534831adSStefano Zampini /* Set types for local objects needed by BDDC precondtioner */ 1338534831adSStefano Zampini impMatType = MATSEQDENSE; 1339534831adSStefano Zampini impVecType = VECSEQ; 1340da1bb401SStefano Zampini /* get vertex indices from constraint matrix */ 1341674ae819SStefano Zampini ierr = PCBDDCGetPrimalVerticesLocalIdx(pc,&n_vertices,&vertices);CHKERRQ(ierr); 1342534831adSStefano Zampini /* Set number of constraints */ 1343534831adSStefano Zampini n_constraints = pcbddc->local_primal_size-n_vertices; 1344534831adSStefano Zampini 1345534831adSStefano Zampini /* vertices in boundary numbering */ 1346534831adSStefano Zampini ierr = PetscMalloc(n_vertices*sizeof(PetscInt),&idx_V_B);CHKERRQ(ierr); 1347674ae819SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_B_local,&BtoNmap);CHKERRQ(ierr); 1348674ae819SStefano Zampini ierr = ISGlobalToLocalMappingApply(BtoNmap,IS_GTOLM_DROP,n_vertices,vertices,&i,idx_V_B);CHKERRQ(ierr); 1349674ae819SStefano Zampini if (i != n_vertices) { 1350674ae819SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",n_vertices,i); 1351534831adSStefano Zampini } 1352534831adSStefano Zampini 1353534831adSStefano Zampini /* transform local matrices if needed */ 1354674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 1355534831adSStefano Zampini ierr = PetscMalloc(pcis->n*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 1356534831adSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 13572fa5cd67SKarl Rupp for (i=0;i<n_D;i++) nnz[is_indices[i]] = 1; 1358534831adSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1359534831adSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1360534831adSStefano Zampini k=1; 1361534831adSStefano Zampini for (i=0;i<n_B;i++) { 13620298fd71SBarry Smith ierr = MatGetRow(pcbddc->ChangeOfBasisMatrix,i,&j,NULL,NULL);CHKERRQ(ierr); 1363534831adSStefano Zampini nnz[is_indices[i]]=j; 13642fa5cd67SKarl Rupp if (k < j) k = j; 13650298fd71SBarry Smith ierr = MatRestoreRow(pcbddc->ChangeOfBasisMatrix,i,&j,NULL,NULL);CHKERRQ(ierr); 1366534831adSStefano Zampini } 1367534831adSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1368534831adSStefano Zampini /* assemble change of basis matrix on the whole set of local dofs */ 1369534831adSStefano Zampini ierr = PetscMalloc(k*sizeof(PetscInt),&temp_indices);CHKERRQ(ierr); 1370534831adSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&change_mat_all);CHKERRQ(ierr); 1371534831adSStefano Zampini ierr = MatSetSizes(change_mat_all,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 1372534831adSStefano Zampini ierr = MatSetType(change_mat_all,MATSEQAIJ);CHKERRQ(ierr); 1373534831adSStefano Zampini ierr = MatSeqAIJSetPreallocation(change_mat_all,0,nnz);CHKERRQ(ierr); 1374534831adSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1375534831adSStefano Zampini for (i=0;i<n_D;i++) { 1376534831adSStefano Zampini ierr = MatSetValue(change_mat_all,is_indices[i],is_indices[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 1377534831adSStefano Zampini } 1378534831adSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1379534831adSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1380534831adSStefano Zampini for (i=0;i<n_B;i++) { 1381534831adSStefano Zampini ierr = MatGetRow(pcbddc->ChangeOfBasisMatrix,i,&j,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 13822fa5cd67SKarl Rupp for (k=0; k<j; k++) temp_indices[k]=is_indices[row_cmat_indices[k]]; 1383534831adSStefano Zampini ierr = MatSetValues(change_mat_all,1,&is_indices[i],j,temp_indices,row_cmat_values,INSERT_VALUES);CHKERRQ(ierr); 1384534831adSStefano Zampini ierr = MatRestoreRow(pcbddc->ChangeOfBasisMatrix,i,&j,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 1385534831adSStefano Zampini } 1386534831adSStefano Zampini ierr = MatAssemblyBegin(change_mat_all,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1387534831adSStefano Zampini ierr = MatAssemblyEnd(change_mat_all,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1388*5ce978abSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ? PtAP not provided */ 1389*5ce978abSStefano Zampini ierr = MatGetBlockSize(matis->A,&i);CHKERRQ(ierr); 1390*5ce978abSStefano Zampini if (i==1) { 1391534831adSStefano Zampini ierr = MatPtAP(matis->A,change_mat_all,MAT_INITIAL_MATRIX,1.0,&pcbddc->local_mat);CHKERRQ(ierr); 1392*5ce978abSStefano Zampini } else { 1393*5ce978abSStefano Zampini Mat work_mat; 1394*5ce978abSStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 1395*5ce978abSStefano Zampini ierr = MatPtAP(work_mat,change_mat_all,MAT_INITIAL_MATRIX,1.0,&pcbddc->local_mat);CHKERRQ(ierr); 1396*5ce978abSStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 1397*5ce978abSStefano Zampini } 1398534831adSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 1399534831adSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 1400534831adSStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 1401534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 1402534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 1403534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 1404534831adSStefano Zampini ierr = MatDestroy(&change_mat_all);CHKERRQ(ierr); 1405534831adSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 1406534831adSStefano Zampini ierr = PetscFree(temp_indices);CHKERRQ(ierr); 1407534831adSStefano Zampini } else { 1408534831adSStefano Zampini /* without change of basis, the local matrix is unchanged */ 1409534831adSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 1410534831adSStefano Zampini pcbddc->local_mat = matis->A; 1411534831adSStefano Zampini } 1412674ae819SStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 1413674ae819SStefano Zampini if (pcbddc->NullSpace && pcbddc->use_change_of_basis) { 1414674ae819SStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 14150bdf917eSStefano Zampini } 1416a0ba757dSStefano Zampini 14170c7d97c5SJed Brown /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 14180c7d97c5SJed Brown ierr = VecSet(pcis->vec1_N,one);CHKERRQ(ierr); 14190c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14202fa5cd67SKarl Rupp for (i=0;i<n_vertices;i++) array[vertices[i]] = zero; 14213b03a366Sstefano_zampini ierr = PetscMalloc(( pcis->n - n_vertices )*sizeof(PetscInt),&idx_R_local);CHKERRQ(ierr); 14222fa5cd67SKarl Rupp for (i=0, n_R=0; i<pcis->n; i++) { 14232fa5cd67SKarl Rupp if (array[i] == one) { 14242fa5cd67SKarl Rupp idx_R_local[n_R] = i; 14252fa5cd67SKarl Rupp n_R++; 14262fa5cd67SKarl Rupp } 14272fa5cd67SKarl Rupp } 14280c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1429e269702eSStefano Zampini if (dbg_flag) { 14300c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 14310c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14320c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 14330c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 14343b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"r_size = %d, v_size = %d, constraints = %d, local_primal_size = %d\n",n_R,n_vertices,n_constraints,pcbddc->local_primal_size);CHKERRQ(ierr); 1435534831adSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"pcbddc->n_vertices = %d, pcbddc->n_constraints = %d\n",pcbddc->n_vertices,pcbddc->n_constraints);CHKERRQ(ierr); 14360c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14370c7d97c5SJed Brown } 1438534831adSStefano Zampini 14390c7d97c5SJed Brown /* Allocate needed vectors */ 1440534831adSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 14413972b0daSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 14420c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_D,&pcbddc->vec4_D);CHKERRQ(ierr); 14430c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_R);CHKERRQ(ierr); 14440c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_R,n_R,n_R);CHKERRQ(ierr); 14450c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 1446d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 14470c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_P);CHKERRQ(ierr); 14480c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_P,pcbddc->local_primal_size,pcbddc->local_primal_size);CHKERRQ(ierr); 14490c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 14500c7d97c5SJed Brown 14510c7d97c5SJed Brown /* Creating some index sets needed */ 14520c7d97c5SJed Brown /* For submatrices */ 1453da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n_R,idx_R_local,PETSC_OWN_POINTER,&is_R_local);CHKERRQ(ierr); 14543b03a366Sstefano_zampini if (n_vertices) { 1455da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n_vertices,vertices,PETSC_OWN_POINTER,&is_V_local);CHKERRQ(ierr); 14563b03a366Sstefano_zampini } 1457da1bb401SStefano Zampini if (n_constraints) { 1458da1bb401SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_C_local);CHKERRQ(ierr); 1459da1bb401SStefano Zampini } 1460da1bb401SStefano Zampini 14610c7d97c5SJed Brown /* For VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 14620c7d97c5SJed Brown { 14630c7d97c5SJed Brown PetscInt *aux_array1; 14640c7d97c5SJed Brown PetscInt *aux_array2; 14652e8d2280SStefano Zampini PetscInt *idx_I_local; 14660c7d97c5SJed Brown 14673b03a366Sstefano_zampini ierr = PetscMalloc( (pcis->n_B-n_vertices)*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 14683b03a366Sstefano_zampini ierr = PetscMalloc( (pcis->n_B-n_vertices)*sizeof(PetscInt),&aux_array2);CHKERRQ(ierr); 14690c7d97c5SJed Brown 14702e8d2280SStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&idx_I_local);CHKERRQ(ierr); 14710c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14722fa5cd67SKarl Rupp for (i=0; i<n_D; i++) array[idx_I_local[i]] = 0; 14732e8d2280SStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&idx_I_local);CHKERRQ(ierr); 14742fa5cd67SKarl Rupp for (i=0, j=0; i<n_R; i++) { 14752fa5cd67SKarl Rupp if (array[idx_R_local[i]] == one) { 14762fa5cd67SKarl Rupp aux_array1[j] = i; 14772fa5cd67SKarl Rupp j++; 14782fa5cd67SKarl Rupp } 14792fa5cd67SKarl Rupp } 14800c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1481da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 14822e8d2280SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14832e8d2280SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14840c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 14852fa5cd67SKarl Rupp for (i=0, j=0; i<n_B; i++) { 14862fa5cd67SKarl Rupp if (array[i] == one) { 14872fa5cd67SKarl Rupp aux_array2[j] = i; j++; 14882fa5cd67SKarl Rupp } 14892fa5cd67SKarl Rupp } 14903828260eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1491da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_COPY_VALUES,&is_aux2);CHKERRQ(ierr); 14920c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 14930c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 14940c7d97c5SJed Brown ierr = PetscFree(aux_array2);CHKERRQ(ierr); 14950c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 14960c7d97c5SJed Brown ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 14970c7d97c5SJed Brown 149829622bf0SStefano Zampini if (pcbddc->inexact_prec_type || dbg_flag ) { 14990c7d97c5SJed Brown ierr = PetscMalloc(n_D*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 15000c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 15012fa5cd67SKarl Rupp for (i=0, j=0; i<n_R; i++) { 15022fa5cd67SKarl Rupp if (array[idx_R_local[i]] == zero) { 15032fa5cd67SKarl Rupp aux_array1[j] = i; 15042fa5cd67SKarl Rupp j++; 15052fa5cd67SKarl Rupp } 15062fa5cd67SKarl Rupp } 15070c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1508da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 15090c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 15100c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 15110c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 15120c7d97c5SJed Brown } 15130c7d97c5SJed Brown } 15140c7d97c5SJed Brown 15150c7d97c5SJed Brown /* Creating PC contexts for local Dirichlet and Neumann problems */ 15160c7d97c5SJed Brown { 15170c7d97c5SJed Brown Mat A_RR; 151853cdbc3dSStefano Zampini PC pc_temp; 1519674ae819SStefano Zampini MatStructure matstruct; 1520674ae819SStefano Zampini /* Matrix for Dirichlet problem is A_II */ 1521674ae819SStefano Zampini /* HACK (TODO) A_II can be changed between nonlinear iterations */ 1522674ae819SStefano Zampini ierr = PCGetOperators(pc,NULL,NULL,&matstruct);CHKERRQ(ierr); 1523674ae819SStefano Zampini if (matstruct == SAME_NONZERO_PATTERN) { 1524674ae819SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_I_local,MAT_REUSE_MATRIX,&pcis->A_II);CHKERRQ(ierr); 1525674ae819SStefano Zampini } else { 1526674ae819SStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 1527674ae819SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_II);CHKERRQ(ierr); 1528674ae819SStefano Zampini } 152953cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 153053cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 153153cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II,SAME_PRECONDITIONER);CHKERRQ(ierr); 153253cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 1533da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,"dirichlet_");CHKERRQ(ierr); 15340c7d97c5SJed Brown /* default */ 153553cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 153653cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 15370c7d97c5SJed Brown /* Allow user's customization */ 153853cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 1539950d796eSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero */ 1540950d796eSStefano Zampini if (!n_D) { 15412e8d2280SStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 1542950d796eSStefano Zampini } 154353cdbc3dSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 154453cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 15453972b0daSStefano Zampini /* set ksp_D into pcis data */ 15463972b0daSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 15473972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 15483972b0daSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 15490c7d97c5SJed Brown /* Matrix for Neumann problem is A_RR -> we need to create it */ 1550534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_R_local,is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 155153cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 155253cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 155353cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR,SAME_PRECONDITIONER);CHKERRQ(ierr); 155453cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 1555da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,"neumann_");CHKERRQ(ierr); 15560c7d97c5SJed Brown /* default */ 155753cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 155853cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 15590c7d97c5SJed Brown /* Allow user's customization */ 156053cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 1561950d796eSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero */ 1562674ae819SStefano Zampini if (!n_R) { 15632e8d2280SStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 1564950d796eSStefano Zampini } 156553cdbc3dSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 156653cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 1567674ae819SStefano Zampini /* check Dirichlet and Neumann solvers and adapt them if a nullspace correction is needed */ 1568b76ba322SStefano Zampini { 15690c7d97c5SJed Brown Vec temp_vec; 1570b76ba322SStefano Zampini PetscReal value; 1571b76ba322SStefano Zampini PetscMPIInt use_exact,use_exact_reduced; 15720c7d97c5SJed Brown 1573a0ba757dSStefano Zampini ierr = VecDuplicate(pcis->vec1_D,&temp_vec);CHKERRQ(ierr); 15740298fd71SBarry Smith ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 1575a0ba757dSStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 1576a0ba757dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,temp_vec);CHKERRQ(ierr); 1577a0ba757dSStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcis->vec1_D);CHKERRQ(ierr); 1578a0ba757dSStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 157929622bf0SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1580b76ba322SStefano Zampini use_exact = 1; 15812fa5cd67SKarl Rupp if (PetscAbsReal(value) > 1.e-4) use_exact = 0; 15822fa5cd67SKarl Rupp 1583ce94432eSBarry Smith ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_INT,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1584b76ba322SStefano Zampini pcbddc->use_exact_dirichlet = (PetscBool) use_exact_reduced; 1585b76ba322SStefano Zampini if (dbg_flag) { 1586a0ba757dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1587a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1588a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Checking solution of Dirichlet and Neumann problems\n");CHKERRQ(ierr); 1589a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Dirichlet solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 1590674ae819SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 159129622bf0SStefano Zampini } 1592674ae819SStefano Zampini if (n_D && pcbddc->NullSpace && !use_exact_reduced && !pcbddc->inexact_prec_type) { 1593674ae819SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,pcis->is_I_local); 159429622bf0SStefano Zampini } 1595d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&temp_vec);CHKERRQ(ierr); 15960298fd71SBarry Smith ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 1597d49ef151SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 1598d49ef151SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,temp_vec);CHKERRQ(ierr); 1599d49ef151SStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 1600d49ef151SStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 1601e269702eSStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 160229622bf0SStefano Zampini use_exact = 1; 16032fa5cd67SKarl Rupp if (PetscAbsReal(value) > 1.e-4) use_exact = 0; 1604ce94432eSBarry Smith ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_INT,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 160529622bf0SStefano Zampini if (dbg_flag) { 16060c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Neumann solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 1607d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 16080c7d97c5SJed Brown } 1609674ae819SStefano Zampini if (n_R && pcbddc->NullSpace && !use_exact_reduced) { 1610674ae819SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,is_R_local); 161129622bf0SStefano Zampini } 1612b76ba322SStefano Zampini } 16130c7d97c5SJed Brown /* free Neumann problem's matrix */ 16140c7d97c5SJed Brown ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 16150c7d97c5SJed Brown } 16160c7d97c5SJed Brown 16170c7d97c5SJed Brown /* Assemble all remaining stuff needed to apply BDDC */ 16180c7d97c5SJed Brown { 16190c7d97c5SJed Brown Mat A_RV,A_VR,A_VV; 16200bdf917eSStefano Zampini Mat M1; 16210c7d97c5SJed Brown Mat C_CR; 16223b03a366Sstefano_zampini Mat AUXMAT; 16230c7d97c5SJed Brown Vec vec1_C; 16240c7d97c5SJed Brown Vec vec2_C; 16250c7d97c5SJed Brown Vec vec1_V; 16260c7d97c5SJed Brown Vec vec2_V; 16270c7d97c5SJed Brown PetscInt *nnz; 16280c7d97c5SJed Brown PetscInt *auxindices; 162953cdbc3dSStefano Zampini PetscInt index; 16300c7d97c5SJed Brown PetscScalar* array2; 16310c7d97c5SJed Brown MatFactorInfo matinfo; 16320c7d97c5SJed Brown 16330c7d97c5SJed Brown /* Allocating some extra storage just to be safe */ 16340c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 16350c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&auxindices);CHKERRQ(ierr); 16362fa5cd67SKarl Rupp for (i=0;i<pcis->n;i++) auxindices[i]=i; 16370c7d97c5SJed Brown 16380c7d97c5SJed Brown /* some work vectors on vertices and/or constraints */ 16393b03a366Sstefano_zampini if (n_vertices) { 16400c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_V);CHKERRQ(ierr); 16413b03a366Sstefano_zampini ierr = VecSetSizes(vec1_V,n_vertices,n_vertices);CHKERRQ(ierr); 16420c7d97c5SJed Brown ierr = VecSetType(vec1_V,impVecType);CHKERRQ(ierr); 16430c7d97c5SJed Brown ierr = VecDuplicate(vec1_V,&vec2_V);CHKERRQ(ierr); 16440c7d97c5SJed Brown } 1645534831adSStefano Zampini if (n_constraints) { 16460c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_C);CHKERRQ(ierr); 1647534831adSStefano Zampini ierr = VecSetSizes(vec1_C,n_constraints,n_constraints);CHKERRQ(ierr); 16480c7d97c5SJed Brown ierr = VecSetType(vec1_C,impVecType);CHKERRQ(ierr); 16490c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&vec2_C);CHKERRQ(ierr); 16500c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&pcbddc->vec1_C);CHKERRQ(ierr); 16510c7d97c5SJed Brown } 16520c7d97c5SJed Brown /* Precompute stuffs needed for preprocessing and application of BDDC*/ 16533b03a366Sstefano_zampini if (n_constraints) { 16540c7d97c5SJed Brown ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->local_auxmat2);CHKERRQ(ierr); 16553b03a366Sstefano_zampini ierr = MatSetSizes(pcbddc->local_auxmat2,n_R,n_constraints,n_R,n_constraints);CHKERRQ(ierr); 16560c7d97c5SJed Brown ierr = MatSetType(pcbddc->local_auxmat2,impMatType);CHKERRQ(ierr); 16570298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(pcbddc->local_auxmat2,NULL);CHKERRQ(ierr); 16580c7d97c5SJed Brown 165957a90decSStefano Zampini /* Create Constraint matrix on R nodes: C_{CR} */ 166057a90decSStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_C_local,is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 166157a90decSStefano Zampini ierr = ISDestroy(&is_C_local);CHKERRQ(ierr); 166257a90decSStefano Zampini 16630c7d97c5SJed Brown /* Assemble local_auxmat2 = - A_{RR}^{-1} C^T_{CR} needed by BDDC application */ 16643b03a366Sstefano_zampini for (i=0;i<n_constraints;i++) { 16653b03a366Sstefano_zampini ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 16663b03a366Sstefano_zampini /* Get row of constraint matrix in R numbering */ 166757a90decSStefano Zampini ierr = VecGetArray(pcbddc->vec1_R,&array);CHKERRQ(ierr); 166857a90decSStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 16692fa5cd67SKarl Rupp for (j=0;j<size_of_constraint;j++) array[row_cmat_indices[j]] = -row_cmat_values[j]; 167057a90decSStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 167157a90decSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_R,&array);CHKERRQ(ierr); 16722fa5cd67SKarl Rupp 16733b03a366Sstefano_zampini /* Solve for row of constraint matrix in R numbering */ 167453cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 16752fa5cd67SKarl Rupp 16763b03a366Sstefano_zampini /* Set values */ 16770c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 16783b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->local_auxmat2,n_R,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 16790c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 16800c7d97c5SJed Brown } 16810c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16820c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16830c7d97c5SJed Brown 16840c7d97c5SJed Brown /* Assemble AUXMAT = ( LUFactor )( -C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 16850c7d97c5SJed Brown ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AUXMAT);CHKERRQ(ierr); 1686d49ef151SStefano Zampini ierr = MatFactorInfoInitialize(&matinfo);CHKERRQ(ierr); 16873b03a366Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,0,1,&is_aux1);CHKERRQ(ierr); 16880c7d97c5SJed Brown ierr = MatLUFactor(AUXMAT,is_aux1,is_aux1,&matinfo);CHKERRQ(ierr); 16890c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 16900c7d97c5SJed Brown 16913b03a366Sstefano_zampini /* Assemble explicitly M1 = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} needed in preproc */ 1692d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M1);CHKERRQ(ierr); 16933b03a366Sstefano_zampini ierr = MatSetSizes(M1,n_constraints,n_constraints,n_constraints,n_constraints);CHKERRQ(ierr); 16940c7d97c5SJed Brown ierr = MatSetType(M1,impMatType);CHKERRQ(ierr); 16950298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(M1,NULL);CHKERRQ(ierr); 16963b03a366Sstefano_zampini for (i=0;i<n_constraints;i++) { 16970c7d97c5SJed Brown ierr = VecSet(vec1_C,zero);CHKERRQ(ierr); 16980c7d97c5SJed Brown ierr = VecSetValue(vec1_C,i,one,INSERT_VALUES);CHKERRQ(ierr); 16990c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_C);CHKERRQ(ierr); 17000c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_C);CHKERRQ(ierr); 17010c7d97c5SJed Brown ierr = MatSolve(AUXMAT,vec1_C,vec2_C);CHKERRQ(ierr); 17020c7d97c5SJed Brown ierr = VecScale(vec2_C,m_one);CHKERRQ(ierr); 17030c7d97c5SJed Brown ierr = VecGetArray(vec2_C,&array);CHKERRQ(ierr); 17043b03a366Sstefano_zampini ierr = MatSetValues(M1,n_constraints,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 17050c7d97c5SJed Brown ierr = VecRestoreArray(vec2_C,&array);CHKERRQ(ierr); 17060c7d97c5SJed Brown } 17070c7d97c5SJed Brown ierr = MatAssemblyBegin(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17080c7d97c5SJed Brown ierr = MatAssemblyEnd(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17090c7d97c5SJed Brown ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 17100c7d97c5SJed Brown /* Assemble local_auxmat1 = M1*C_{CR} needed by BDDC application in KSP and in preproc */ 17110c7d97c5SJed Brown ierr = MatMatMult(M1,C_CR,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 17120c7d97c5SJed Brown 17130c7d97c5SJed Brown } 17140c7d97c5SJed Brown 17150c7d97c5SJed Brown /* Get submatrices from subdomain matrix */ 17163b03a366Sstefano_zampini if (n_vertices){ 1717534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_R_local,is_V_local,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 1718534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_V_local,is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 1719534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_V_local,is_V_local,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 17200c7d97c5SJed Brown } 17210c7d97c5SJed Brown 17220c7d97c5SJed Brown /* Matrix of coarse basis functions (local) */ 1723d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 17240c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 17250c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_B,impMatType);CHKERRQ(ierr); 17260298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_phi_B,NULL);CHKERRQ(ierr); 172729622bf0SStefano Zampini if (pcbddc->inexact_prec_type || dbg_flag ) { 1728d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 17290c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 17300c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_D,impMatType);CHKERRQ(ierr); 17310298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_phi_D,NULL);CHKERRQ(ierr); 17320c7d97c5SJed Brown } 17330c7d97c5SJed Brown 1734e269702eSStefano Zampini if (dbg_flag) { 17350c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&coarsefunctions_errors);CHKERRQ(ierr); 17360c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&constraints_errors);CHKERRQ(ierr); 17370c7d97c5SJed Brown } 17383b03a366Sstefano_zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 17390c7d97c5SJed Brown ierr = PetscMalloc ((pcbddc->local_primal_size)*(pcbddc->local_primal_size)*sizeof(PetscScalar),&coarse_submat_vals);CHKERRQ(ierr); 17400c7d97c5SJed Brown 17410c7d97c5SJed Brown /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 17423b03a366Sstefano_zampini for (i=0;i<n_vertices;i++){ 17430c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 17440c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 17450c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 17460c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 17470c7d97c5SJed Brown /* solution of saddle point problem */ 17480bdf917eSStefano Zampini ierr = MatMult(A_RV,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 17490bdf917eSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 17500c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_R,m_one);CHKERRQ(ierr); 17513b03a366Sstefano_zampini if (n_constraints) { 17520c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec1_R,vec1_C);CHKERRQ(ierr); 17530c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 17540c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 17550c7d97c5SJed Brown } 17560c7d97c5SJed Brown ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); 17570c7d97c5SJed Brown ierr = MatMultAdd(A_VV,vec1_V,vec2_V,vec2_V);CHKERRQ(ierr); 17580c7d97c5SJed Brown 17590c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 17600c7d97c5SJed Brown /* coarse basis functions */ 17610c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 17620c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17630c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17640c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 17653b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 17660c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 17670c7d97c5SJed Brown ierr = MatSetValue(pcbddc->coarse_phi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 176829622bf0SStefano Zampini if ( pcbddc->inexact_prec_type || dbg_flag ) { 17690c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17700c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17710c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 17723b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 17730c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 17740c7d97c5SJed Brown } 17750c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 17760c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 17772fa5cd67SKarl Rupp for (j=0; j<n_vertices; j++) coarse_submat_vals[i*pcbddc->local_primal_size+j] = array[j]; /* WARNING -> column major ordering */ 17780c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 17793b03a366Sstefano_zampini if (n_constraints) { 17800c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 17812fa5cd67SKarl Rupp for (j=0; j<n_constraints; j++) coarse_submat_vals[i*pcbddc->local_primal_size+j+n_vertices] = array[j]; /* WARNING -> column major ordering */ 17820c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 17830c7d97c5SJed Brown } 17840c7d97c5SJed Brown 1785e269702eSStefano Zampini if ( dbg_flag ) { 17860c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 1787d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 17880c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 17890c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 17902fa5cd67SKarl Rupp for (j=0;j<n_R;j++) array[idx_R_local[j]] = array2[j]; 17913b03a366Sstefano_zampini array[ vertices[i] ] = one; 17920c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 17930c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 17940c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers (i.e. primal nodes) */ 1795d49ef151SStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 17960c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 17970c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 17982fa5cd67SKarl Rupp for (j=0;j<n_vertices;j++) array2[j]=array[j]; 17990c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 18003b03a366Sstefano_zampini if (n_constraints) { 18010c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 18022fa5cd67SKarl Rupp for (j=0;j<n_constraints;j++) array2[j+n_vertices]=array[j]; 18030c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 18040c7d97c5SJed Brown } 18050c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 18060c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_P,m_one);CHKERRQ(ierr); 18070c7d97c5SJed Brown /* check saddle point solution */ 1808534831adSStefano Zampini ierr = MatMult(pcbddc->local_mat,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 18093b03a366Sstefano_zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 18103b03a366Sstefano_zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[i]);CHKERRQ(ierr); 18113b03a366Sstefano_zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 18120c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 18133b03a366Sstefano_zampini array[i]=array[i]+m_one; /* shift by the identity matrix */ 18140c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 18153b03a366Sstefano_zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[i]);CHKERRQ(ierr); 18160c7d97c5SJed Brown } 18170c7d97c5SJed Brown } 18180c7d97c5SJed Brown 18193b03a366Sstefano_zampini for (i=0;i<n_constraints;i++){ 1820d49ef151SStefano Zampini ierr = VecSet(vec2_C,zero);CHKERRQ(ierr); 18210c7d97c5SJed Brown ierr = VecSetValue(vec2_C,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 18220c7d97c5SJed Brown ierr = VecAssemblyBegin(vec2_C);CHKERRQ(ierr); 18230c7d97c5SJed Brown ierr = VecAssemblyEnd(vec2_C);CHKERRQ(ierr); 18240c7d97c5SJed Brown /* solution of saddle point problem */ 18250c7d97c5SJed Brown ierr = MatMult(M1,vec2_C,vec1_C);CHKERRQ(ierr); 18260c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 18270c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 18283b03a366Sstefano_zampini if (n_vertices) { ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); } 18290c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 18300c7d97c5SJed Brown /* coarse basis functions */ 18313b03a366Sstefano_zampini index=i+n_vertices; 18320c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 18330c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18340c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18350c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 183653cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 18370c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 183829622bf0SStefano Zampini if ( pcbddc->inexact_prec_type || dbg_flag ) { 18390c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18400c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18410c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 184253cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 18430c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 18440c7d97c5SJed Brown } 18450c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 18463b03a366Sstefano_zampini if (n_vertices) { 18470c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 18482fa5cd67SKarl Rupp for (j=0; j<n_vertices; j++) coarse_submat_vals[index*pcbddc->local_primal_size+j]=array[j]; /* WARNING -> column major ordering */ 18490c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 18500c7d97c5SJed Brown } 18510c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 18522fa5cd67SKarl Rupp for (j=0; j<n_constraints; j++) coarse_submat_vals[index*pcbddc->local_primal_size+j+n_vertices]=array[j]; /* WARNING -> column major ordering */ 18530c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 18540c7d97c5SJed Brown 1855e269702eSStefano Zampini if ( dbg_flag ) { 18560c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 185753cdbc3dSStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 18580c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 18590c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 18602fa5cd67SKarl Rupp for (j=0;j<n_R;j++) array[idx_R_local[j]] = array2[j]; 18610c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 18620c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 18630c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers */ 186453cdbc3dSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 18650c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 18663b03a366Sstefano_zampini if ( n_vertices) { 18670c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 18682fa5cd67SKarl Rupp for (j=0;j<n_vertices;j++) array2[j]=-array[j]; 18690c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 18700c7d97c5SJed Brown } 18710c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 18723b03a366Sstefano_zampini for (j=0;j<n_constraints;j++) {array2[j+n_vertices]=-array[j];} 18730c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 18740c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 18753972b0daSStefano Zampini /* check saddle point solution */ 1876534831adSStefano Zampini ierr = MatMult(pcbddc->local_mat,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 18773b03a366Sstefano_zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 187853cdbc3dSStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[index]);CHKERRQ(ierr); 18793b03a366Sstefano_zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 18800c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 188153cdbc3dSStefano Zampini array[index]=array[index]+m_one; /* shift by the identity matrix */ 18820c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 188353cdbc3dSStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[index]);CHKERRQ(ierr); 18840c7d97c5SJed Brown } 18850c7d97c5SJed Brown } 18860c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18870c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 188829622bf0SStefano Zampini if ( pcbddc->inexact_prec_type || dbg_flag ) { 18890c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18900c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18910c7d97c5SJed Brown } 18920c7d97c5SJed Brown /* Checking coarse_sub_mat and coarse basis functios */ 18930c7d97c5SJed Brown /* It shuld be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 18949d2fce94SStefano Zampini if (dbg_flag) { 18950c7d97c5SJed Brown Mat coarse_sub_mat; 18960c7d97c5SJed Brown Mat TM1,TM2,TM3,TM4; 18970c7d97c5SJed Brown Mat coarse_phi_D,coarse_phi_B,A_II,A_BB,A_IB,A_BI; 189819fd82e9SBarry Smith MatType checkmattype=MATSEQAIJ; 18990c7d97c5SJed Brown PetscScalar value; 19000c7d97c5SJed Brown 1901c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 1902c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 1903c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 1904c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 1905c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 1906c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 1907c042a7c3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 1908c042a7c3SStefano Zampini ierr = MatConvert(coarse_sub_mat,checkmattype,MAT_REUSE_MATRIX,&coarse_sub_mat);CHKERRQ(ierr); 19090c7d97c5SJed Brown 19100c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 19110c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Check coarse sub mat and local basis functions\n");CHKERRQ(ierr); 19120c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 191353cdbc3dSStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 191453cdbc3dSStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 191553cdbc3dSStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1916c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 191753cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 191853cdbc3dSStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1919c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 192053cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 192153cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 192253cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 192353cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 192453cdbc3dSStefano Zampini ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 192553cdbc3dSStefano Zampini ierr = MatNorm(TM1,NORM_INFINITY,&value);CHKERRQ(ierr); 19260c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"----------------------------------\n");CHKERRQ(ierr); 19270c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d \n",PetscGlobalRank);CHKERRQ(ierr); 19280c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"matrix error = % 1.14e\n",value);CHKERRQ(ierr); 19290c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"coarse functions errors\n");CHKERRQ(ierr); 193053cdbc3dSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local %02d-th function error = % 1.14e\n",i,coarsefunctions_errors[i]);CHKERRQ(ierr); } 19310c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"constraints errors\n");CHKERRQ(ierr); 193253cdbc3dSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local %02d-th function error = % 1.14e\n",i,constraints_errors[i]);CHKERRQ(ierr); } 19330c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 193453cdbc3dSStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 193553cdbc3dSStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 193653cdbc3dSStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 193753cdbc3dSStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 193853cdbc3dSStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 193953cdbc3dSStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 194053cdbc3dSStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 194153cdbc3dSStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 194253cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 194353cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 194453cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 19450c7d97c5SJed Brown ierr = PetscFree(coarsefunctions_errors);CHKERRQ(ierr); 19460c7d97c5SJed Brown ierr = PetscFree(constraints_errors);CHKERRQ(ierr); 19470c7d97c5SJed Brown } 19480c7d97c5SJed Brown /* free memory */ 19493b03a366Sstefano_zampini if (n_vertices) { 19500c7d97c5SJed Brown ierr = VecDestroy(&vec1_V);CHKERRQ(ierr); 19510c7d97c5SJed Brown ierr = VecDestroy(&vec2_V);CHKERRQ(ierr); 19520c7d97c5SJed Brown ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 19530c7d97c5SJed Brown ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 19540c7d97c5SJed Brown ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 19550c7d97c5SJed Brown } 1956534831adSStefano Zampini if (n_constraints) { 19570c7d97c5SJed Brown ierr = VecDestroy(&vec1_C);CHKERRQ(ierr); 19580c7d97c5SJed Brown ierr = VecDestroy(&vec2_C);CHKERRQ(ierr); 19590c7d97c5SJed Brown ierr = MatDestroy(&M1);CHKERRQ(ierr); 19600c7d97c5SJed Brown ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 19610c7d97c5SJed Brown } 1962a929c220SStefano Zampini ierr = PetscFree(auxindices);CHKERRQ(ierr); 1963a929c220SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 1964a929c220SStefano Zampini /* create coarse matrix and data structures for message passing associated actual choice of coarse problem type */ 1965674ae819SStefano Zampini ierr = PCBDDCSetUpCoarseEnvironment(pc,coarse_submat_vals);CHKERRQ(ierr); 1966a929c220SStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 19670c7d97c5SJed Brown } 19680c7d97c5SJed Brown /* free memory */ 19693b03a366Sstefano_zampini if (n_vertices) { 19700c7d97c5SJed Brown ierr = ISDestroy(&is_V_local);CHKERRQ(ierr); 19710c7d97c5SJed Brown } 1972674ae819SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 1973674ae819SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&BtoNmap);CHKERRQ(ierr); 19740c7d97c5SJed Brown ierr = ISDestroy(&is_R_local);CHKERRQ(ierr); 1975674ae819SStefano Zampini 19760c7d97c5SJed Brown PetscFunctionReturn(0); 19770c7d97c5SJed Brown } 19780c7d97c5SJed Brown 19790c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 19800c7d97c5SJed Brown 19810c7d97c5SJed Brown #undef __FUNCT__ 1982674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseEnvironment" 1983674ae819SStefano Zampini static PetscErrorCode PCBDDCSetUpCoarseEnvironment(PC pc,PetscScalar* coarse_submat_vals) 19840c7d97c5SJed Brown { 1985674ae819SStefano Zampini 1986674ae819SStefano Zampini 19870c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 19880c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 19890c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 1990ce94432eSBarry Smith MPI_Comm prec_comm; 19910c7d97c5SJed Brown MPI_Comm coarse_comm; 19920c7d97c5SJed Brown 1993674ae819SStefano Zampini MatNullSpace CoarseNullSpace; 1994674ae819SStefano Zampini 19950c7d97c5SJed Brown /* common to all choiches */ 19960c7d97c5SJed Brown PetscScalar *temp_coarse_mat_vals; 19970c7d97c5SJed Brown PetscScalar *ins_coarse_mat_vals; 19980c7d97c5SJed Brown PetscInt *ins_local_primal_indices; 19990c7d97c5SJed Brown PetscMPIInt *localsizes2,*localdispl2; 20000c7d97c5SJed Brown PetscMPIInt size_prec_comm; 20010c7d97c5SJed Brown PetscMPIInt rank_prec_comm; 20020c7d97c5SJed Brown PetscMPIInt active_rank=MPI_PROC_NULL; 20030c7d97c5SJed Brown PetscMPIInt master_proc=0; 20040c7d97c5SJed Brown PetscInt ins_local_primal_size; 20050c7d97c5SJed Brown /* specific to MULTILEVEL_BDDC */ 20060c7d97c5SJed Brown PetscMPIInt *ranks_recv; 20070c7d97c5SJed Brown PetscMPIInt count_recv=0; 20080c7d97c5SJed Brown PetscMPIInt rank_coarse_proc_send_to; 20090c7d97c5SJed Brown PetscMPIInt coarse_color = MPI_UNDEFINED; 20100c7d97c5SJed Brown ISLocalToGlobalMapping coarse_ISLG; 20110c7d97c5SJed Brown /* some other variables */ 20120c7d97c5SJed Brown PetscErrorCode ierr; 201319fd82e9SBarry Smith MatType coarse_mat_type; 201419fd82e9SBarry Smith PCType coarse_pc_type; 201519fd82e9SBarry Smith KSPType coarse_ksp_type; 201653cdbc3dSStefano Zampini PC pc_temp; 20174fad6a16SStefano Zampini PetscInt i,j,k; 20183b03a366Sstefano_zampini PetscInt max_it_coarse_ksp=1; /* don't increase this value */ 2019e269702eSStefano Zampini /* verbose output viewer */ 2020e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 2021e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 2022142dfd88SStefano Zampini 2023ea7e1babSStefano Zampini PetscInt offset,offset2; 2024a929c220SStefano Zampini PetscMPIInt im_active,active_procs; 2025523858cfSStefano Zampini PetscInt *dnz,*onz; 2026142dfd88SStefano Zampini 2027142dfd88SStefano Zampini PetscBool setsym,issym=PETSC_FALSE; 20280c7d97c5SJed Brown 20290c7d97c5SJed Brown PetscFunctionBegin; 20304b2d0b89SJed Brown ierr = PetscObjectGetComm((PetscObject)pc,&prec_comm);CHKERRQ(ierr); 20310c7d97c5SJed Brown ins_local_primal_indices = 0; 20320c7d97c5SJed Brown ins_coarse_mat_vals = 0; 20330c7d97c5SJed Brown localsizes2 = 0; 20340c7d97c5SJed Brown localdispl2 = 0; 20350c7d97c5SJed Brown temp_coarse_mat_vals = 0; 20360c7d97c5SJed Brown coarse_ISLG = 0; 20370c7d97c5SJed Brown 203853cdbc3dSStefano Zampini ierr = MPI_Comm_size(prec_comm,&size_prec_comm);CHKERRQ(ierr); 203953cdbc3dSStefano Zampini ierr = MPI_Comm_rank(prec_comm,&rank_prec_comm);CHKERRQ(ierr); 2040142dfd88SStefano Zampini ierr = MatIsSymmetricKnown(pc->pmat,&setsym,&issym);CHKERRQ(ierr); 2041142dfd88SStefano Zampini 2042beed3852SStefano Zampini /* Assign global numbering to coarse dofs */ 2043beed3852SStefano Zampini { 2044674ae819SStefano Zampini PetscInt *auxlocal_primal,*aux_idx; 2045ef028eecSStefano Zampini PetscMPIInt mpi_local_primal_size; 2046ef028eecSStefano Zampini PetscScalar coarsesum,*array; 2047ef028eecSStefano Zampini 2048ef028eecSStefano Zampini mpi_local_primal_size = (PetscMPIInt)pcbddc->local_primal_size; 2049beed3852SStefano Zampini 2050beed3852SStefano Zampini /* Construct needed data structures for message passing */ 2051ffe5efe1SStefano Zampini j = 0; 2052142dfd88SStefano Zampini if (rank_prec_comm == 0 || pcbddc->coarse_problem_type == REPLICATED_BDDC || pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2053ffe5efe1SStefano Zampini j = size_prec_comm; 2054ffe5efe1SStefano Zampini } 2055ffe5efe1SStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->local_primal_sizes);CHKERRQ(ierr); 2056ffe5efe1SStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 2057beed3852SStefano Zampini /* Gather local_primal_size information for all processes */ 2058142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == REPLICATED_BDDC || pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 20595619798eSStefano Zampini ierr = MPI_Allgather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,prec_comm);CHKERRQ(ierr); 2060ffe5efe1SStefano Zampini } else { 2061ffe5efe1SStefano Zampini ierr = MPI_Gather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 2062ffe5efe1SStefano Zampini } 2063beed3852SStefano Zampini pcbddc->replicated_primal_size = 0; 2064ffe5efe1SStefano Zampini for (i=0; i<j; i++) { 2065beed3852SStefano Zampini pcbddc->local_primal_displacements[i] = pcbddc->replicated_primal_size ; 2066beed3852SStefano Zampini pcbddc->replicated_primal_size += pcbddc->local_primal_sizes[i]; 2067beed3852SStefano Zampini } 2068beed3852SStefano Zampini 2069da1bb401SStefano Zampini /* First let's count coarse dofs. 2070beed3852SStefano Zampini This code fragment assumes that the number of local constraints per connected component 2071beed3852SStefano Zampini is not greater than the number of nodes defined for the connected component 2072beed3852SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 2073ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscInt),&auxlocal_primal);CHKERRQ(ierr); 2074674ae819SStefano Zampini ierr = PCBDDCGetPrimalVerticesLocalIdx(pc,&i,&aux_idx);CHKERRQ(ierr); 2075674ae819SStefano Zampini ierr = PetscMemcpy(auxlocal_primal,aux_idx,i*sizeof(PetscInt));CHKERRQ(ierr); 2076674ae819SStefano Zampini ierr = PetscFree(aux_idx);CHKERRQ(ierr); 2077674ae819SStefano Zampini ierr = PCBDDCGetPrimalConstraintsLocalIdx(pc,&j,&aux_idx);CHKERRQ(ierr); 2078674ae819SStefano Zampini ierr = PetscMemcpy(&auxlocal_primal[i],aux_idx,j*sizeof(PetscInt));CHKERRQ(ierr); 2079674ae819SStefano Zampini ierr = PetscFree(aux_idx);CHKERRQ(ierr); 2080ef028eecSStefano Zampini /* Compute number of coarse dofs */ 2081674ae819SStefano Zampini ierr = PCBDDCSubsetNumbering(prec_comm,matis->mapping,pcbddc->local_primal_size,auxlocal_primal,NULL,&pcbddc->coarse_size,&pcbddc->local_primal_indices);CHKERRQ(ierr); 2082ef028eecSStefano Zampini 2083ef028eecSStefano Zampini if (dbg_flag) { 20842e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 20852e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 20862e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Check coarse indices\n");CHKERRQ(ierr); 20872e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 20882e8d2280SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 20892fa5cd67SKarl Rupp for (i=0;i<pcbddc->local_primal_size;i++) array[auxlocal_primal[i]]=1.0; 2090beed3852SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 20912e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 2092da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2093da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2094da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2095da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2096da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 20972e8d2280SStefano Zampini for (i=0;i<pcis->n;i++) { 20982e8d2280SStefano Zampini if (array[i] == 1.0) { 20992e8d2280SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,1,&i,&j);CHKERRQ(ierr); 21002e8d2280SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d: WRONG COARSE INDEX %d (local %d)\n",PetscGlobalRank,j,i);CHKERRQ(ierr); 21012e8d2280SStefano Zampini } 21022e8d2280SStefano Zampini } 21032e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 21042e8d2280SStefano Zampini for (i=0;i<pcis->n;i++) { 21052fa5cd67SKarl Rupp if (array[i] > 0.0) array[i] = 1.0/array[i]; 21062e8d2280SStefano Zampini } 2107da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 21082e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 2109da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2110da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2111da1bb401SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 21122e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem SHOULD be %lf\n",coarsesum);CHKERRQ(ierr); 21132e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 21142e8d2280SStefano Zampini } 2115142dfd88SStefano Zampini ierr = PetscFree(auxlocal_primal);CHKERRQ(ierr); 21160bdf917eSStefano Zampini } 21170bdf917eSStefano Zampini 21182e8d2280SStefano Zampini if (dbg_flag) { 21197cf533a6SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem is %d\n",pcbddc->coarse_size);CHKERRQ(ierr); 2120674ae819SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 2121674ae819SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2122674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 2123674ae819SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 2124674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_primal_indices[%d]=%d \n",i,pcbddc->local_primal_indices[i]); 2125674ae819SStefano Zampini } 21262e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 21272e8d2280SStefano Zampini } 21282e8d2280SStefano Zampini 2129a929c220SStefano Zampini im_active = 0; 21302fa5cd67SKarl Rupp if (pcis->n) im_active = 1; 2131a929c220SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,prec_comm);CHKERRQ(ierr); 21320bdf917eSStefano Zampini 21330bdf917eSStefano Zampini /* adapt coarse problem type */ 21344fad6a16SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 21354fad6a16SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 2136a929c220SStefano Zampini if ( (active_procs/pcbddc->coarsening_ratio) < 2 ) { 21370bdf917eSStefano Zampini if (dbg_flag) { 2138a929c220SStefano 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); 21390bdf917eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 21400bdf917eSStefano Zampini } 21410bdf917eSStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 2142142dfd88SStefano Zampini } 21434fad6a16SStefano Zampini } else { 21444fad6a16SStefano Zampini if (dbg_flag) { 2145a929c220SStefano 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); 21464fad6a16SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 21474fad6a16SStefano Zampini } 21484fad6a16SStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 21494fad6a16SStefano Zampini } 21504fad6a16SStefano Zampini } 2151beed3852SStefano Zampini 21520c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 21530c7d97c5SJed Brown 2154da1bb401SStefano Zampini case(MULTILEVEL_BDDC): /* we define a coarse mesh where subdomains are elements */ 21550c7d97c5SJed Brown { 21560c7d97c5SJed Brown /* we need additional variables */ 21570c7d97c5SJed Brown MetisInt n_subdomains,n_parts,objval,ncon,faces_nvtxs; 21580c7d97c5SJed Brown MetisInt *metis_coarse_subdivision; 21590c7d97c5SJed Brown MetisInt options[METIS_NOPTIONS]; 21600c7d97c5SJed Brown PetscMPIInt size_coarse_comm,rank_coarse_comm; 21610c7d97c5SJed Brown PetscMPIInt procs_jumps_coarse_comm; 21620c7d97c5SJed Brown PetscMPIInt *coarse_subdivision; 21630c7d97c5SJed Brown PetscMPIInt *total_count_recv; 21640c7d97c5SJed Brown PetscMPIInt *total_ranks_recv; 21650c7d97c5SJed Brown PetscMPIInt *displacements_recv; 21660c7d97c5SJed Brown PetscMPIInt *my_faces_connectivity; 21670c7d97c5SJed Brown PetscMPIInt *petsc_faces_adjncy; 21680c7d97c5SJed Brown MetisInt *faces_adjncy; 21690c7d97c5SJed Brown MetisInt *faces_xadj; 21700c7d97c5SJed Brown PetscMPIInt *number_of_faces; 21710c7d97c5SJed Brown PetscMPIInt *faces_displacements; 21720c7d97c5SJed Brown PetscInt *array_int; 21730c7d97c5SJed Brown PetscMPIInt my_faces=0; 21740c7d97c5SJed Brown PetscMPIInt total_faces=0; 21753828260eSStefano Zampini PetscInt ranks_stretching_ratio; 21760c7d97c5SJed Brown 21770c7d97c5SJed Brown /* define some quantities */ 21780c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 21790c7d97c5SJed Brown coarse_mat_type = MATIS; 21800c7d97c5SJed Brown coarse_pc_type = PCBDDC; 2181142dfd88SStefano Zampini coarse_ksp_type = KSPRICHARDSON; 21820c7d97c5SJed Brown 21830c7d97c5SJed Brown /* details of coarse decomposition */ 2184a929c220SStefano Zampini n_subdomains = active_procs; 21850c7d97c5SJed Brown n_parts = n_subdomains/pcbddc->coarsening_ratio; 2186a929c220SStefano Zampini ranks_stretching_ratio = size_prec_comm/active_procs; 21873828260eSStefano Zampini procs_jumps_coarse_comm = pcbddc->coarsening_ratio*ranks_stretching_ratio; 21883828260eSStefano Zampini 2189a929c220SStefano Zampini #if 0 2190a929c220SStefano Zampini PetscMPIInt *old_ranks; 2191a929c220SStefano Zampini PetscInt *new_ranks,*jj,*ii; 2192a929c220SStefano Zampini MatPartitioning mat_part; 2193a929c220SStefano Zampini IS coarse_new_decomposition,is_numbering; 2194a929c220SStefano Zampini PetscViewer viewer_test; 2195a929c220SStefano Zampini MPI_Comm test_coarse_comm; 2196a929c220SStefano Zampini PetscMPIInt test_coarse_color; 2197a929c220SStefano Zampini Mat mat_adj; 2198a929c220SStefano Zampini /* Create new communicator for coarse problem splitting the old one */ 2199a929c220SStefano Zampini /* procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 2200a929c220SStefano Zampini key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator */ 2201a929c220SStefano Zampini test_coarse_color = ( im_active ? 0 : MPI_UNDEFINED ); 2202a929c220SStefano Zampini test_coarse_comm = MPI_COMM_NULL; 2203a929c220SStefano Zampini ierr = MPI_Comm_split(prec_comm,test_coarse_color,rank_prec_comm,&test_coarse_comm);CHKERRQ(ierr); 2204a929c220SStefano Zampini if (im_active) { 2205a929c220SStefano Zampini ierr = PetscMalloc(n_subdomains*sizeof(PetscMPIInt),&old_ranks); 2206a929c220SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscInt),&new_ranks); 2207a929c220SStefano Zampini ierr = MPI_Comm_rank(test_coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 2208a929c220SStefano Zampini ierr = MPI_Comm_size(test_coarse_comm,&j);CHKERRQ(ierr); 2209a929c220SStefano Zampini ierr = MPI_Allgather(&rank_prec_comm,1,MPIU_INT,old_ranks,1,MPIU_INT,test_coarse_comm);CHKERRQ(ierr); 2210674ae819SStefano Zampini for (i=0; i<size_prec_comm; i++) new_ranks[i] = -1; 2211674ae819SStefano Zampini for (i=0; i<n_subdomains; i++) new_ranks[old_ranks[i]] = i; 2212a929c220SStefano Zampini ierr = PetscViewerASCIIOpen(test_coarse_comm,"test_mat_part.out",&viewer_test);CHKERRQ(ierr); 2213a929c220SStefano Zampini k = pcis->n_neigh-1; 2214a929c220SStefano Zampini ierr = PetscMalloc(2*sizeof(PetscInt),&ii); 2215a929c220SStefano Zampini ii[0]=0; 2216a929c220SStefano Zampini ii[1]=k; 2217a929c220SStefano Zampini ierr = PetscMalloc(k*sizeof(PetscInt),&jj); 2218674ae819SStefano Zampini for (i=0; i<k; i++) jj[i]=new_ranks[pcis->neigh[i+1]]; 2219a929c220SStefano Zampini ierr = PetscSortInt(k,jj);CHKERRQ(ierr); 22200298fd71SBarry Smith ierr = MatCreateMPIAdj(test_coarse_comm,1,n_subdomains,ii,jj,NULL,&mat_adj);CHKERRQ(ierr); 2221a929c220SStefano Zampini ierr = MatView(mat_adj,viewer_test);CHKERRQ(ierr); 2222a929c220SStefano Zampini ierr = MatPartitioningCreate(test_coarse_comm,&mat_part);CHKERRQ(ierr); 2223a929c220SStefano Zampini ierr = MatPartitioningSetAdjacency(mat_part,mat_adj);CHKERRQ(ierr); 2224a929c220SStefano Zampini ierr = MatPartitioningSetFromOptions(mat_part);CHKERRQ(ierr); 2225a929c220SStefano Zampini printf("Setting Nparts %d\n",n_parts); 2226a929c220SStefano Zampini ierr = MatPartitioningSetNParts(mat_part,n_parts);CHKERRQ(ierr); 2227a929c220SStefano Zampini ierr = MatPartitioningView(mat_part,viewer_test);CHKERRQ(ierr); 2228a929c220SStefano Zampini ierr = MatPartitioningApply(mat_part,&coarse_new_decomposition);CHKERRQ(ierr); 2229a929c220SStefano Zampini ierr = ISView(coarse_new_decomposition,viewer_test);CHKERRQ(ierr); 2230a929c220SStefano Zampini ierr = ISPartitioningToNumbering(coarse_new_decomposition,&is_numbering);CHKERRQ(ierr); 2231a929c220SStefano Zampini ierr = ISView(is_numbering,viewer_test);CHKERRQ(ierr); 2232a929c220SStefano Zampini ierr = PetscViewerDestroy(&viewer_test);CHKERRQ(ierr); 2233a929c220SStefano Zampini ierr = ISDestroy(&coarse_new_decomposition);CHKERRQ(ierr); 2234a929c220SStefano Zampini ierr = ISDestroy(&is_numbering);CHKERRQ(ierr); 2235a929c220SStefano Zampini ierr = MatPartitioningDestroy(&mat_part);CHKERRQ(ierr); 2236a929c220SStefano Zampini ierr = PetscFree(old_ranks);CHKERRQ(ierr); 2237a929c220SStefano Zampini ierr = PetscFree(new_ranks);CHKERRQ(ierr); 2238a929c220SStefano Zampini ierr = MPI_Comm_free(&test_coarse_comm);CHKERRQ(ierr); 2239a929c220SStefano Zampini } 2240a929c220SStefano Zampini #endif 2241a929c220SStefano Zampini 22424fad6a16SStefano Zampini /* build CSR graph of subdomains' connectivity */ 22430c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&array_int);CHKERRQ(ierr); 22443828260eSStefano Zampini ierr = PetscMemzero(array_int,pcis->n*sizeof(PetscInt));CHKERRQ(ierr); 22450c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++){/* i=1 so I don't count myself -> faces nodes counts to 1 */ 22460c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++){ 22470c7d97c5SJed Brown array_int[ pcis->shared[i][j] ]+=1; 22480c7d97c5SJed Brown } 22490c7d97c5SJed Brown } 22500c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++){ 22510c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++){ 22527cf533a6SStefano Zampini if (array_int[ pcis->shared[i][j] ] > 0 ){ 22530c7d97c5SJed Brown my_faces++; 22540c7d97c5SJed Brown break; 22550c7d97c5SJed Brown } 22560c7d97c5SJed Brown } 22570c7d97c5SJed Brown } 22580c7d97c5SJed Brown 225953cdbc3dSStefano Zampini ierr = MPI_Reduce(&my_faces,&total_faces,1,MPIU_INT,MPI_SUM,master_proc,prec_comm);CHKERRQ(ierr); 22600c7d97c5SJed Brown ierr = PetscMalloc (my_faces*sizeof(PetscInt),&my_faces_connectivity);CHKERRQ(ierr); 22610c7d97c5SJed Brown my_faces=0; 22620c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++){ 22630c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++){ 22647cf533a6SStefano Zampini if (array_int[ pcis->shared[i][j] ] > 0 ){ 22650c7d97c5SJed Brown my_faces_connectivity[my_faces]=pcis->neigh[i]; 22660c7d97c5SJed Brown my_faces++; 22670c7d97c5SJed Brown break; 22680c7d97c5SJed Brown } 22690c7d97c5SJed Brown } 22700c7d97c5SJed Brown } 22710c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 22720c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(PetscMPIInt),&petsc_faces_adjncy);CHKERRQ(ierr); 22730c7d97c5SJed Brown ierr = PetscMalloc (size_prec_comm*sizeof(PetscMPIInt),&number_of_faces);CHKERRQ(ierr); 22740c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(MetisInt),&faces_adjncy);CHKERRQ(ierr); 22750c7d97c5SJed Brown ierr = PetscMalloc ((n_subdomains+1)*sizeof(MetisInt),&faces_xadj);CHKERRQ(ierr); 22760c7d97c5SJed Brown ierr = PetscMalloc ((size_prec_comm+1)*sizeof(PetscMPIInt),&faces_displacements);CHKERRQ(ierr); 22770c7d97c5SJed Brown } 227853cdbc3dSStefano Zampini ierr = MPI_Gather(&my_faces,1,MPIU_INT,&number_of_faces[0],1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 22790c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 22800c7d97c5SJed Brown faces_xadj[0]=0; 22810c7d97c5SJed Brown faces_displacements[0]=0; 22820c7d97c5SJed Brown j=0; 22830c7d97c5SJed Brown for (i=1;i<size_prec_comm+1;i++) { 22840c7d97c5SJed Brown faces_displacements[i]=faces_displacements[i-1]+number_of_faces[i-1]; 22850c7d97c5SJed Brown if (number_of_faces[i-1]) { 22860c7d97c5SJed Brown j++; 22870c7d97c5SJed Brown faces_xadj[j]=faces_xadj[j-1]+number_of_faces[i-1]; 22880c7d97c5SJed Brown } 22890c7d97c5SJed Brown } 22900c7d97c5SJed Brown } 229153cdbc3dSStefano 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); 22920c7d97c5SJed Brown ierr = PetscFree(my_faces_connectivity);CHKERRQ(ierr); 22930c7d97c5SJed Brown ierr = PetscFree(array_int);CHKERRQ(ierr); 22940c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 22953828260eSStefano Zampini for (i=0;i<total_faces;i++) faces_adjncy[i]=(MetisInt)(petsc_faces_adjncy[i]/ranks_stretching_ratio); /* cast to MetisInt */ 22960c7d97c5SJed Brown ierr = PetscFree(faces_displacements);CHKERRQ(ierr); 22970c7d97c5SJed Brown ierr = PetscFree(number_of_faces);CHKERRQ(ierr); 22980c7d97c5SJed Brown ierr = PetscFree(petsc_faces_adjncy);CHKERRQ(ierr); 22990c7d97c5SJed Brown } 23000c7d97c5SJed Brown 23010c7d97c5SJed Brown if ( rank_prec_comm == master_proc ) { 2302674ae819SStefano Zampini 23033828260eSStefano Zampini PetscInt heuristic_for_metis=3; 2304674ae819SStefano Zampini 23050c7d97c5SJed Brown ncon=1; 23060c7d97c5SJed Brown faces_nvtxs=n_subdomains; 23070c7d97c5SJed Brown /* partition graoh induced by face connectivity */ 23080c7d97c5SJed Brown ierr = PetscMalloc (n_subdomains*sizeof(MetisInt),&metis_coarse_subdivision);CHKERRQ(ierr); 23090c7d97c5SJed Brown ierr = METIS_SetDefaultOptions(options); 23100c7d97c5SJed Brown /* we need a contiguous partition of the coarse mesh */ 23110c7d97c5SJed Brown options[METIS_OPTION_CONTIG]=1; 23120c7d97c5SJed Brown options[METIS_OPTION_NITER]=30; 23134fad6a16SStefano Zampini if (pcbddc->coarsening_ratio > 1) { 23143828260eSStefano Zampini if (n_subdomains>n_parts*heuristic_for_metis) { 23153828260eSStefano Zampini options[METIS_OPTION_IPTYPE]=METIS_IPTYPE_EDGE; 23163828260eSStefano Zampini options[METIS_OPTION_OBJTYPE]=METIS_OBJTYPE_CUT; 23170c7d97c5SJed Brown ierr = METIS_PartGraphKway(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 2318674ae819SStefano 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); 23193828260eSStefano Zampini } else { 23203828260eSStefano Zampini ierr = METIS_PartGraphRecursive(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 2321674ae819SStefano 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); 23223828260eSStefano Zampini } 23234fad6a16SStefano Zampini } else { 23242fa5cd67SKarl Rupp for (i=0;i<n_subdomains;i++) metis_coarse_subdivision[i]=i; 23254fad6a16SStefano Zampini } 23260c7d97c5SJed Brown ierr = PetscFree(faces_xadj);CHKERRQ(ierr); 23270c7d97c5SJed Brown ierr = PetscFree(faces_adjncy);CHKERRQ(ierr); 23280bdf917eSStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&coarse_subdivision);CHKERRQ(ierr); 23292fa5cd67SKarl Rupp 23300c7d97c5SJed Brown /* copy/cast values avoiding possible type conflicts between PETSc, MPI and METIS */ 23312fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) coarse_subdivision[i]=MPI_PROC_NULL; 23322fa5cd67SKarl Rupp for (i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=(PetscInt)(metis_coarse_subdivision[i]); 23330c7d97c5SJed Brown ierr = PetscFree(metis_coarse_subdivision);CHKERRQ(ierr); 23340c7d97c5SJed Brown } 23350c7d97c5SJed Brown 23360c7d97c5SJed Brown /* Create new communicator for coarse problem splitting the old one */ 23370c7d97c5SJed Brown if ( !(rank_prec_comm%procs_jumps_coarse_comm) && rank_prec_comm < procs_jumps_coarse_comm*n_parts ){ 2338da1bb401SStefano Zampini coarse_color=0; /* for communicator splitting */ 2339da1bb401SStefano Zampini active_rank=rank_prec_comm; /* for insertion of matrix values */ 23400c7d97c5SJed Brown } 2341da1bb401SStefano Zampini /* procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 2342da1bb401SStefano Zampini key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator */ 234353cdbc3dSStefano Zampini ierr = MPI_Comm_split(prec_comm,coarse_color,rank_prec_comm,&coarse_comm);CHKERRQ(ierr); 23440c7d97c5SJed Brown 23450c7d97c5SJed Brown if ( coarse_color == 0 ) { 234653cdbc3dSStefano Zampini ierr = MPI_Comm_size(coarse_comm,&size_coarse_comm);CHKERRQ(ierr); 234753cdbc3dSStefano Zampini ierr = MPI_Comm_rank(coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 23480c7d97c5SJed Brown } else { 23490c7d97c5SJed Brown rank_coarse_comm = MPI_PROC_NULL; 23500c7d97c5SJed Brown } 23510c7d97c5SJed Brown 23527cf533a6SStefano Zampini /* master proc take care of arranging and distributing coarse information */ 23530c7d97c5SJed Brown if (rank_coarse_comm == master_proc) { 23540c7d97c5SJed Brown ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&displacements_recv);CHKERRQ(ierr); 23550bdf917eSStefano Zampini ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&total_count_recv);CHKERRQ(ierr); 23560bdf917eSStefano Zampini ierr = PetscMalloc (n_subdomains*sizeof(PetscMPIInt),&total_ranks_recv);CHKERRQ(ierr); 23570c7d97c5SJed Brown /* some initializations */ 23580c7d97c5SJed Brown displacements_recv[0]=0; 23590bdf917eSStefano Zampini ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 23600c7d97c5SJed Brown /* count from how many processes the j-th process of the coarse decomposition will receive data */ 23610bdf917eSStefano Zampini for (j=0;j<size_coarse_comm;j++) { 23620bdf917eSStefano Zampini for (i=0;i<size_prec_comm;i++) { 23632fa5cd67SKarl Rupp if (coarse_subdivision[i]==j) total_count_recv[j]++; 23640bdf917eSStefano Zampini } 23650bdf917eSStefano Zampini } 23660c7d97c5SJed Brown /* displacements needed for scatterv of total_ranks_recv */ 23672fa5cd67SKarl Rupp for (i=1; i<size_coarse_comm; i++) displacements_recv[i]=displacements_recv[i-1]+total_count_recv[i-1]; 23682fa5cd67SKarl Rupp 23690c7d97c5SJed Brown /* Now fill properly total_ranks_recv -> each coarse process will receive the ranks (in prec_comm communicator) of its friend (sending) processes */ 23700c7d97c5SJed Brown ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 23710c7d97c5SJed Brown for (j=0;j<size_coarse_comm;j++) { 23723828260eSStefano Zampini for (i=0;i<size_prec_comm;i++) { 23730c7d97c5SJed Brown if (coarse_subdivision[i]==j) { 23740c7d97c5SJed Brown total_ranks_recv[displacements_recv[j]+total_count_recv[j]]=i; 23753828260eSStefano Zampini total_count_recv[j]+=1; 23760c7d97c5SJed Brown } 23770c7d97c5SJed Brown } 23780c7d97c5SJed Brown } 2379da1bb401SStefano Zampini /*for (j=0;j<size_coarse_comm;j++) { 23803828260eSStefano Zampini printf("process %d in new rank will receive from %d processes (original ranks follows)\n",j,total_count_recv[j]); 23813828260eSStefano Zampini for (i=0;i<total_count_recv[j];i++) { 23823828260eSStefano Zampini printf("%d ",total_ranks_recv[displacements_recv[j]+i]); 23833828260eSStefano Zampini } 23843828260eSStefano Zampini printf("\n"); 2385da1bb401SStefano Zampini }*/ 23860c7d97c5SJed Brown 23870c7d97c5SJed Brown /* identify new decomposition in terms of ranks in the old communicator */ 23880bdf917eSStefano Zampini for (i=0;i<n_subdomains;i++) { 23890bdf917eSStefano Zampini coarse_subdivision[ranks_stretching_ratio*i]=coarse_subdivision[ranks_stretching_ratio*i]*procs_jumps_coarse_comm; 23900bdf917eSStefano Zampini } 2391da1bb401SStefano Zampini /*printf("coarse_subdivision in old end new ranks\n"); 2392674ae819SStefano Zampini for (i=0;i<size_prec_comm;i++) 23933828260eSStefano Zampini if (coarse_subdivision[i]!=MPI_PROC_NULL) { 23943828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]/procs_jumps_coarse_comm); 23953828260eSStefano Zampini } else { 23963828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]); 23973828260eSStefano Zampini } 2398da1bb401SStefano Zampini printf("\n");*/ 23990c7d97c5SJed Brown } 24000c7d97c5SJed Brown 24010c7d97c5SJed Brown /* Scatter new decomposition for send details */ 240253cdbc3dSStefano Zampini ierr = MPI_Scatter(&coarse_subdivision[0],1,MPIU_INT,&rank_coarse_proc_send_to,1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 24030c7d97c5SJed Brown /* Scatter receiving details to members of coarse decomposition */ 24040c7d97c5SJed Brown if ( coarse_color == 0) { 240553cdbc3dSStefano Zampini ierr = MPI_Scatter(&total_count_recv[0],1,MPIU_INT,&count_recv,1,MPIU_INT,master_proc,coarse_comm);CHKERRQ(ierr); 24060c7d97c5SJed Brown ierr = PetscMalloc (count_recv*sizeof(PetscMPIInt),&ranks_recv);CHKERRQ(ierr); 240753cdbc3dSStefano 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); 24080c7d97c5SJed Brown } 24090c7d97c5SJed Brown 2410da1bb401SStefano Zampini /*printf("I will send my matrix data to proc %d\n",rank_coarse_proc_send_to); 2411da1bb401SStefano Zampini if (coarse_color == 0) { 2412da1bb401SStefano Zampini printf("I will receive some matrix data from %d processes (ranks follows)\n",count_recv); 2413da1bb401SStefano Zampini for (i=0;i<count_recv;i++) 2414da1bb401SStefano Zampini printf("%d ",ranks_recv[i]); 2415da1bb401SStefano Zampini printf("\n"); 2416da1bb401SStefano Zampini }*/ 24170c7d97c5SJed Brown 24180c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 24190bdf917eSStefano Zampini ierr = PetscFree(coarse_subdivision);CHKERRQ(ierr); 2420da1bb401SStefano Zampini ierr = PetscFree(total_count_recv);CHKERRQ(ierr); 24210bdf917eSStefano Zampini ierr = PetscFree(total_ranks_recv);CHKERRQ(ierr); 24220c7d97c5SJed Brown ierr = PetscFree(displacements_recv);CHKERRQ(ierr); 24230c7d97c5SJed Brown } 24240c7d97c5SJed Brown break; 24250c7d97c5SJed Brown } 24260c7d97c5SJed Brown 24270c7d97c5SJed Brown case(REPLICATED_BDDC): 24280c7d97c5SJed Brown 24290c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 24300c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 24310c7d97c5SJed Brown coarse_pc_type = PCLU; 243253cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 24330c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 24340c7d97c5SJed Brown active_rank = rank_prec_comm; 24350c7d97c5SJed Brown break; 24360c7d97c5SJed Brown 24370c7d97c5SJed Brown case(PARALLEL_BDDC): 24380c7d97c5SJed Brown 24390c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 2440674ae819SStefano Zampini coarse_mat_type = MATAIJ; 24410c7d97c5SJed Brown coarse_pc_type = PCREDUNDANT; 244253cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 24430c7d97c5SJed Brown coarse_comm = prec_comm; 24440c7d97c5SJed Brown active_rank = rank_prec_comm; 24450c7d97c5SJed Brown break; 24460c7d97c5SJed Brown 24470c7d97c5SJed Brown case(SEQUENTIAL_BDDC): 24480c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 2449674ae819SStefano Zampini coarse_mat_type = MATAIJ; 24500c7d97c5SJed Brown coarse_pc_type = PCLU; 245153cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 24520c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 24530c7d97c5SJed Brown active_rank = master_proc; 24540c7d97c5SJed Brown break; 24550c7d97c5SJed Brown } 24560c7d97c5SJed Brown 24570c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 24580c7d97c5SJed Brown 24590c7d97c5SJed Brown case(SCATTERS_BDDC): 24600c7d97c5SJed Brown { 24610c7d97c5SJed Brown if (pcbddc->coarse_problem_type==MULTILEVEL_BDDC) { 24620c7d97c5SJed Brown 24632e8d2280SStefano Zampini IS coarse_IS; 24642e8d2280SStefano Zampini 2465523858cfSStefano Zampini if(pcbddc->coarsening_ratio == 1) { 2466523858cfSStefano Zampini ins_local_primal_size = pcbddc->local_primal_size; 2467523858cfSStefano Zampini ins_local_primal_indices = pcbddc->local_primal_indices; 2468523858cfSStefano Zampini if (coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 2469523858cfSStefano Zampini /* nonzeros */ 2470523858cfSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&dnz);CHKERRQ(ierr); 2471523858cfSStefano Zampini ierr = PetscMemzero(dnz,ins_local_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 2472523858cfSStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 2473523858cfSStefano Zampini dnz[i] = ins_local_primal_size; 2474523858cfSStefano Zampini } 2475523858cfSStefano Zampini } else { 24760c7d97c5SJed Brown PetscMPIInt send_size; 2477ef028eecSStefano Zampini PetscMPIInt *send_buffer; 24780c7d97c5SJed Brown PetscInt *aux_ins_indices; 24790c7d97c5SJed Brown PetscInt ii,jj; 24800c7d97c5SJed Brown MPI_Request *requests; 2481ef028eecSStefano Zampini 2482523858cfSStefano Zampini ierr = PetscMalloc(count_recv*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 2483523858cfSStefano Zampini /* reusing pcbddc->local_primal_displacements and pcbddc->replicated_primal_size */ 2484523858cfSStefano Zampini ierr = PetscFree(pcbddc->local_primal_displacements);CHKERRQ(ierr); 2485523858cfSStefano Zampini ierr = PetscMalloc((count_recv+1)*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 2486523858cfSStefano Zampini pcbddc->replicated_primal_size = count_recv; 2487523858cfSStefano Zampini j = 0; 2488523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 2489523858cfSStefano Zampini pcbddc->local_primal_displacements[i] = j; 2490523858cfSStefano Zampini j += pcbddc->local_primal_sizes[ranks_recv[i]]; 2491523858cfSStefano Zampini } 2492523858cfSStefano Zampini pcbddc->local_primal_displacements[count_recv] = j; 2493523858cfSStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 24940c7d97c5SJed Brown /* allocate auxiliary space */ 2495523858cfSStefano Zampini ierr = PetscMalloc(count_recv*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 24960c7d97c5SJed Brown ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscInt),&aux_ins_indices);CHKERRQ(ierr); 24970c7d97c5SJed Brown ierr = PetscMemzero(aux_ins_indices,pcbddc->coarse_size*sizeof(PetscInt));CHKERRQ(ierr); 24980c7d97c5SJed Brown /* allocate stuffs for message massing */ 24990c7d97c5SJed Brown ierr = PetscMalloc((count_recv+1)*sizeof(MPI_Request),&requests);CHKERRQ(ierr); 2500523858cfSStefano Zampini for (i=0;i<count_recv+1;i++) { requests[i]=MPI_REQUEST_NULL; } 2501523858cfSStefano Zampini /* send indices to be inserted */ 2502523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 2503523858cfSStefano Zampini send_size = pcbddc->local_primal_sizes[ranks_recv[i]]; 2504523858cfSStefano 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); 2505523858cfSStefano Zampini } 2506523858cfSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 2507523858cfSStefano Zampini send_size = pcbddc->local_primal_size; 2508ef028eecSStefano Zampini ierr = PetscMalloc(send_size*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 2509ef028eecSStefano Zampini for (i=0;i<send_size;i++) { 2510ef028eecSStefano Zampini send_buffer[i]=(PetscMPIInt)pcbddc->local_primal_indices[i]; 2511ef028eecSStefano Zampini } 2512ef028eecSStefano Zampini ierr = MPI_Isend(send_buffer,send_size,MPIU_INT,rank_coarse_proc_send_to,999,prec_comm,&requests[count_recv]);CHKERRQ(ierr); 2513523858cfSStefano Zampini } 2514523858cfSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2515ef028eecSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 2516ef028eecSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 2517ef028eecSStefano Zampini } 25180c7d97c5SJed Brown j = 0; 25190c7d97c5SJed Brown for (i=0;i<count_recv;i++) { 25202e8d2280SStefano Zampini ii = pcbddc->local_primal_displacements[i+1]-pcbddc->local_primal_displacements[i]; 25212e8d2280SStefano Zampini localsizes2[i] = ii*ii; 25220c7d97c5SJed Brown localdispl2[i] = j; 25230c7d97c5SJed Brown j += localsizes2[i]; 2524523858cfSStefano Zampini jj = pcbddc->local_primal_displacements[i]; 25254fad6a16SStefano Zampini /* it counts the coarse subdomains sharing the coarse node */ 25262e8d2280SStefano Zampini for (k=0;k<ii;k++) { 25274fad6a16SStefano Zampini aux_ins_indices[pcbddc->replicated_local_primal_indices[jj+k]] += 1; 25280c7d97c5SJed Brown } 25294fad6a16SStefano Zampini } 2530523858cfSStefano Zampini /* temp_coarse_mat_vals used to store matrix values to be received */ 25310c7d97c5SJed Brown ierr = PetscMalloc(j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 25320c7d97c5SJed Brown /* evaluate how many values I will insert in coarse mat */ 25330c7d97c5SJed Brown ins_local_primal_size = 0; 2534ea7e1babSStefano Zampini for (i=0;i<pcbddc->coarse_size;i++) { 2535ea7e1babSStefano Zampini if (aux_ins_indices[i]) { 25360c7d97c5SJed Brown ins_local_primal_size++; 2537ea7e1babSStefano Zampini } 2538ea7e1babSStefano Zampini } 25390c7d97c5SJed Brown /* evaluate indices I will insert in coarse mat */ 25400c7d97c5SJed Brown ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 25410c7d97c5SJed Brown j = 0; 2542ea7e1babSStefano Zampini for(i=0;i<pcbddc->coarse_size;i++) { 2543ea7e1babSStefano Zampini if(aux_ins_indices[i]) { 25442e8d2280SStefano Zampini ins_local_primal_indices[j] = i; 25452e8d2280SStefano Zampini j++; 2546ea7e1babSStefano Zampini } 2547ea7e1babSStefano Zampini } 2548523858cfSStefano Zampini /* processes partecipating in coarse problem receive matrix data from their friends */ 2549523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 2550523858cfSStefano Zampini ierr = MPI_Irecv(&temp_coarse_mat_vals[localdispl2[i]],localsizes2[i],MPIU_SCALAR,ranks_recv[i],666,prec_comm,&requests[i]);CHKERRQ(ierr); 2551523858cfSStefano Zampini } 2552523858cfSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 2553523858cfSStefano Zampini send_size = pcbddc->local_primal_size*pcbddc->local_primal_size; 2554523858cfSStefano 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); 2555523858cfSStefano Zampini } 2556523858cfSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2557523858cfSStefano Zampini /* nonzeros */ 2558523858cfSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&dnz);CHKERRQ(ierr); 2559523858cfSStefano Zampini ierr = PetscMemzero(dnz,ins_local_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 25600c7d97c5SJed Brown /* use aux_ins_indices to realize a global to local mapping */ 25610c7d97c5SJed Brown j=0; 25620c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++){ 25630c7d97c5SJed Brown if(aux_ins_indices[i]==0){ 25640c7d97c5SJed Brown aux_ins_indices[i]=-1; 25650c7d97c5SJed Brown } else { 25660c7d97c5SJed Brown aux_ins_indices[i]=j; 25670c7d97c5SJed Brown j++; 25680c7d97c5SJed Brown } 25690c7d97c5SJed Brown } 25704fad6a16SStefano Zampini for (i=0;i<count_recv;i++) { 2571523858cfSStefano Zampini j = pcbddc->local_primal_sizes[ranks_recv[i]]; 2572523858cfSStefano Zampini for (k=0;k<j;k++) { 2573523858cfSStefano Zampini dnz[aux_ins_indices[pcbddc->replicated_local_primal_indices[pcbddc->local_primal_displacements[i]+k]]] += j; 25740c7d97c5SJed Brown } 25750c7d97c5SJed Brown } 2576523858cfSStefano Zampini /* check */ 2577523858cfSStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 2578523858cfSStefano Zampini if (dnz[i] > ins_local_primal_size) { 2579523858cfSStefano Zampini dnz[i] = ins_local_primal_size; 25800c7d97c5SJed Brown } 25810c7d97c5SJed Brown } 25820c7d97c5SJed Brown ierr = PetscFree(requests);CHKERRQ(ierr); 25830c7d97c5SJed Brown ierr = PetscFree(aux_ins_indices);CHKERRQ(ierr); 25840c7d97c5SJed Brown if (coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 25854fad6a16SStefano Zampini } 25860c7d97c5SJed Brown /* create local to global mapping needed by coarse MATIS */ 2587142dfd88SStefano Zampini if (coarse_comm != MPI_COMM_NULL ) {ierr = MPI_Comm_free(&coarse_comm);CHKERRQ(ierr);} 25880c7d97c5SJed Brown coarse_comm = prec_comm; 25890c7d97c5SJed Brown active_rank = rank_prec_comm; 25900c7d97c5SJed Brown ierr = ISCreateGeneral(coarse_comm,ins_local_primal_size,ins_local_primal_indices,PETSC_COPY_VALUES,&coarse_IS);CHKERRQ(ierr); 25910c7d97c5SJed Brown ierr = ISLocalToGlobalMappingCreateIS(coarse_IS,&coarse_ISLG);CHKERRQ(ierr); 25920c7d97c5SJed Brown ierr = ISDestroy(&coarse_IS);CHKERRQ(ierr); 25932e8d2280SStefano Zampini } else if (pcbddc->coarse_problem_type==PARALLEL_BDDC) { 25940c7d97c5SJed Brown /* arrays for values insertion */ 25950c7d97c5SJed Brown ins_local_primal_size = pcbddc->local_primal_size; 25962e8d2280SStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 25970c7d97c5SJed Brown ierr = PetscMalloc(ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 25980c7d97c5SJed Brown for (j=0;j<ins_local_primal_size;j++){ 25990c7d97c5SJed Brown ins_local_primal_indices[j]=pcbddc->local_primal_indices[j]; 26004fad6a16SStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 26014fad6a16SStefano Zampini ins_coarse_mat_vals[j*ins_local_primal_size+i]=coarse_submat_vals[j*ins_local_primal_size+i]; 26024fad6a16SStefano Zampini } 26030c7d97c5SJed Brown } 26040c7d97c5SJed Brown } 26050c7d97c5SJed Brown break; 2606674ae819SStefano Zampini 26070c7d97c5SJed Brown } 26080c7d97c5SJed Brown 26090c7d97c5SJed Brown case(GATHERS_BDDC): 26100c7d97c5SJed Brown { 2611674ae819SStefano Zampini 26120c7d97c5SJed Brown PetscMPIInt mysize,mysize2; 2613ef028eecSStefano Zampini PetscMPIInt *send_buffer; 26140c7d97c5SJed Brown 26150c7d97c5SJed Brown if (rank_prec_comm==active_rank) { 26160c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 26170bdf917eSStefano Zampini ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscScalar),&pcbddc->replicated_local_primal_values);CHKERRQ(ierr); 26180c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 26190c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 26200c7d97c5SJed Brown /* arrays for values insertion */ 26212fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) localsizes2[i]=pcbddc->local_primal_sizes[i]*pcbddc->local_primal_sizes[i]; 26220c7d97c5SJed Brown localdispl2[0]=0; 26232fa5cd67SKarl Rupp for (i=1;i<size_prec_comm;i++) localdispl2[i]=localsizes2[i-1]+localdispl2[i-1]; 26240c7d97c5SJed Brown j=0; 26252fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) j+=localsizes2[i]; 26260c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 26270c7d97c5SJed Brown } 26280c7d97c5SJed Brown 26290c7d97c5SJed Brown mysize=pcbddc->local_primal_size; 26300c7d97c5SJed Brown mysize2=pcbddc->local_primal_size*pcbddc->local_primal_size; 2631ef028eecSStefano Zampini ierr = PetscMalloc(mysize*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 26322fa5cd67SKarl Rupp for (i=0; i<mysize; i++) send_buffer[i]=(PetscMPIInt)pcbddc->local_primal_indices[i]; 26332fa5cd67SKarl Rupp 26340c7d97c5SJed Brown if (pcbddc->coarse_problem_type == SEQUENTIAL_BDDC){ 2635ef028eecSStefano 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); 263653cdbc3dSStefano 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); 26370c7d97c5SJed Brown } else { 2638ef028eecSStefano 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); 263953cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,prec_comm);CHKERRQ(ierr); 26400c7d97c5SJed Brown } 2641ef028eecSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 26420c7d97c5SJed Brown break; 2643da1bb401SStefano Zampini }/* switch on coarse problem and communications associated with finished */ 26440c7d97c5SJed Brown } 26450c7d97c5SJed Brown 26460c7d97c5SJed Brown /* Now create and fill up coarse matrix */ 26470c7d97c5SJed Brown if ( rank_prec_comm == active_rank ) { 2648142dfd88SStefano Zampini 2649142dfd88SStefano Zampini Mat matis_coarse_local_mat; 2650142dfd88SStefano Zampini 26510c7d97c5SJed Brown if (pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 26520c7d97c5SJed Brown ierr = MatCreate(coarse_comm,&pcbddc->coarse_mat);CHKERRQ(ierr); 26530c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_mat,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size);CHKERRQ(ierr); 26540c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_mat,coarse_mat_type);CHKERRQ(ierr); 2655674ae819SStefano Zampini ierr = MatSetOptionsPrefix(pcbddc->coarse_mat,"coarse_");CHKERRQ(ierr); 2656674ae819SStefano Zampini ierr = MatSetFromOptions(pcbddc->coarse_mat);CHKERRQ(ierr); 26573b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 2658da1bb401SStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 26593b03a366Sstefano_zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 26600c7d97c5SJed Brown } else { 26614fad6a16SStefano Zampini ierr = MatCreateIS(coarse_comm,1,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_ISLG,&pcbddc->coarse_mat);CHKERRQ(ierr); 26623b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 26630c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 2664674ae819SStefano Zampini ierr = MatSetOptionsPrefix(pcbddc->coarse_mat,"coarse_");CHKERRQ(ierr); 2665674ae819SStefano Zampini ierr = MatSetFromOptions(pcbddc->coarse_mat);CHKERRQ(ierr); 26663b03a366Sstefano_zampini ierr = MatSetUp(matis_coarse_local_mat);CHKERRQ(ierr); 2667da1bb401SStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 2668a0ba757dSStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 26690c7d97c5SJed Brown } 2670142dfd88SStefano Zampini /* preallocation */ 2671142dfd88SStefano Zampini if (pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 2672ef028eecSStefano Zampini 2673674ae819SStefano Zampini PetscInt lrows,lcols,bs; 2674ef028eecSStefano Zampini 2675142dfd88SStefano Zampini ierr = MatGetLocalSize(pcbddc->coarse_mat,&lrows,&lcols);CHKERRQ(ierr); 2676142dfd88SStefano Zampini ierr = MatPreallocateInitialize(coarse_comm,lrows,lcols,dnz,onz);CHKERRQ(ierr); 2677674ae819SStefano Zampini ierr = MatGetBlockSize(pcbddc->coarse_mat,&bs);CHKERRQ(ierr); 2678ef028eecSStefano Zampini 2679142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == PARALLEL_BDDC) { 2680ef028eecSStefano Zampini 2681ef028eecSStefano Zampini Vec vec_dnz,vec_onz; 2682ef028eecSStefano Zampini PetscScalar *my_dnz,*my_onz,*array; 2683ef028eecSStefano Zampini PetscInt *mat_ranges,*row_ownership; 2684ef028eecSStefano Zampini PetscInt coarse_index_row,coarse_index_col,owner; 2685ef028eecSStefano Zampini 2686ef028eecSStefano Zampini ierr = VecCreate(prec_comm,&vec_dnz);CHKERRQ(ierr); 2687674ae819SStefano Zampini ierr = VecSetBlockSize(vec_dnz,bs);CHKERRQ(ierr); 2688ef028eecSStefano Zampini ierr = VecSetSizes(vec_dnz,PETSC_DECIDE,pcbddc->coarse_size);CHKERRQ(ierr); 2689ef028eecSStefano Zampini ierr = VecSetType(vec_dnz,VECMPI);CHKERRQ(ierr); 2690ef028eecSStefano Zampini ierr = VecDuplicate(vec_dnz,&vec_onz);CHKERRQ(ierr); 2691ef028eecSStefano Zampini 2692ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscScalar),&my_dnz);CHKERRQ(ierr); 2693ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscScalar),&my_onz);CHKERRQ(ierr); 2694ef028eecSStefano Zampini ierr = PetscMemzero(my_dnz,pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 2695ef028eecSStefano Zampini ierr = PetscMemzero(my_onz,pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 2696ef028eecSStefano Zampini 2697ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscInt),&row_ownership);CHKERRQ(ierr); 2698ef028eecSStefano Zampini ierr = MatGetOwnershipRanges(pcbddc->coarse_mat,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 2699142dfd88SStefano Zampini for (i=0;i<size_prec_comm;i++) { 2700ef028eecSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 2701ef028eecSStefano Zampini row_ownership[j]=i; 2702142dfd88SStefano Zampini } 2703142dfd88SStefano Zampini } 2704ef028eecSStefano Zampini 2705ef028eecSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 2706ef028eecSStefano Zampini coarse_index_row = pcbddc->local_primal_indices[i]; 2707ef028eecSStefano Zampini owner = row_ownership[coarse_index_row]; 2708ef028eecSStefano Zampini for (j=i;j<pcbddc->local_primal_size;j++) { 2709ef028eecSStefano Zampini owner = row_ownership[coarse_index_row]; 2710ef028eecSStefano Zampini coarse_index_col = pcbddc->local_primal_indices[j]; 2711ef028eecSStefano Zampini if (coarse_index_col > mat_ranges[owner]-1 && coarse_index_col < mat_ranges[owner+1] ) { 2712ef028eecSStefano Zampini my_dnz[i] += 1.0; 2713142dfd88SStefano Zampini } else { 2714ef028eecSStefano Zampini my_onz[i] += 1.0; 2715142dfd88SStefano Zampini } 2716ef028eecSStefano Zampini if (i != j) { 2717ef028eecSStefano Zampini owner = row_ownership[coarse_index_col]; 2718ef028eecSStefano Zampini if (coarse_index_row > mat_ranges[owner]-1 && coarse_index_row < mat_ranges[owner+1] ) { 2719ef028eecSStefano Zampini my_dnz[j] += 1.0; 2720142dfd88SStefano Zampini } else { 2721ef028eecSStefano Zampini my_onz[j] += 1.0; 2722142dfd88SStefano Zampini } 2723142dfd88SStefano Zampini } 2724142dfd88SStefano Zampini } 2725142dfd88SStefano Zampini } 2726ef028eecSStefano Zampini ierr = VecSet(vec_dnz,0.0);CHKERRQ(ierr); 2727ef028eecSStefano Zampini ierr = VecSet(vec_onz,0.0);CHKERRQ(ierr); 2728a929c220SStefano Zampini if (pcbddc->local_primal_size) { 2729ef028eecSStefano Zampini ierr = VecSetValues(vec_dnz,pcbddc->local_primal_size,pcbddc->local_primal_indices,my_dnz,ADD_VALUES);CHKERRQ(ierr); 2730ef028eecSStefano Zampini ierr = VecSetValues(vec_onz,pcbddc->local_primal_size,pcbddc->local_primal_indices,my_onz,ADD_VALUES);CHKERRQ(ierr); 2731a929c220SStefano Zampini } 2732ef028eecSStefano Zampini ierr = VecAssemblyBegin(vec_dnz);CHKERRQ(ierr); 2733ef028eecSStefano Zampini ierr = VecAssemblyBegin(vec_onz);CHKERRQ(ierr); 2734ef028eecSStefano Zampini ierr = VecAssemblyEnd(vec_dnz);CHKERRQ(ierr); 2735ef028eecSStefano Zampini ierr = VecAssemblyEnd(vec_onz);CHKERRQ(ierr); 2736ef028eecSStefano Zampini j = mat_ranges[rank_prec_comm+1]-mat_ranges[rank_prec_comm]; 2737ef028eecSStefano Zampini ierr = VecGetArray(vec_dnz,&array);CHKERRQ(ierr); 27382fa5cd67SKarl Rupp for (i=0; i<j; i++) dnz[i] = (PetscInt)array[i]; 27392fa5cd67SKarl Rupp 2740ef028eecSStefano Zampini ierr = VecRestoreArray(vec_dnz,&array);CHKERRQ(ierr); 2741ef028eecSStefano Zampini ierr = VecGetArray(vec_onz,&array);CHKERRQ(ierr); 27422fa5cd67SKarl Rupp for (i=0;i<j;i++) onz[i] = (PetscInt)array[i]; 27432fa5cd67SKarl Rupp 2744ef028eecSStefano Zampini ierr = VecRestoreArray(vec_onz,&array);CHKERRQ(ierr); 2745ef028eecSStefano Zampini ierr = PetscFree(my_dnz);CHKERRQ(ierr); 2746ef028eecSStefano Zampini ierr = PetscFree(my_onz);CHKERRQ(ierr); 2747ef028eecSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 2748ef028eecSStefano Zampini ierr = VecDestroy(&vec_dnz);CHKERRQ(ierr); 2749ef028eecSStefano Zampini ierr = VecDestroy(&vec_onz);CHKERRQ(ierr); 2750142dfd88SStefano Zampini } else { 2751142dfd88SStefano Zampini for (k=0;k<size_prec_comm;k++){ 2752142dfd88SStefano Zampini offset=pcbddc->local_primal_displacements[k]; 2753142dfd88SStefano Zampini offset2=localdispl2[k]; 2754142dfd88SStefano Zampini ins_local_primal_size = pcbddc->local_primal_sizes[k]; 2755ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2756ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2757ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2758ef028eecSStefano Zampini } 2759142dfd88SStefano Zampini for (j=0;j<ins_local_primal_size;j++) { 2760142dfd88SStefano Zampini ierr = MatPreallocateSet(ins_local_primal_indices[j],ins_local_primal_size,ins_local_primal_indices,dnz,onz);CHKERRQ(ierr); 2761142dfd88SStefano Zampini } 2762ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2763142dfd88SStefano Zampini } 2764142dfd88SStefano Zampini } 27652fa5cd67SKarl Rupp 2766142dfd88SStefano Zampini /* check */ 2767142dfd88SStefano Zampini for (i=0;i<lrows;i++) { 27682fa5cd67SKarl Rupp if (dnz[i]>lcols) dnz[i]=lcols; 27692fa5cd67SKarl Rupp if (onz[i]>pcbddc->coarse_size-lcols) onz[i]=pcbddc->coarse_size-lcols; 2770142dfd88SStefano Zampini } 2771d9a4edebSJed Brown ierr = MatSeqAIJSetPreallocation(pcbddc->coarse_mat,0,dnz);CHKERRQ(ierr); 2772d9a4edebSJed Brown ierr = MatMPIAIJSetPreallocation(pcbddc->coarse_mat,0,dnz,0,onz);CHKERRQ(ierr); 2773142dfd88SStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 2774142dfd88SStefano Zampini } else { 2775523858cfSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis_coarse_local_mat,0,dnz);CHKERRQ(ierr); 2776523858cfSStefano Zampini ierr = PetscFree(dnz);CHKERRQ(ierr); 2777142dfd88SStefano Zampini } 2778142dfd88SStefano Zampini /* insert values */ 2779523858cfSStefano Zampini if (pcbddc->coarse_problem_type == PARALLEL_BDDC) { 27800c7d97c5SJed 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); 2781523858cfSStefano Zampini } else if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2782523858cfSStefano Zampini if (pcbddc->coarsening_ratio == 1) { 2783523858cfSStefano Zampini ins_coarse_mat_vals = coarse_submat_vals; 2784523858cfSStefano 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); 2785523858cfSStefano Zampini } else { 2786523858cfSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2787523858cfSStefano Zampini for (k=0;k<pcbddc->replicated_primal_size;k++) { 2788523858cfSStefano Zampini offset = pcbddc->local_primal_displacements[k]; 2789523858cfSStefano Zampini offset2 = localdispl2[k]; 2790523858cfSStefano Zampini ins_local_primal_size = pcbddc->local_primal_displacements[k+1]-pcbddc->local_primal_displacements[k]; 2791ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2792ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2793ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2794ef028eecSStefano Zampini } 2795523858cfSStefano Zampini ins_coarse_mat_vals = &temp_coarse_mat_vals[offset2]; 2796523858cfSStefano 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); 2797ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2798523858cfSStefano Zampini } 2799523858cfSStefano Zampini } 2800523858cfSStefano Zampini ins_local_primal_indices = 0; 2801523858cfSStefano Zampini ins_coarse_mat_vals = 0; 2802ea7e1babSStefano Zampini } else { 2803ea7e1babSStefano Zampini for (k=0;k<size_prec_comm;k++){ 2804ea7e1babSStefano Zampini offset=pcbddc->local_primal_displacements[k]; 2805ea7e1babSStefano Zampini offset2=localdispl2[k]; 2806ea7e1babSStefano Zampini ins_local_primal_size = pcbddc->local_primal_sizes[k]; 2807ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2808ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2809ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2810ef028eecSStefano Zampini } 2811ea7e1babSStefano Zampini ins_coarse_mat_vals = &temp_coarse_mat_vals[offset2]; 2812ea7e1babSStefano 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); 2813ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2814ea7e1babSStefano Zampini } 2815ea7e1babSStefano Zampini ins_local_primal_indices = 0; 2816ea7e1babSStefano Zampini ins_coarse_mat_vals = 0; 2817ea7e1babSStefano Zampini } 28180c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28190c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2820142dfd88SStefano Zampini /* symmetry of coarse matrix */ 2821142dfd88SStefano Zampini if (issym) { 2822142dfd88SStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 2823142dfd88SStefano Zampini } 28240c7d97c5SJed Brown ierr = MatGetVecs(pcbddc->coarse_mat,&pcbddc->coarse_vec,&pcbddc->coarse_rhs);CHKERRQ(ierr); 28250bdf917eSStefano Zampini } 28260bdf917eSStefano Zampini 28270bdf917eSStefano Zampini /* create loc to glob scatters if needed */ 28280bdf917eSStefano Zampini if (pcbddc->coarse_communications_type == SCATTERS_BDDC) { 28290bdf917eSStefano Zampini IS local_IS,global_IS; 28300bdf917eSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&local_IS);CHKERRQ(ierr); 28310bdf917eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_indices,PETSC_COPY_VALUES,&global_IS);CHKERRQ(ierr); 28320bdf917eSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,local_IS,pcbddc->coarse_vec,global_IS,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 28330bdf917eSStefano Zampini ierr = ISDestroy(&local_IS);CHKERRQ(ierr); 28340bdf917eSStefano Zampini ierr = ISDestroy(&global_IS);CHKERRQ(ierr); 28350bdf917eSStefano Zampini } 28360bdf917eSStefano Zampini 2837a929c220SStefano Zampini /* free memory no longer needed */ 2838a929c220SStefano Zampini if (coarse_ISLG) { ierr = ISLocalToGlobalMappingDestroy(&coarse_ISLG);CHKERRQ(ierr); } 2839a929c220SStefano Zampini if (ins_local_primal_indices) { ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); } 2840a929c220SStefano Zampini if (ins_coarse_mat_vals) { ierr = PetscFree(ins_coarse_mat_vals);CHKERRQ(ierr); } 2841a929c220SStefano Zampini if (localsizes2) { ierr = PetscFree(localsizes2);CHKERRQ(ierr); } 2842a929c220SStefano Zampini if (localdispl2) { ierr = PetscFree(localdispl2);CHKERRQ(ierr); } 2843a929c220SStefano Zampini if (temp_coarse_mat_vals) { ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr); } 2844a929c220SStefano Zampini 2845674ae819SStefano Zampini /* Compute coarse null space */ 2846674ae819SStefano Zampini CoarseNullSpace = 0; 28470bdf917eSStefano Zampini if (pcbddc->NullSpace) { 2848674ae819SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,&CoarseNullSpace);CHKERRQ(ierr); 28490bdf917eSStefano Zampini } 28500bdf917eSStefano Zampini 28510bdf917eSStefano Zampini /* KSP for coarse problem */ 28520bdf917eSStefano Zampini if (rank_prec_comm == active_rank) { 28532e8d2280SStefano Zampini PetscBool isbddc=PETSC_FALSE; 28540bdf917eSStefano Zampini 285553cdbc3dSStefano Zampini ierr = KSPCreate(coarse_comm,&pcbddc->coarse_ksp);CHKERRQ(ierr); 285653cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 285753cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 28583b03a366Sstefano_zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,max_it_coarse_ksp);CHKERRQ(ierr); 285953cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 286053cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 286153cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 28620c7d97c5SJed Brown /* Allow user's customization */ 2863da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,"coarse_");CHKERRQ(ierr); 28640c7d97c5SJed Brown /* Set Up PC for coarse problem BDDC */ 286553cdbc3dSStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 28664fad6a16SStefano Zampini i = pcbddc->current_level+1; 28674fad6a16SStefano Zampini ierr = PCBDDCSetLevel(pc_temp,i);CHKERRQ(ierr); 28684fad6a16SStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 28694fad6a16SStefano Zampini ierr = PCBDDCSetMaxLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 287053cdbc3dSStefano Zampini ierr = PCBDDCSetCoarseProblemType(pc_temp,MULTILEVEL_BDDC);CHKERRQ(ierr); 2871674ae819SStefano Zampini if (CoarseNullSpace) { 2872674ae819SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 2873674ae819SStefano Zampini } 28744fad6a16SStefano Zampini if (dbg_flag) { 28754fad6a16SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------Level %d: Setting up level %d---------------\n",pcbddc->current_level,i);CHKERRQ(ierr); 28764fad6a16SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 287753cdbc3dSStefano Zampini } 2878674ae819SStefano Zampini } else { 2879674ae819SStefano Zampini if (CoarseNullSpace) { 2880674ae819SStefano Zampini ierr = KSPSetNullSpace(pcbddc->coarse_ksp,CoarseNullSpace);CHKERRQ(ierr); 2881674ae819SStefano Zampini } 28824fad6a16SStefano Zampini } 28834fad6a16SStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 288453cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 2885142dfd88SStefano Zampini 28860298fd71SBarry Smith ierr = KSPGetTolerances(pcbddc->coarse_ksp,NULL,NULL,NULL,&j);CHKERRQ(ierr); 28872e8d2280SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 28882e8d2280SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 28892e8d2280SStefano Zampini if (j == 1) { 28902e8d2280SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 28912e8d2280SStefano Zampini if (isbddc) { 28922e8d2280SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc_temp,PETSC_FALSE);CHKERRQ(ierr); 28935619798eSStefano Zampini } 28945619798eSStefano Zampini } 28950c7d97c5SJed Brown } 2896a929c220SStefano Zampini /* Check coarse problem if requested */ 2897142dfd88SStefano Zampini if ( dbg_flag && rank_prec_comm == active_rank ) { 2898142dfd88SStefano Zampini KSP check_ksp; 2899142dfd88SStefano Zampini PC check_pc; 2900142dfd88SStefano Zampini Vec check_vec; 2901142dfd88SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min,lambda_max; 290219fd82e9SBarry Smith KSPType check_ksp_type; 29030c7d97c5SJed Brown 2904142dfd88SStefano Zampini /* Create ksp object suitable for extreme eigenvalues' estimation */ 2905142dfd88SStefano Zampini ierr = KSPCreate(coarse_comm,&check_ksp);CHKERRQ(ierr); 2906142dfd88SStefano Zampini ierr = KSPSetOperators(check_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 29070bdf917eSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 2908142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 29092fa5cd67SKarl Rupp if (issym) check_ksp_type = KSPCG; 29102fa5cd67SKarl Rupp else check_ksp_type = KSPGMRES; 2911142dfd88SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,PETSC_TRUE);CHKERRQ(ierr); 2912142dfd88SStefano Zampini } else { 2913142dfd88SStefano Zampini check_ksp_type = KSPPREONLY; 2914142dfd88SStefano Zampini } 2915142dfd88SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 2916142dfd88SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 2917142dfd88SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 2918142dfd88SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 2919142dfd88SStefano Zampini /* create random vec */ 2920142dfd88SStefano Zampini ierr = VecDuplicate(pcbddc->coarse_vec,&check_vec);CHKERRQ(ierr); 29210298fd71SBarry Smith ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 2922674ae819SStefano Zampini if (CoarseNullSpace) { 2923674ae819SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec,NULL);CHKERRQ(ierr); 2924674ae819SStefano Zampini } 2925142dfd88SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,check_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 2926142dfd88SStefano Zampini /* solve coarse problem */ 2927142dfd88SStefano Zampini ierr = KSPSolve(check_ksp,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 2928674ae819SStefano Zampini if (CoarseNullSpace) { 2929674ae819SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 2930674ae819SStefano Zampini } 2931142dfd88SStefano Zampini /* check coarse problem residual error */ 2932142dfd88SStefano Zampini ierr = VecAXPY(check_vec,-1.0,pcbddc->coarse_vec);CHKERRQ(ierr); 2933142dfd88SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 2934142dfd88SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,check_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 2935142dfd88SStefano Zampini ierr = VecNorm(pcbddc->coarse_rhs,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 2936142dfd88SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 2937142dfd88SStefano Zampini /* get eigenvalue estimation if inexact */ 2938142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2939142dfd88SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); 2940142dfd88SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&k);CHKERRQ(ierr); 2941142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues estimated with %d iterations of %s.\n",k,check_ksp_type);CHKERRQ(ierr); 2942e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues: % 1.14e %1.14e\n",lambda_min,lambda_max);CHKERRQ(ierr); 29433b03a366Sstefano_zampini } 2944142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem exact infty_error : %1.14e\n",infty_error);CHKERRQ(ierr); 2945142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem residual infty_error: %1.14e\n",abs_infty_error);CHKERRQ(ierr); 2946142dfd88SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 294753cdbc3dSStefano Zampini } 2948674ae819SStefano Zampini if (dbg_flag) { 2949da1bb401SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2950da1bb401SStefano Zampini } 2951674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 2952a0ba757dSStefano Zampini 29530c7d97c5SJed Brown PetscFunctionReturn(0); 29540c7d97c5SJed Brown } 29550c7d97c5SJed Brown 2956