153cdbc3dSStefano Zampini /* TODOLIST 2da1bb401SStefano Zampini DofSplitting and DM attached to pc? 3da1bb401SStefano Zampini Change SetNeumannBoundaries to SetNeumannBoundariesLocal and provide new SetNeumannBoundaries (same Dirichlet) 4a0ba757dSStefano Zampini change how to deal with the coarse problem (PCBDDCSetCoarseEnvironment): 5a0ba757dSStefano Zampini - simplify coarse problem structure -> PCBDDC or PCREDUDANT, nothing else -> same comm for all levels? 6a0ba757dSStefano Zampini - remove coarse enums and allow use of PCBDDCGetCoarseKSP 7674ae819SStefano Zampini - remove metis dependency -> use MatPartitioning for multilevel -> Assemble serial adjacency in PCBDDCAnalyzeInterface? 8a0ba757dSStefano Zampini code refactoring: 9a0ba757dSStefano Zampini - pick up better names for static functions 10a0ba757dSStefano Zampini change options structure: 11a0ba757dSStefano Zampini - insert BDDC into MG framework? 12a0ba757dSStefano Zampini provide other ops? Ask to developers 13a0ba757dSStefano Zampini remove all unused printf 14a0ba757dSStefano Zampini man pages 1553cdbc3dSStefano Zampini */ 160c7d97c5SJed Brown 1753cdbc3dSStefano Zampini /* ---------------------------------------------------------------------------------------------------------------------------------------------- 180c7d97c5SJed Brown Implementation of BDDC preconditioner based on: 190c7d97c5SJed Brown C. Dohrmann "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 2053cdbc3dSStefano Zampini ---------------------------------------------------------------------------------------------------------------------------------------------- */ 2153cdbc3dSStefano Zampini 22674ae819SStefano Zampini #include "bddc.h" /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 23674ae819SStefano Zampini #include "bddcprivate.h" 243b03a366Sstefano_zampini #include <petscblaslapack.h> 25674ae819SStefano Zampini 26674ae819SStefano Zampini /* prototypes for static functions contained in bddc.c */ 27674ae819SStefano Zampini static PetscErrorCode PCBDDCSetLevel(PC,PetscInt); 28674ae819SStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC); 29674ae819SStefano Zampini static PetscErrorCode PCBDDCSetUpCoarseEnvironment(PC,PetscScalar*); 30674ae819SStefano Zampini 310c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 320c7d97c5SJed Brown #undef __FUNCT__ 330c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC" 340c7d97c5SJed Brown PetscErrorCode PCSetFromOptions_BDDC(PC pc) 350c7d97c5SJed Brown { 360c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 370c7d97c5SJed Brown PetscErrorCode ierr; 380c7d97c5SJed Brown 390c7d97c5SJed Brown PetscFunctionBegin; 400c7d97c5SJed Brown ierr = PetscOptionsHead("BDDC options");CHKERRQ(ierr); 410c7d97c5SJed Brown /* Verbose debugging of main data structures */ 429d9e44b6SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_check_level" ,"Verbose (debugging) output for PCBDDC" ,"none",pcbddc->dbg_flag ,&pcbddc->dbg_flag ,NULL);CHKERRQ(ierr); 430c7d97c5SJed Brown /* Some customization for default primal space */ 440298fd71SBarry 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); 450298fd71SBarry 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); 460298fd71SBarry 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); 470298fd71SBarry 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); 480c7d97c5SJed Brown /* Coarse solver context */ 496c667b0aSStefano 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 */ 500298fd71SBarry 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); 510c7d97c5SJed Brown /* Two different application of BDDC to the whole set of dofs, internal and interface */ 520298fd71SBarry 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); 53674ae819SStefano 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); 54674ae819SStefano 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); 55674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 56674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 57674ae819SStefano Zampini } 580298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr); 590298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_max_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr); 60674ae819SStefano 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); 610c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 620c7d97c5SJed Brown PetscFunctionReturn(0); 630c7d97c5SJed Brown } 640c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 65674ae819SStefano Zampini #undef __FUNCT__ 66674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS_BDDC" 67674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 68674ae819SStefano Zampini { 69674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 70674ae819SStefano Zampini PetscErrorCode ierr; 711e6b0712SBarry Smith 72674ae819SStefano Zampini PetscFunctionBegin; 73674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 74674ae819SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 75674ae819SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 76674ae819SStefano Zampini PetscFunctionReturn(0); 77674ae819SStefano Zampini } 78674ae819SStefano Zampini #undef __FUNCT__ 79674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS" 80674ae819SStefano Zampini /*@ 81674ae819SStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set user defined primal vertices in PCBDDC. 82674ae819SStefano Zampini 83674ae819SStefano Zampini Not collective 84674ae819SStefano Zampini 85674ae819SStefano Zampini Input Parameters: 86674ae819SStefano Zampini + pc - the preconditioning context 87674ae819SStefano Zampini - PrimalVertices - index sets of primal vertices in local numbering 88674ae819SStefano Zampini 89674ae819SStefano Zampini Level: intermediate 90674ae819SStefano Zampini 91674ae819SStefano Zampini Notes: 92674ae819SStefano Zampini 93674ae819SStefano Zampini .seealso: PCBDDC 94674ae819SStefano Zampini @*/ 95674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 96674ae819SStefano Zampini { 97674ae819SStefano Zampini PetscErrorCode ierr; 98674ae819SStefano Zampini 99674ae819SStefano Zampini PetscFunctionBegin; 100674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 101674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 102674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 103674ae819SStefano Zampini PetscFunctionReturn(0); 104674ae819SStefano Zampini } 105674ae819SStefano Zampini /* -------------------------------------------------------------------------- */ 1060c7d97c5SJed Brown #undef __FUNCT__ 1070c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType_BDDC" 10853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetCoarseProblemType_BDDC(PC pc, CoarseProblemType CPT) 1090c7d97c5SJed Brown { 1100c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1110c7d97c5SJed Brown 1120c7d97c5SJed Brown PetscFunctionBegin; 1130c7d97c5SJed Brown pcbddc->coarse_problem_type = CPT; 1140c7d97c5SJed Brown PetscFunctionReturn(0); 1150c7d97c5SJed Brown } 1161e6b0712SBarry Smith 1170c7d97c5SJed Brown #undef __FUNCT__ 1180c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType" 11953cdbc3dSStefano Zampini /*@ 1209c0446d6SStefano Zampini PCBDDCSetCoarseProblemType - Set coarse problem type in PCBDDC. 12153cdbc3dSStefano Zampini 1229c0446d6SStefano Zampini Not collective 12353cdbc3dSStefano Zampini 12453cdbc3dSStefano Zampini Input Parameters: 12553cdbc3dSStefano Zampini + pc - the preconditioning context 12653cdbc3dSStefano Zampini - CoarseProblemType - pick a better name and explain what this is 12753cdbc3dSStefano Zampini 12853cdbc3dSStefano Zampini Level: intermediate 12953cdbc3dSStefano Zampini 13053cdbc3dSStefano Zampini Notes: 131da1bb401SStefano Zampini Not collective but all procs must call with same arguments. 13253cdbc3dSStefano Zampini 13353cdbc3dSStefano Zampini .seealso: PCBDDC 13453cdbc3dSStefano Zampini @*/ 1350c7d97c5SJed Brown PetscErrorCode PCBDDCSetCoarseProblemType(PC pc, CoarseProblemType CPT) 1360c7d97c5SJed Brown { 1370c7d97c5SJed Brown PetscErrorCode ierr; 1380c7d97c5SJed Brown 1390c7d97c5SJed Brown PetscFunctionBegin; 1400c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1410c7d97c5SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetCoarseProblemType_C",(PC,CoarseProblemType),(pc,CPT));CHKERRQ(ierr); 1420c7d97c5SJed Brown PetscFunctionReturn(0); 1430c7d97c5SJed Brown } 1440c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1450c7d97c5SJed Brown #undef __FUNCT__ 1464fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio_BDDC" 1474fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 1484fad6a16SStefano Zampini { 1494fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1504fad6a16SStefano Zampini 1514fad6a16SStefano Zampini PetscFunctionBegin; 1524fad6a16SStefano Zampini pcbddc->coarsening_ratio=k; 1534fad6a16SStefano Zampini PetscFunctionReturn(0); 1544fad6a16SStefano Zampini } 1551e6b0712SBarry Smith 1564fad6a16SStefano Zampini #undef __FUNCT__ 1574fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio" 1584fad6a16SStefano Zampini /*@ 1594fad6a16SStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel coarsening 1604fad6a16SStefano Zampini 1614fad6a16SStefano Zampini Logically collective on PC 1624fad6a16SStefano Zampini 1634fad6a16SStefano Zampini Input Parameters: 1644fad6a16SStefano Zampini + pc - the preconditioning context 1654fad6a16SStefano Zampini - k - coarsening ratio 1664fad6a16SStefano Zampini 1674fad6a16SStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level. 1684fad6a16SStefano Zampini 1694fad6a16SStefano Zampini Level: intermediate 1704fad6a16SStefano Zampini 1714fad6a16SStefano Zampini Notes: 1724fad6a16SStefano Zampini 1734fad6a16SStefano Zampini .seealso: PCBDDC 1744fad6a16SStefano Zampini @*/ 1754fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 1764fad6a16SStefano Zampini { 1774fad6a16SStefano Zampini PetscErrorCode ierr; 1784fad6a16SStefano Zampini 1794fad6a16SStefano Zampini PetscFunctionBegin; 1804fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1814fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 1824fad6a16SStefano Zampini PetscFunctionReturn(0); 1834fad6a16SStefano Zampini } 1844fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 1851e6b0712SBarry Smith 1864fad6a16SStefano Zampini #undef __FUNCT__ 1874fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetMaxLevels_BDDC" 1884fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetMaxLevels_BDDC(PC pc,PetscInt max_levels) 1894fad6a16SStefano Zampini { 1904fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1914fad6a16SStefano Zampini 1924fad6a16SStefano Zampini PetscFunctionBegin; 1934fad6a16SStefano Zampini pcbddc->max_levels=max_levels; 1944fad6a16SStefano Zampini PetscFunctionReturn(0); 1954fad6a16SStefano Zampini } 1961e6b0712SBarry Smith 1974fad6a16SStefano Zampini #undef __FUNCT__ 1984fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetMaxLevels" 1994fad6a16SStefano Zampini /*@ 2004fad6a16SStefano Zampini PCBDDCSetMaxLevels - Sets the maximum number of levels within the multilevel approach. 2014fad6a16SStefano Zampini 2024fad6a16SStefano Zampini Logically collective on PC 2034fad6a16SStefano Zampini 2044fad6a16SStefano Zampini Input Parameters: 2054fad6a16SStefano Zampini + pc - the preconditioning context 2064fad6a16SStefano Zampini - max_levels - the maximum number of levels 2074fad6a16SStefano Zampini 2084fad6a16SStefano Zampini Default value is 1, i.e. coarse problem will be solved inexactly with one application 2094fad6a16SStefano Zampini of PCBDDC preconditioner if the multilevel approach is requested. 2104fad6a16SStefano Zampini 2114fad6a16SStefano Zampini Level: intermediate 2124fad6a16SStefano Zampini 2134fad6a16SStefano Zampini Notes: 2144fad6a16SStefano Zampini 2154fad6a16SStefano Zampini .seealso: PCBDDC 2164fad6a16SStefano Zampini @*/ 2174fad6a16SStefano Zampini PetscErrorCode PCBDDCSetMaxLevels(PC pc,PetscInt max_levels) 2184fad6a16SStefano Zampini { 2194fad6a16SStefano Zampini PetscErrorCode ierr; 2204fad6a16SStefano Zampini 2214fad6a16SStefano Zampini PetscFunctionBegin; 2224fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2234fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetMaxLevels_C",(PC,PetscInt),(pc,max_levels));CHKERRQ(ierr); 2244fad6a16SStefano Zampini PetscFunctionReturn(0); 2254fad6a16SStefano Zampini } 2264fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 2271e6b0712SBarry Smith 2284fad6a16SStefano Zampini #undef __FUNCT__ 2290bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace_BDDC" 2300bdf917eSStefano Zampini static PetscErrorCode PCBDDCSetNullSpace_BDDC(PC pc,MatNullSpace NullSpace) 2310bdf917eSStefano Zampini { 2320bdf917eSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2330bdf917eSStefano Zampini PetscErrorCode ierr; 2340bdf917eSStefano Zampini 2350bdf917eSStefano Zampini PetscFunctionBegin; 2360bdf917eSStefano Zampini ierr = PetscObjectReference((PetscObject)NullSpace);CHKERRQ(ierr); 2370bdf917eSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 2380bdf917eSStefano Zampini pcbddc->NullSpace=NullSpace; 2390bdf917eSStefano Zampini PetscFunctionReturn(0); 2400bdf917eSStefano Zampini } 2411e6b0712SBarry Smith 2420bdf917eSStefano Zampini #undef __FUNCT__ 2430bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace" 2440bdf917eSStefano Zampini /*@ 2450bdf917eSStefano Zampini PCBDDCSetNullSpace - Set NullSpace of global operator of BDDC preconditioned mat. 2460bdf917eSStefano Zampini 2470bdf917eSStefano Zampini Logically collective on PC and MatNullSpace 2480bdf917eSStefano Zampini 2490bdf917eSStefano Zampini Input Parameters: 2500bdf917eSStefano Zampini + pc - the preconditioning context 2510bdf917eSStefano Zampini - NullSpace - Null space of the linear operator to be preconditioned. 2520bdf917eSStefano Zampini 2530bdf917eSStefano Zampini Level: intermediate 2540bdf917eSStefano Zampini 2550bdf917eSStefano Zampini Notes: 2560bdf917eSStefano Zampini 2570bdf917eSStefano Zampini .seealso: PCBDDC 2580bdf917eSStefano Zampini @*/ 2590bdf917eSStefano Zampini PetscErrorCode PCBDDCSetNullSpace(PC pc,MatNullSpace NullSpace) 2600bdf917eSStefano Zampini { 2610bdf917eSStefano Zampini PetscErrorCode ierr; 2620bdf917eSStefano Zampini 2630bdf917eSStefano Zampini PetscFunctionBegin; 2640bdf917eSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 265674ae819SStefano Zampini PetscValidHeaderSpecific(NullSpace,MAT_NULLSPACE_CLASSID,2); 2660bdf917eSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNullSpace_C",(PC,MatNullSpace),(pc,NullSpace));CHKERRQ(ierr); 2670bdf917eSStefano Zampini PetscFunctionReturn(0); 2680bdf917eSStefano Zampini } 2690bdf917eSStefano Zampini /* -------------------------------------------------------------------------- */ 2701e6b0712SBarry Smith 2710bdf917eSStefano Zampini #undef __FUNCT__ 2723b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC" 2733b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 2743b03a366Sstefano_zampini { 2753b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2763b03a366Sstefano_zampini PetscErrorCode ierr; 2773b03a366Sstefano_zampini 2783b03a366Sstefano_zampini PetscFunctionBegin; 2793b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 28036e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 28136e030ebSStefano Zampini pcbddc->DirichletBoundaries=DirichletBoundaries; 2823b03a366Sstefano_zampini PetscFunctionReturn(0); 2833b03a366Sstefano_zampini } 2841e6b0712SBarry Smith 2853b03a366Sstefano_zampini #undef __FUNCT__ 2863b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries" 2873b03a366Sstefano_zampini /*@ 288da1bb401SStefano Zampini PCBDDCSetDirichletBoundaries - Set index set defining subdomain part (in local ordering) 289da1bb401SStefano Zampini of Dirichlet boundaries for the global problem. 2903b03a366Sstefano_zampini 2913b03a366Sstefano_zampini Not collective 2923b03a366Sstefano_zampini 2933b03a366Sstefano_zampini Input Parameters: 2943b03a366Sstefano_zampini + pc - the preconditioning context 2950298fd71SBarry Smith - DirichletBoundaries - sequential index set defining the subdomain part of Dirichlet boundaries (can be NULL) 2963b03a366Sstefano_zampini 2973b03a366Sstefano_zampini Level: intermediate 2983b03a366Sstefano_zampini 2993b03a366Sstefano_zampini Notes: 3003b03a366Sstefano_zampini 3013b03a366Sstefano_zampini .seealso: PCBDDC 3023b03a366Sstefano_zampini @*/ 3033b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 3043b03a366Sstefano_zampini { 3053b03a366Sstefano_zampini PetscErrorCode ierr; 3063b03a366Sstefano_zampini 3073b03a366Sstefano_zampini PetscFunctionBegin; 3083b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 309674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 3103b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 3113b03a366Sstefano_zampini PetscFunctionReturn(0); 3123b03a366Sstefano_zampini } 3133b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 3141e6b0712SBarry Smith 3153b03a366Sstefano_zampini #undef __FUNCT__ 3160c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 31753cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 3180c7d97c5SJed Brown { 3190c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 32053cdbc3dSStefano Zampini PetscErrorCode ierr; 3210c7d97c5SJed Brown 3220c7d97c5SJed Brown PetscFunctionBegin; 32353cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 32436e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 32536e030ebSStefano Zampini pcbddc->NeumannBoundaries=NeumannBoundaries; 3260c7d97c5SJed Brown PetscFunctionReturn(0); 3270c7d97c5SJed Brown } 3281e6b0712SBarry Smith 3290c7d97c5SJed Brown #undef __FUNCT__ 3300c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 33157527edcSJed Brown /*@ 332da1bb401SStefano Zampini PCBDDCSetNeumannBoundaries - Set index set defining subdomain part (in local ordering) 333da1bb401SStefano Zampini of Neumann boundaries for the global problem. 33457527edcSJed Brown 3359c0446d6SStefano Zampini Not collective 33657527edcSJed Brown 33757527edcSJed Brown Input Parameters: 33857527edcSJed Brown + pc - the preconditioning context 3390298fd71SBarry Smith - NeumannBoundaries - sequential index set defining the subdomain part of Neumann boundaries (can be NULL) 34057527edcSJed Brown 34157527edcSJed Brown Level: intermediate 34257527edcSJed Brown 34357527edcSJed Brown Notes: 34457527edcSJed Brown 34557527edcSJed Brown .seealso: PCBDDC 34657527edcSJed Brown @*/ 34753cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 3480c7d97c5SJed Brown { 3490c7d97c5SJed Brown PetscErrorCode ierr; 3500c7d97c5SJed Brown 3510c7d97c5SJed Brown PetscFunctionBegin; 3520c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 353674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 35453cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 35553cdbc3dSStefano Zampini PetscFunctionReturn(0); 35653cdbc3dSStefano Zampini } 35753cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 3581e6b0712SBarry Smith 35953cdbc3dSStefano Zampini #undef __FUNCT__ 360da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC" 361da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 362da1bb401SStefano Zampini { 363da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 364da1bb401SStefano Zampini 365da1bb401SStefano Zampini PetscFunctionBegin; 366da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 367da1bb401SStefano Zampini PetscFunctionReturn(0); 368da1bb401SStefano Zampini } 3691e6b0712SBarry Smith 370da1bb401SStefano Zampini #undef __FUNCT__ 371da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries" 372da1bb401SStefano Zampini /*@ 373da1bb401SStefano Zampini PCBDDCGetDirichletBoundaries - Get index set defining subdomain part (in local ordering) 374da1bb401SStefano Zampini of Dirichlet boundaries for the global problem. 375da1bb401SStefano Zampini 376da1bb401SStefano Zampini Not collective 377da1bb401SStefano Zampini 378da1bb401SStefano Zampini Input Parameters: 379da1bb401SStefano Zampini + pc - the preconditioning context 380da1bb401SStefano Zampini 381da1bb401SStefano Zampini Output Parameters: 382da1bb401SStefano Zampini + DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 383da1bb401SStefano Zampini 384da1bb401SStefano Zampini Level: intermediate 385da1bb401SStefano Zampini 386da1bb401SStefano Zampini Notes: 387da1bb401SStefano Zampini 388da1bb401SStefano Zampini .seealso: PCBDDC 389da1bb401SStefano Zampini @*/ 390da1bb401SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 391da1bb401SStefano Zampini { 392da1bb401SStefano Zampini PetscErrorCode ierr; 393da1bb401SStefano Zampini 394da1bb401SStefano Zampini PetscFunctionBegin; 395da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 396da1bb401SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 397da1bb401SStefano Zampini PetscFunctionReturn(0); 398da1bb401SStefano Zampini } 399da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 4001e6b0712SBarry Smith 401da1bb401SStefano Zampini #undef __FUNCT__ 40253cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 40353cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 40453cdbc3dSStefano Zampini { 40553cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 40653cdbc3dSStefano Zampini 40753cdbc3dSStefano Zampini PetscFunctionBegin; 40853cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 40953cdbc3dSStefano Zampini PetscFunctionReturn(0); 41053cdbc3dSStefano Zampini } 4111e6b0712SBarry Smith 41253cdbc3dSStefano Zampini #undef __FUNCT__ 41353cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 41453cdbc3dSStefano Zampini /*@ 415da1bb401SStefano Zampini PCBDDCGetNeumannBoundaries - Get index set defining subdomain part (in local ordering) 416da1bb401SStefano Zampini of Neumann boundaries for the global problem. 41753cdbc3dSStefano Zampini 4189c0446d6SStefano Zampini Not collective 41953cdbc3dSStefano Zampini 42053cdbc3dSStefano Zampini Input Parameters: 42153cdbc3dSStefano Zampini + pc - the preconditioning context 42253cdbc3dSStefano Zampini 42353cdbc3dSStefano Zampini Output Parameters: 42453cdbc3dSStefano Zampini + NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 42553cdbc3dSStefano Zampini 42653cdbc3dSStefano Zampini Level: intermediate 42753cdbc3dSStefano Zampini 42853cdbc3dSStefano Zampini Notes: 42953cdbc3dSStefano Zampini 43053cdbc3dSStefano Zampini .seealso: PCBDDC 43153cdbc3dSStefano Zampini @*/ 43253cdbc3dSStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 43353cdbc3dSStefano Zampini { 43453cdbc3dSStefano Zampini PetscErrorCode ierr; 43553cdbc3dSStefano Zampini 43653cdbc3dSStefano Zampini PetscFunctionBegin; 43753cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 43853cdbc3dSStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 4390c7d97c5SJed Brown PetscFunctionReturn(0); 4400c7d97c5SJed Brown } 44136e030ebSStefano Zampini /* -------------------------------------------------------------------------- */ 4421e6b0712SBarry Smith 44336e030ebSStefano Zampini #undef __FUNCT__ 444da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC" 4451a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 44636e030ebSStefano Zampini { 44736e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 448da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 449da1bb401SStefano Zampini PetscErrorCode ierr; 45036e030ebSStefano Zampini 45136e030ebSStefano Zampini PetscFunctionBegin; 452674ae819SStefano Zampini /* free old CSR */ 453674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 454674ae819SStefano Zampini /* get CSR into graph structure */ 455da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 456674ae819SStefano Zampini ierr = PetscMalloc((nvtxs+1)*sizeof(PetscInt),&mat_graph->xadj);CHKERRQ(ierr); 457674ae819SStefano Zampini ierr = PetscMalloc(xadj[nvtxs]*sizeof(PetscInt),&mat_graph->adjncy);CHKERRQ(ierr); 458674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 459674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 460da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 4611a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 4621a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 463674ae819SStefano Zampini } 464575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 46536e030ebSStefano Zampini PetscFunctionReturn(0); 46636e030ebSStefano Zampini } 4671e6b0712SBarry Smith 46836e030ebSStefano Zampini #undef __FUNCT__ 469da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph" 47036e030ebSStefano Zampini /*@ 471da1bb401SStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set CSR graph of local matrix for use of PCBDDC. 47236e030ebSStefano Zampini 47336e030ebSStefano Zampini Not collective 47436e030ebSStefano Zampini 47536e030ebSStefano Zampini Input Parameters: 47636e030ebSStefano Zampini + pc - the preconditioning context 477da1bb401SStefano Zampini - nvtxs - number of local vertices of the graph 478da1bb401SStefano Zampini - xadj, adjncy - the CSR graph 479da1bb401SStefano Zampini - copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER. In the former case the user must free the array passed in; 480da1bb401SStefano Zampini in the latter case, memory must be obtained with PetscMalloc. 48136e030ebSStefano Zampini 48236e030ebSStefano Zampini Level: intermediate 48336e030ebSStefano Zampini 48436e030ebSStefano Zampini Notes: 48536e030ebSStefano Zampini 48636e030ebSStefano Zampini .seealso: PCBDDC 48736e030ebSStefano Zampini @*/ 4881a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 48936e030ebSStefano Zampini { 490575ad6abSStefano Zampini void (*f)(void) = 0; 49136e030ebSStefano Zampini PetscErrorCode ierr; 49236e030ebSStefano Zampini 49336e030ebSStefano Zampini PetscFunctionBegin; 49436e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 495674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 496674ae819SStefano Zampini PetscValidIntPointer(xadj,4); 497674ae819SStefano Zampini if (copymode != PETSC_COPY_VALUES && copymode != PETSC_OWN_POINTER) { 498674ae819SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d in %s\n",copymode,__FUNCT__); 499da1bb401SStefano Zampini } 50036e030ebSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 501575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 502575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 503575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 504575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 505575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 50636e030ebSStefano Zampini } 50736e030ebSStefano Zampini PetscFunctionReturn(0); 50836e030ebSStefano Zampini } 5099c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 5101e6b0712SBarry Smith 5119c0446d6SStefano Zampini #undef __FUNCT__ 5129c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 5139c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 5149c0446d6SStefano Zampini { 5159c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5169c0446d6SStefano Zampini PetscInt i; 5179c0446d6SStefano Zampini PetscErrorCode ierr; 5189c0446d6SStefano Zampini 5199c0446d6SStefano Zampini PetscFunctionBegin; 520da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 5219c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 5229c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 5239c0446d6SStefano Zampini } 524d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 525da1bb401SStefano Zampini /* allocate space then set */ 5269c0446d6SStefano Zampini ierr = PetscMalloc(n_is*sizeof(IS),&pcbddc->ISForDofs);CHKERRQ(ierr); 5279c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 528da1bb401SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 529da1bb401SStefano Zampini pcbddc->ISForDofs[i]=ISForDofs[i]; 5309c0446d6SStefano Zampini } 5319c0446d6SStefano Zampini pcbddc->n_ISForDofs=n_is; 5329c0446d6SStefano Zampini PetscFunctionReturn(0); 5339c0446d6SStefano Zampini } 5341e6b0712SBarry Smith 5359c0446d6SStefano Zampini #undef __FUNCT__ 5369c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 5379c0446d6SStefano Zampini /*@ 538da1bb401SStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of local mat. 5399c0446d6SStefano Zampini 5409c0446d6SStefano Zampini Not collective 5419c0446d6SStefano Zampini 5429c0446d6SStefano Zampini Input Parameters: 5439c0446d6SStefano Zampini + pc - the preconditioning context 544da1bb401SStefano Zampini - n - number of index sets defining the fields 545da1bb401SStefano Zampini - IS[] - array of IS describing the fields 5469c0446d6SStefano Zampini 5479c0446d6SStefano Zampini Level: intermediate 5489c0446d6SStefano Zampini 5499c0446d6SStefano Zampini Notes: 5509c0446d6SStefano Zampini 5519c0446d6SStefano Zampini .seealso: PCBDDC 5529c0446d6SStefano Zampini @*/ 5539c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 5549c0446d6SStefano Zampini { 5559c0446d6SStefano Zampini PetscErrorCode ierr; 5569c0446d6SStefano Zampini 5579c0446d6SStefano Zampini PetscFunctionBegin; 5589c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5599c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 5609c0446d6SStefano Zampini PetscFunctionReturn(0); 5619c0446d6SStefano Zampini } 562da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 563534831adSStefano Zampini #undef __FUNCT__ 564534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC" 565534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 566534831adSStefano Zampini /* 567534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 568534831adSStefano Zampini guess if a transformation of basis approach has been selected. 5699c0446d6SStefano Zampini 570534831adSStefano Zampini Input Parameter: 571534831adSStefano Zampini + pc - the preconditioner contex 572534831adSStefano Zampini 573534831adSStefano Zampini Application Interface Routine: PCPreSolve() 574534831adSStefano Zampini 575534831adSStefano Zampini Notes: 576534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 577534831adSStefano Zampini the user, but instead is called by KSPSolve(). 578534831adSStefano Zampini */ 579534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 580534831adSStefano Zampini { 581534831adSStefano Zampini PetscErrorCode ierr; 582534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 583534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 584534831adSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 585534831adSStefano Zampini Mat temp_mat; 5863972b0daSStefano Zampini IS dirIS; 5873972b0daSStefano Zampini PetscInt dirsize,i,*is_indices; 5883972b0daSStefano Zampini PetscScalar *array_x,*array_diagonal; 5893972b0daSStefano Zampini Vec used_vec; 5903972b0daSStefano Zampini PetscBool guess_nonzero; 591534831adSStefano Zampini 592534831adSStefano Zampini PetscFunctionBegin; 5933972b0daSStefano Zampini if (x) { 5943972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 5953972b0daSStefano Zampini used_vec = x; 5963972b0daSStefano Zampini } else { 5973972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 5983972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 5993972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 6003972b0daSStefano Zampini } 6013972b0daSStefano Zampini /* hack into ksp data structure PCPreSolve comes earlier in src/ksp/ksp/interface/itfunc.c */ 6023972b0daSStefano Zampini if (ksp) { 6033972b0daSStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&guess_nonzero);CHKERRQ(ierr); 6043972b0daSStefano Zampini if ( !guess_nonzero ) { 6053972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 6063972b0daSStefano Zampini } 6073972b0daSStefano Zampini } 6083972b0daSStefano Zampini /* store the original rhs */ 6093972b0daSStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 6103972b0daSStefano Zampini 6113972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 6123972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 6133972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 6143972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6153972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6163972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6173972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6183972b0daSStefano Zampini ierr = PCBDDCGetDirichletBoundaries(pc,&dirIS);CHKERRQ(ierr); 6193972b0daSStefano Zampini if (dirIS) { 6203972b0daSStefano Zampini ierr = ISGetSize(dirIS,&dirsize);CHKERRQ(ierr); 6213972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 6223972b0daSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 6233972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6242fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 6253972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6263972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 6273972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 6283972b0daSStefano Zampini } 6293972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6303972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 631b76ba322SStefano Zampini 6323972b0daSStefano Zampini /* remove the computed solution from the rhs */ 6333972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 6343972b0daSStefano Zampini ierr = MatMultAdd(pc->pmat,used_vec,rhs,rhs);CHKERRQ(ierr); 6353972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 636b76ba322SStefano Zampini 637b76ba322SStefano Zampini /* store partially computed solution and set initial guess */ 6383972b0daSStefano Zampini if (x) { 6393972b0daSStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 6403972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 64115aaf578SStefano Zampini if (pcbddc->use_exact_dirichlet && !pcbddc->coarse_psi_B) { 642b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 643b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 644b76ba322SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 645b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 646b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 647b76ba322SStefano Zampini if (ksp) { 648b76ba322SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 649b76ba322SStefano Zampini } 650b76ba322SStefano Zampini } 6513972b0daSStefano Zampini } 652b76ba322SStefano Zampini 653b76ba322SStefano Zampini /* rhs change of basis */ 654674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 655b76ba322SStefano Zampini /* swap pointers for local matrices */ 656b76ba322SStefano Zampini temp_mat = matis->A; 657b76ba322SStefano Zampini matis->A = pcbddc->local_mat; 658b76ba322SStefano Zampini pcbddc->local_mat = temp_mat; 659b76ba322SStefano Zampini /* Get local rhs and apply transformation of basis */ 660b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 661b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 662b76ba322SStefano Zampini /* from original basis to modified basis */ 663b76ba322SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 664b76ba322SStefano Zampini /* put back modified values into the global vec using INSERT_VALUES copy mode */ 665b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 666b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 667674ae819SStefano Zampini } 6680bdf917eSStefano Zampini if (ksp && pcbddc->NullSpace) { 669d0195637SJed Brown ierr = MatNullSpaceRemove(pcbddc->NullSpace,used_vec);CHKERRQ(ierr); 670d0195637SJed Brown ierr = MatNullSpaceRemove(pcbddc->NullSpace,rhs);CHKERRQ(ierr); 671b76ba322SStefano Zampini } 6720bdf917eSStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 673534831adSStefano Zampini PetscFunctionReturn(0); 674534831adSStefano Zampini } 675534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 676534831adSStefano Zampini #undef __FUNCT__ 677534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC" 678534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 679534831adSStefano Zampini /* 680534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 681534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 682534831adSStefano Zampini 683534831adSStefano Zampini Input Parameter: 684534831adSStefano Zampini + pc - the preconditioner contex 685534831adSStefano Zampini 686534831adSStefano Zampini Application Interface Routine: PCPostSolve() 687534831adSStefano Zampini 688534831adSStefano Zampini Notes: 689534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 690534831adSStefano Zampini the user, but instead is called by KSPSolve(). 691534831adSStefano Zampini */ 692534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 693534831adSStefano Zampini { 694534831adSStefano Zampini PetscErrorCode ierr; 695534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 696534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 697534831adSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 698534831adSStefano Zampini Mat temp_mat; 699534831adSStefano Zampini 700534831adSStefano Zampini PetscFunctionBegin; 701674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 702534831adSStefano Zampini /* swap pointers for local matrices */ 703534831adSStefano Zampini temp_mat = matis->A; 704534831adSStefano Zampini matis->A = pcbddc->local_mat; 705534831adSStefano Zampini pcbddc->local_mat = temp_mat; 706534831adSStefano Zampini /* restore rhs to its original state */ 7073425bc38SStefano Zampini if (rhs) { 7083425bc38SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,rhs);CHKERRQ(ierr); 7093425bc38SStefano Zampini } 710534831adSStefano Zampini /* Get Local boundary and apply transformation of basis to solution vector */ 711534831adSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 712534831adSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 713534831adSStefano Zampini /* from modified basis to original basis */ 714534831adSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 715534831adSStefano Zampini /* put back modified values into the global vec using INSERT_VALUES copy mode */ 716534831adSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 717534831adSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 718534831adSStefano Zampini } 7193972b0daSStefano Zampini /* add solution removed in presolve */ 7203425bc38SStefano Zampini if (x) { 7213425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 7223425bc38SStefano Zampini } 723534831adSStefano Zampini PetscFunctionReturn(0); 724534831adSStefano Zampini } 725534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 72653cdbc3dSStefano Zampini #undef __FUNCT__ 72753cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 7280c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 7290c7d97c5SJed Brown /* 7300c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 7310c7d97c5SJed Brown by setting data structures and options. 7320c7d97c5SJed Brown 7330c7d97c5SJed Brown Input Parameter: 73453cdbc3dSStefano Zampini + pc - the preconditioner context 7350c7d97c5SJed Brown 7360c7d97c5SJed Brown Application Interface Routine: PCSetUp() 7370c7d97c5SJed Brown 7380c7d97c5SJed Brown Notes: 7390c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 7400c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 7410c7d97c5SJed Brown */ 74253cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 7430c7d97c5SJed Brown { 7440c7d97c5SJed Brown PetscErrorCode ierr; 7450c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 746674ae819SStefano Zampini MatStructure flag; 747674ae819SStefano Zampini PetscBool computeis,computetopography,computesolvers; 7480c7d97c5SJed Brown 7490c7d97c5SJed Brown PetscFunctionBegin; 750674ae819SStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other nonoverlapping preconditioners */ 7513b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 7529c0446d6SStefano Zampini So, we set to pcnone the Neumann problem of pcis in order to avoid unneeded computation 7530c7d97c5SJed Brown Also, we decide to directly build the (same) Dirichlet problem */ 7540c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localN_pc_type","none");CHKERRQ(ierr); 7550c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localD_pc_type","none");CHKERRQ(ierr); 7563b03a366Sstefano_zampini /* Get stdout for dbg */ 757674ae819SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->dbg_viewer) { 758ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pc),&pcbddc->dbg_viewer);CHKERRQ(ierr); 759e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 760e269702eSStefano Zampini } 761674ae819SStefano Zampini /* first attempt to split work */ 762674ae819SStefano Zampini if (pc->setupcalled) { 763674ae819SStefano Zampini computeis = PETSC_FALSE; 764674ae819SStefano Zampini ierr = PCGetOperators(pc,NULL,NULL,&flag);CHKERRQ(ierr); 765674ae819SStefano Zampini if (flag == SAME_PRECONDITIONER) { 766674ae819SStefano Zampini computetopography = PETSC_FALSE; 767674ae819SStefano Zampini computesolvers = PETSC_FALSE; 768674ae819SStefano Zampini } else if (flag == SAME_NONZERO_PATTERN) { 769674ae819SStefano Zampini computetopography = PETSC_FALSE; 770674ae819SStefano Zampini computesolvers = PETSC_TRUE; 771674ae819SStefano Zampini } else { /* DIFFERENT_NONZERO_PATTERN */ 772674ae819SStefano Zampini computetopography = PETSC_TRUE; 773674ae819SStefano Zampini computesolvers = PETSC_TRUE; 774674ae819SStefano Zampini } 775674ae819SStefano Zampini } else { 776674ae819SStefano Zampini computeis = PETSC_TRUE; 777674ae819SStefano Zampini computetopography = PETSC_TRUE; 778674ae819SStefano Zampini computesolvers = PETSC_TRUE; 779674ae819SStefano Zampini } 780674ae819SStefano Zampini /* Set up all the "iterative substructuring" common block */ 781674ae819SStefano Zampini if (computeis) { 782674ae819SStefano Zampini ierr = PCISSetUp(pc);CHKERRQ(ierr); 783674ae819SStefano Zampini } 784674ae819SStefano Zampini /* Analyze interface and set up local constraint and change of basis matrices */ 785674ae819SStefano Zampini if (computetopography) { 786674ae819SStefano Zampini /* reset data */ 787674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 788674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 789674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 790674ae819SStefano Zampini } 791674ae819SStefano Zampini if (computesolvers) { 792674ae819SStefano Zampini /* reset data */ 793674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 794674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 7950c7d97c5SJed Brown /* Create coarse and local stuffs used for evaluating action of preconditioner */ 7960c7d97c5SJed Brown ierr = PCBDDCCoarseSetUp(pc);CHKERRQ(ierr); 797674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 7980c7d97c5SJed Brown } 7990c7d97c5SJed Brown PetscFunctionReturn(0); 8000c7d97c5SJed Brown } 8010c7d97c5SJed Brown 8020c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 8030c7d97c5SJed Brown /* 8040c7d97c5SJed Brown PCApply_BDDC - Applies the BDDC preconditioner to a vector. 8050c7d97c5SJed Brown 8060c7d97c5SJed Brown Input Parameters: 8070c7d97c5SJed Brown . pc - the preconditioner context 8080c7d97c5SJed Brown . r - input vector (global) 8090c7d97c5SJed Brown 8100c7d97c5SJed Brown Output Parameter: 8110c7d97c5SJed Brown . z - output vector (global) 8120c7d97c5SJed Brown 8130c7d97c5SJed Brown Application Interface Routine: PCApply() 8140c7d97c5SJed Brown */ 8150c7d97c5SJed Brown #undef __FUNCT__ 8160c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 81753cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 8180c7d97c5SJed Brown { 8190c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 8200c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 8210c7d97c5SJed Brown PetscErrorCode ierr; 8223b03a366Sstefano_zampini const PetscScalar one = 1.0; 8233b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 8242617d88aSStefano Zampini const PetscScalar zero = 0.0; 8250c7d97c5SJed Brown 8260c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 8270c7d97c5SJed Brown NN interface preconditioner changed to BDDC 82829622bf0SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->inexact_prec_type = PETSC_TRUE) */ 8290c7d97c5SJed Brown 8300c7d97c5SJed Brown PetscFunctionBegin; 83115aaf578SStefano Zampini if (!pcbddc->use_exact_dirichlet || pcbddc->coarse_psi_B) { 8320c7d97c5SJed Brown /* First Dirichlet solve */ 8330c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8340c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 83553cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 8360c7d97c5SJed Brown /* 8370c7d97c5SJed Brown Assembling right hand side for BDDC operator 838674ae819SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE) 839674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 8400c7d97c5SJed Brown */ 8410c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 8420c7d97c5SJed Brown ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 84329622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 8440c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 8450c7d97c5SJed Brown ierr = VecCopy(r,z);CHKERRQ(ierr); 8460c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8470c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 848674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 849b76ba322SStefano Zampini } else { 8500bdf917eSStefano Zampini ierr = VecSet(pcis->vec1_D,zero);CHKERRQ(ierr); 851b76ba322SStefano Zampini ierr = VecSet(pcis->vec2_D,zero);CHKERRQ(ierr); 852674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 853b76ba322SStefano Zampini } 854b76ba322SStefano Zampini 8552617d88aSStefano Zampini /* Apply interface preconditioner 8562617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 8572617d88aSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc);CHKERRQ(ierr); 8582617d88aSStefano Zampini 859674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 860674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 8610c7d97c5SJed Brown 8623b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 8630c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8640c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8650c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 86629622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 86753cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr); 8680c7d97c5SJed Brown ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr); 86929622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); } 8700c7d97c5SJed Brown ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr); 8710c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8720c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8730c7d97c5SJed Brown PetscFunctionReturn(0); 8740c7d97c5SJed Brown } 875da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 876674ae819SStefano Zampini 877da1bb401SStefano Zampini #undef __FUNCT__ 878da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC" 879da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 880da1bb401SStefano Zampini { 881da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 882da1bb401SStefano Zampini PetscErrorCode ierr; 883da1bb401SStefano Zampini 884da1bb401SStefano Zampini PetscFunctionBegin; 885da1bb401SStefano Zampini /* free data created by PCIS */ 886da1bb401SStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 887674ae819SStefano Zampini /* free BDDC custom data */ 888674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 889674ae819SStefano Zampini /* destroy objects related to topography */ 890674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 891674ae819SStefano Zampini /* free allocated graph structure */ 892da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr); 893674ae819SStefano Zampini /* free data for scaling operator */ 894674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 895674ae819SStefano Zampini /* free solvers stuff */ 896674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 89733bc96a4SStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 89833bc96a4SStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 899*ac78edfcSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 9003425bc38SStefano Zampini /* remove functions */ 901674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 902bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 903bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetMaxLevels_C",NULL);CHKERRQ(ierr); 904bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",NULL);CHKERRQ(ierr); 905bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 906bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 907bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 908bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 909bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseProblemType_C",NULL);CHKERRQ(ierr); 910bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 911bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 912bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 913bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 914bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 915674ae819SStefano Zampini /* Free the private data structure */ 916674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 917da1bb401SStefano Zampini PetscFunctionReturn(0); 918da1bb401SStefano Zampini } 9193425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 9201e6b0712SBarry Smith 9213425bc38SStefano Zampini #undef __FUNCT__ 9223425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC" 9233425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 9243425bc38SStefano Zampini { 925674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 9263425bc38SStefano Zampini PC_IS* pcis; 9273425bc38SStefano Zampini PC_BDDC* pcbddc; 9283425bc38SStefano Zampini PetscErrorCode ierr; 9290c7d97c5SJed Brown 9303425bc38SStefano Zampini PetscFunctionBegin; 9313425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 9323425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 9333425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 9343425bc38SStefano Zampini 9353425bc38SStefano Zampini /* change of basis for physical rhs if needed 9363425bc38SStefano Zampini It also changes the rhs in case of dirichlet boundaries */ 9370298fd71SBarry Smith (*mat_ctx->pc->ops->presolve)(mat_ctx->pc,NULL,standard_rhs,NULL); 9383425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 9393425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9403425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 941674ae819SStefano Zampini /* scale rhs since it should be unassembled : TODO use counter scaling? (also below) */ 9423425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9433425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 944674ae819SStefano Zampini /* Apply partition of unity */ 9453425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 946674ae819SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 94729622bf0SStefano Zampini if (!pcbddc->inexact_prec_type) { 9483425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 9493425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 9503425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 9513425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 9523425bc38SStefano Zampini ierr = VecSet(standard_rhs,0.0);CHKERRQ(ierr); 9533425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9543425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 955674ae819SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 9563425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9573425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9583425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 9593425bc38SStefano Zampini } 9603425bc38SStefano Zampini /* BDDC rhs */ 9613425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 96229622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { 9633425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 9643425bc38SStefano Zampini } 9653425bc38SStefano Zampini /* apply BDDC */ 9663425bc38SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr); 9673425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 9683425bc38SStefano Zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 9693425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 9703425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9713425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9723425bc38SStefano Zampini /* restore original rhs */ 9733425bc38SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,standard_rhs);CHKERRQ(ierr); 9743425bc38SStefano Zampini PetscFunctionReturn(0); 9753425bc38SStefano Zampini } 9761e6b0712SBarry Smith 9773425bc38SStefano Zampini #undef __FUNCT__ 9783425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS" 9793425bc38SStefano Zampini /*@ 9803425bc38SStefano Zampini PCBDDCMatFETIDPGetRHS - Get rhs for FETIDP linear system. 9813425bc38SStefano Zampini 9823425bc38SStefano Zampini Collective 9833425bc38SStefano Zampini 9843425bc38SStefano Zampini Input Parameters: 9853425bc38SStefano Zampini + fetidp_mat - the FETIDP mat obtained by a call to PCBDDCCreateFETIDPOperators 9863425bc38SStefano Zampini + standard_rhs - the rhs of your linear system 9873425bc38SStefano Zampini 9883425bc38SStefano Zampini Output Parameters: 9893425bc38SStefano Zampini + fetidp_flux_rhs - the rhs of the FETIDP linear system 9903425bc38SStefano Zampini 9913425bc38SStefano Zampini Level: developer 9923425bc38SStefano Zampini 9933425bc38SStefano Zampini Notes: 9943425bc38SStefano Zampini 9953425bc38SStefano Zampini .seealso: PCBDDC 9963425bc38SStefano Zampini @*/ 9973425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 9983425bc38SStefano Zampini { 999674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 10003425bc38SStefano Zampini PetscErrorCode ierr; 10013425bc38SStefano Zampini 10023425bc38SStefano Zampini PetscFunctionBegin; 10033425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10043425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 10053425bc38SStefano Zampini PetscFunctionReturn(0); 10063425bc38SStefano Zampini } 10073425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 10081e6b0712SBarry Smith 10093425bc38SStefano Zampini #undef __FUNCT__ 10103425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC" 10113425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 10123425bc38SStefano Zampini { 1013674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 10143425bc38SStefano Zampini PC_IS* pcis; 10153425bc38SStefano Zampini PC_BDDC* pcbddc; 10163425bc38SStefano Zampini PetscErrorCode ierr; 10173425bc38SStefano Zampini 10183425bc38SStefano Zampini PetscFunctionBegin; 10193425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10203425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 10213425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 10223425bc38SStefano Zampini 10233425bc38SStefano Zampini /* apply B_delta^T */ 10243425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10253425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10263425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 10273425bc38SStefano Zampini /* compute rhs for BDDC application */ 10283425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 102929622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { 10303425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 10313425bc38SStefano Zampini } 10323425bc38SStefano Zampini /* apply BDDC */ 10333425bc38SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr); 10343425bc38SStefano Zampini /* put values into standard global vector */ 10353425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10363425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 103729622bf0SStefano Zampini if (!pcbddc->inexact_prec_type) { 10383425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 10393425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 10403425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_D,-1.0,pcis->vec1_D);CHKERRQ(ierr); 10413425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 10423425bc38SStefano Zampini } 10433425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10443425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10453425bc38SStefano Zampini /* final change of basis if needed 10463425bc38SStefano Zampini Is also sums the dirichlet part removed during RHS assembling */ 10470298fd71SBarry Smith (*mat_ctx->pc->ops->postsolve)(mat_ctx->pc,NULL,NULL,standard_sol); 10483425bc38SStefano Zampini PetscFunctionReturn(0); 10493425bc38SStefano Zampini 10503425bc38SStefano Zampini } 10511e6b0712SBarry Smith 10523425bc38SStefano Zampini #undef __FUNCT__ 10533425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution" 10543425bc38SStefano Zampini /*@ 10553425bc38SStefano Zampini PCBDDCMatFETIDPGetSolution - Get Solution for FETIDP linear system. 10563425bc38SStefano Zampini 10573425bc38SStefano Zampini Collective 10583425bc38SStefano Zampini 10593425bc38SStefano Zampini Input Parameters: 10603425bc38SStefano Zampini + fetidp_mat - the FETIDP mat obtained by a call to PCBDDCCreateFETIDPOperators 10613425bc38SStefano Zampini + fetidp_flux_sol - the solution of the FETIDP linear system 10623425bc38SStefano Zampini 10633425bc38SStefano Zampini Output Parameters: 10643425bc38SStefano Zampini + standard_sol - the solution on the global domain 10653425bc38SStefano Zampini 10663425bc38SStefano Zampini Level: developer 10673425bc38SStefano Zampini 10683425bc38SStefano Zampini Notes: 10693425bc38SStefano Zampini 10703425bc38SStefano Zampini .seealso: PCBDDC 10713425bc38SStefano Zampini @*/ 10723425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 10733425bc38SStefano Zampini { 1074674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 10753425bc38SStefano Zampini PetscErrorCode ierr; 10763425bc38SStefano Zampini 10773425bc38SStefano Zampini PetscFunctionBegin; 10783425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10793425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 10803425bc38SStefano Zampini PetscFunctionReturn(0); 10813425bc38SStefano Zampini } 10823425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 10831e6b0712SBarry Smith 1084f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec); 1085f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat); 1086f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec); 1087f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC); 1088674ae819SStefano Zampini 10893425bc38SStefano Zampini #undef __FUNCT__ 10903425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC" 10913425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 10923425bc38SStefano Zampini { 1093674ae819SStefano Zampini 1094674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 10953425bc38SStefano Zampini Mat newmat; 1096674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 10973425bc38SStefano Zampini PC newpc; 1098ce94432eSBarry Smith MPI_Comm comm; 10993425bc38SStefano Zampini PetscErrorCode ierr; 11003425bc38SStefano Zampini 11013425bc38SStefano Zampini PetscFunctionBegin; 1102ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 11033425bc38SStefano Zampini /* FETIDP linear matrix */ 11043425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 11053425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 11063425bc38SStefano Zampini ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 11073425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 11083425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 11093425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 11103425bc38SStefano Zampini /* FETIDP preconditioner */ 11113425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 11123425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 11133425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 11143425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 11153425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 11163425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 11173425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 11183425bc38SStefano Zampini ierr = PCSetOperators(newpc,newmat,newmat,SAME_PRECONDITIONER);CHKERRQ(ierr); 11193425bc38SStefano Zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 11203425bc38SStefano Zampini /* return pointers for objects created */ 11213425bc38SStefano Zampini *fetidp_mat=newmat; 11223425bc38SStefano Zampini *fetidp_pc=newpc; 11233425bc38SStefano Zampini PetscFunctionReturn(0); 11243425bc38SStefano Zampini } 11251e6b0712SBarry Smith 11263425bc38SStefano Zampini #undef __FUNCT__ 11273425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators" 11283425bc38SStefano Zampini /*@ 11293425bc38SStefano Zampini PCBDDCCreateFETIDPOperators - Create operators for FETIDP. 11303425bc38SStefano Zampini 11313425bc38SStefano Zampini Collective 11323425bc38SStefano Zampini 11333425bc38SStefano Zampini Input Parameters: 11343425bc38SStefano Zampini + pc - the BDDC preconditioning context (setup must be already called) 11353425bc38SStefano Zampini 11363425bc38SStefano Zampini Level: developer 11373425bc38SStefano Zampini 11383425bc38SStefano Zampini Notes: 11393425bc38SStefano Zampini 11403425bc38SStefano Zampini .seealso: PCBDDC 11413425bc38SStefano Zampini @*/ 11423425bc38SStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 11433425bc38SStefano Zampini { 11443425bc38SStefano Zampini PetscErrorCode ierr; 11453425bc38SStefano Zampini 11463425bc38SStefano Zampini PetscFunctionBegin; 11473425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 11483425bc38SStefano Zampini if (pc->setupcalled) { 11493425bc38SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,Mat*,PC*),(pc,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 1150f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n"); 11513425bc38SStefano Zampini PetscFunctionReturn(0); 11523425bc38SStefano Zampini } 11530c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1154da1bb401SStefano Zampini /*MC 1155da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 11560c7d97c5SJed Brown 1157da1bb401SStefano Zampini Options Database Keys: 1158da1bb401SStefano Zampini . -pcbddc ??? - 1159da1bb401SStefano Zampini 1160da1bb401SStefano Zampini Level: intermediate 1161da1bb401SStefano Zampini 1162da1bb401SStefano Zampini Notes: The matrix used with this preconditioner must be of type MATIS 1163da1bb401SStefano Zampini 1164da1bb401SStefano Zampini Unlike more 'conventional' interface preconditioners, this iterates over ALL the 1165da1bb401SStefano Zampini degrees of freedom, NOT just those on the interface (this allows the use of approximate solvers 1166da1bb401SStefano Zampini on the subdomains). 1167da1bb401SStefano Zampini 1168da1bb401SStefano Zampini Options for the coarse grid preconditioner can be set with - 1169da1bb401SStefano Zampini Options for the Dirichlet subproblem can be set with - 1170da1bb401SStefano Zampini Options for the Neumann subproblem can be set with - 1171da1bb401SStefano Zampini 1172da1bb401SStefano Zampini Contributed by Stefano Zampini 1173da1bb401SStefano Zampini 1174da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 1175da1bb401SStefano Zampini M*/ 1176b2573a8aSBarry Smith 1177da1bb401SStefano Zampini #undef __FUNCT__ 1178da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC" 11798cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 1180da1bb401SStefano Zampini { 1181da1bb401SStefano Zampini PetscErrorCode ierr; 1182da1bb401SStefano Zampini PC_BDDC *pcbddc; 1183da1bb401SStefano Zampini 1184da1bb401SStefano Zampini PetscFunctionBegin; 1185da1bb401SStefano Zampini /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 1186da1bb401SStefano Zampini ierr = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr); 1187da1bb401SStefano Zampini pc->data = (void*)pcbddc; 1188da1bb401SStefano Zampini 1189da1bb401SStefano Zampini /* create PCIS data structure */ 1190da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 1191da1bb401SStefano Zampini 1192da1bb401SStefano Zampini /* BDDC specific */ 1193674ae819SStefano Zampini pcbddc->user_primal_vertices = 0; 11940bdf917eSStefano Zampini pcbddc->NullSpace = 0; 11953972b0daSStefano Zampini pcbddc->temp_solution = 0; 1196534831adSStefano Zampini pcbddc->original_rhs = 0; 1197534831adSStefano Zampini pcbddc->local_mat = 0; 1198534831adSStefano Zampini pcbddc->ChangeOfBasisMatrix = 0; 1199674ae819SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 1200674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 1201da1bb401SStefano Zampini pcbddc->coarse_vec = 0; 1202da1bb401SStefano Zampini pcbddc->coarse_rhs = 0; 1203da1bb401SStefano Zampini pcbddc->coarse_ksp = 0; 1204da1bb401SStefano Zampini pcbddc->coarse_phi_B = 0; 1205da1bb401SStefano Zampini pcbddc->coarse_phi_D = 0; 120615aaf578SStefano Zampini pcbddc->coarse_psi_B = 0; 120715aaf578SStefano Zampini pcbddc->coarse_psi_D = 0; 1208da1bb401SStefano Zampini pcbddc->vec1_P = 0; 1209da1bb401SStefano Zampini pcbddc->vec1_R = 0; 1210da1bb401SStefano Zampini pcbddc->vec2_R = 0; 1211da1bb401SStefano Zampini pcbddc->local_auxmat1 = 0; 1212da1bb401SStefano Zampini pcbddc->local_auxmat2 = 0; 1213da1bb401SStefano Zampini pcbddc->R_to_B = 0; 1214da1bb401SStefano Zampini pcbddc->R_to_D = 0; 1215da1bb401SStefano Zampini pcbddc->ksp_D = 0; 1216da1bb401SStefano Zampini pcbddc->ksp_R = 0; 1217da1bb401SStefano Zampini pcbddc->local_primal_indices = 0; 121829622bf0SStefano Zampini pcbddc->inexact_prec_type = PETSC_FALSE; 1219da1bb401SStefano Zampini pcbddc->NeumannBoundaries = 0; 1220da1bb401SStefano Zampini pcbddc->ISForDofs = 0; 1221da1bb401SStefano Zampini pcbddc->ConstraintMatrix = 0; 1222da1bb401SStefano Zampini pcbddc->use_nnsp_true = PETSC_FALSE; 1223da1bb401SStefano Zampini pcbddc->local_primal_sizes = 0; 1224da1bb401SStefano Zampini pcbddc->local_primal_displacements = 0; 1225da1bb401SStefano Zampini pcbddc->coarse_loc_to_glob = 0; 12269d9e44b6SStefano Zampini pcbddc->dbg_flag = 0; 1227da1bb401SStefano Zampini pcbddc->coarsening_ratio = 8; 1228b76ba322SStefano Zampini pcbddc->use_exact_dirichlet = PETSC_TRUE; 12294fad6a16SStefano Zampini pcbddc->current_level = 0; 12304fad6a16SStefano Zampini pcbddc->max_levels = 1; 1231674ae819SStefano Zampini pcbddc->replicated_local_primal_indices = 0; 1232674ae819SStefano Zampini pcbddc->replicated_local_primal_values = 0; 1233da1bb401SStefano Zampini 1234674ae819SStefano Zampini /* create local graph structure */ 1235674ae819SStefano Zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 1236674ae819SStefano Zampini 1237674ae819SStefano Zampini /* scaling */ 1238674ae819SStefano Zampini pcbddc->use_deluxe_scaling = PETSC_FALSE; 1239674ae819SStefano Zampini pcbddc->work_scaling = 0; 1240da1bb401SStefano Zampini 1241da1bb401SStefano Zampini /* function pointers */ 1242da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 1243da1bb401SStefano Zampini pc->ops->applytranspose = 0; 1244da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 1245da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 1246da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 1247da1bb401SStefano Zampini pc->ops->view = 0; 1248da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 1249da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 1250da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 1251534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 1252534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 1253da1bb401SStefano Zampini 1254da1bb401SStefano Zampini /* composing function */ 1255674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 1256bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 1257bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetMaxLevels_C",PCBDDCSetMaxLevels_BDDC);CHKERRQ(ierr); 1258bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",PCBDDCSetNullSpace_BDDC);CHKERRQ(ierr); 1259bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 1260bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 1261bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 1262bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 1263bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseProblemType_C",PCBDDCSetCoarseProblemType_BDDC);CHKERRQ(ierr); 1264bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 1265bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 1266bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 1267bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 1268bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 1269da1bb401SStefano Zampini PetscFunctionReturn(0); 1270da1bb401SStefano Zampini } 12713425bc38SStefano Zampini 1272da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 1273da1bb401SStefano Zampini /* All static functions from now on */ 1274da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 127529622bf0SStefano Zampini 127629622bf0SStefano Zampini #undef __FUNCT__ 12774fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel" 12784fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 12794fad6a16SStefano Zampini { 12804fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 12814fad6a16SStefano Zampini 12824fad6a16SStefano Zampini PetscFunctionBegin; 12834fad6a16SStefano Zampini pcbddc->current_level=level; 12844fad6a16SStefano Zampini PetscFunctionReturn(0); 12854fad6a16SStefano Zampini } 12863425bc38SStefano Zampini 12873b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 12880c7d97c5SJed Brown #undef __FUNCT__ 12890c7d97c5SJed Brown #define __FUNCT__ "PCBDDCCoarseSetUp" 129053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC pc) 12910c7d97c5SJed Brown { 12920c7d97c5SJed Brown PetscErrorCode ierr; 1293674ae819SStefano Zampini 12940c7d97c5SJed Brown PC_IS* pcis = (PC_IS*)(pc->data); 12950c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 12960c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 12970c7d97c5SJed Brown IS is_R_local; 129819fd82e9SBarry Smith VecType impVecType; 129919fd82e9SBarry Smith MatType impMatType; 13000c7d97c5SJed Brown PetscInt n_R=0; 13010c7d97c5SJed Brown PetscInt n_D=0; 13020c7d97c5SJed Brown PetscInt n_B=0; 13030c7d97c5SJed Brown PetscScalar zero=0.0; 13040c7d97c5SJed Brown PetscScalar one=1.0; 13050c7d97c5SJed Brown PetscScalar m_one=-1.0; 13060c7d97c5SJed Brown PetscScalar* array; 13070c7d97c5SJed Brown PetscScalar *coarse_submat_vals; 13080c7d97c5SJed Brown PetscInt *idx_R_local; 13095b08dc53SStefano Zampini PetscReal *coarsefunctions_errors,*constraints_errors; 13100c7d97c5SJed Brown /* auxiliary indices */ 1311534831adSStefano Zampini PetscInt i,j,k; 1312e269702eSStefano Zampini /* for verbose output of bddc */ 1313e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 13145b08dc53SStefano Zampini PetscInt dbg_flag=pcbddc->dbg_flag; 1315a0ba757dSStefano Zampini /* for counting coarse dofs */ 1316534831adSStefano Zampini PetscInt n_vertices,n_constraints; 13173b03a366Sstefano_zampini PetscInt size_of_constraint; 13183b03a366Sstefano_zampini PetscInt *row_cmat_indices; 13193b03a366Sstefano_zampini PetscScalar *row_cmat_values; 1320e6872a76SStefano Zampini PetscInt *vertices; 1321*ac78edfcSStefano Zampini /* manage repeated solves */ 1322*ac78edfcSStefano Zampini MatReuse reuse; 1323*ac78edfcSStefano Zampini MatStructure matstruct; 13240c7d97c5SJed Brown 13250c7d97c5SJed Brown PetscFunctionBegin; 13260c7d97c5SJed Brown /* Set Non-overlapping dimensions */ 13270c7d97c5SJed Brown n_B = pcis->n_B; n_D = pcis->n - n_B; 1328534831adSStefano Zampini 1329*ac78edfcSStefano Zampini /* get mat flags */ 1330*ac78edfcSStefano Zampini ierr = PCGetOperators(pc,NULL,NULL,&matstruct);CHKERRQ(ierr); 1331*ac78edfcSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1332*ac78edfcSStefano Zampini if (pc->setupcalled) { 1333*ac78edfcSStefano Zampini /* when matstruct is SAME_PRECONDITIONER, we shouldn't be here */ 1334*ac78edfcSStefano Zampini if (matstruct == SAME_PRECONDITIONER) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen"); 1335*ac78edfcSStefano Zampini if (matstruct == SAME_NONZERO_PATTERN) { 1336*ac78edfcSStefano Zampini reuse = MAT_REUSE_MATRIX; 1337*ac78edfcSStefano Zampini } else { 1338*ac78edfcSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1339*ac78edfcSStefano Zampini } 1340*ac78edfcSStefano Zampini } 1341*ac78edfcSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 1342*ac78edfcSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 1343*ac78edfcSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 1344*ac78edfcSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 1345*ac78edfcSStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 1346*ac78edfcSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 1347*ac78edfcSStefano Zampini } 1348*ac78edfcSStefano Zampini 1349534831adSStefano Zampini /* transform local matrices if needed */ 1350674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 1351e6872a76SStefano Zampini Mat change_mat_all; 1352e6872a76SStefano Zampini PetscInt *nnz,*is_indices,*temp_indices; 1353e6872a76SStefano Zampini 1354534831adSStefano Zampini ierr = PetscMalloc(pcis->n*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 1355534831adSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 13562fa5cd67SKarl Rupp for (i=0;i<n_D;i++) nnz[is_indices[i]] = 1; 1357534831adSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1358534831adSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1359534831adSStefano Zampini k=1; 1360534831adSStefano Zampini for (i=0;i<n_B;i++) { 13610298fd71SBarry Smith ierr = MatGetRow(pcbddc->ChangeOfBasisMatrix,i,&j,NULL,NULL);CHKERRQ(ierr); 1362534831adSStefano Zampini nnz[is_indices[i]]=j; 13632fa5cd67SKarl Rupp if (k < j) k = j; 13640298fd71SBarry Smith ierr = MatRestoreRow(pcbddc->ChangeOfBasisMatrix,i,&j,NULL,NULL);CHKERRQ(ierr); 1365534831adSStefano Zampini } 1366534831adSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1367534831adSStefano Zampini /* assemble change of basis matrix on the whole set of local dofs */ 1368534831adSStefano Zampini ierr = PetscMalloc(k*sizeof(PetscInt),&temp_indices);CHKERRQ(ierr); 1369534831adSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&change_mat_all);CHKERRQ(ierr); 1370534831adSStefano Zampini ierr = MatSetSizes(change_mat_all,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 1371534831adSStefano Zampini ierr = MatSetType(change_mat_all,MATSEQAIJ);CHKERRQ(ierr); 1372534831adSStefano Zampini ierr = MatSeqAIJSetPreallocation(change_mat_all,0,nnz);CHKERRQ(ierr); 1373534831adSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1374534831adSStefano Zampini for (i=0;i<n_D;i++) { 1375534831adSStefano Zampini ierr = MatSetValue(change_mat_all,is_indices[i],is_indices[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 1376534831adSStefano Zampini } 1377534831adSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1378534831adSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1379534831adSStefano Zampini for (i=0;i<n_B;i++) { 1380534831adSStefano Zampini ierr = MatGetRow(pcbddc->ChangeOfBasisMatrix,i,&j,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 13812fa5cd67SKarl Rupp for (k=0; k<j; k++) temp_indices[k]=is_indices[row_cmat_indices[k]]; 1382534831adSStefano Zampini ierr = MatSetValues(change_mat_all,1,&is_indices[i],j,temp_indices,row_cmat_values,INSERT_VALUES);CHKERRQ(ierr); 1383534831adSStefano Zampini ierr = MatRestoreRow(pcbddc->ChangeOfBasisMatrix,i,&j,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 1384534831adSStefano Zampini } 1385534831adSStefano Zampini ierr = MatAssemblyBegin(change_mat_all,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1386534831adSStefano Zampini ierr = MatAssemblyEnd(change_mat_all,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13875ce978abSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ? PtAP not provided */ 13885ce978abSStefano Zampini ierr = MatGetBlockSize(matis->A,&i);CHKERRQ(ierr); 13895ce978abSStefano Zampini if (i==1) { 1390*ac78edfcSStefano Zampini ierr = MatPtAP(matis->A,change_mat_all,reuse,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 13915ce978abSStefano Zampini } else { 13925ce978abSStefano Zampini Mat work_mat; 13935ce978abSStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 1394*ac78edfcSStefano Zampini ierr = MatPtAP(work_mat,change_mat_all,reuse,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 13955ce978abSStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 13965ce978abSStefano Zampini } 1397534831adSStefano Zampini ierr = MatDestroy(&change_mat_all);CHKERRQ(ierr); 1398534831adSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 1399534831adSStefano Zampini ierr = PetscFree(temp_indices);CHKERRQ(ierr); 1400534831adSStefano Zampini } else { 1401534831adSStefano Zampini /* without change of basis, the local matrix is unchanged */ 1402*ac78edfcSStefano Zampini if (!pcbddc->local_mat) { 1403534831adSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 1404534831adSStefano Zampini pcbddc->local_mat = matis->A; 1405534831adSStefano Zampini } 1406*ac78edfcSStefano Zampini } 1407*ac78edfcSStefano Zampini 1408*ac78edfcSStefano Zampini /* get submatrices */ 1409*ac78edfcSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_I_local,reuse,&pcis->A_II);CHKERRQ(ierr); 1410*ac78edfcSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,reuse,&pcis->A_IB);CHKERRQ(ierr); 1411*ac78edfcSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,reuse,&pcis->A_BI);CHKERRQ(ierr); 1412*ac78edfcSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,reuse,&pcis->A_BB);CHKERRQ(ierr); 1413*ac78edfcSStefano Zampini 1414674ae819SStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 1415674ae819SStefano Zampini if (pcbddc->NullSpace && pcbddc->use_change_of_basis) { 1416674ae819SStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 14170bdf917eSStefano Zampini } 1418a0ba757dSStefano Zampini 1419e6872a76SStefano Zampini /* Set types for local objects needed by BDDC precondtioner */ 1420e6872a76SStefano Zampini impMatType = MATSEQDENSE; 1421e6872a76SStefano Zampini impVecType = VECSEQ; 1422e6872a76SStefano Zampini /* get vertex indices from constraint matrix */ 1423e6872a76SStefano Zampini ierr = PCBDDCGetPrimalVerticesLocalIdx(pc,&n_vertices,&vertices);CHKERRQ(ierr); 1424e6872a76SStefano Zampini /* Set number of constraints */ 1425e6872a76SStefano Zampini n_constraints = pcbddc->local_primal_size-n_vertices; 14260c7d97c5SJed Brown /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 14270c7d97c5SJed Brown ierr = VecSet(pcis->vec1_N,one);CHKERRQ(ierr); 14280c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14292fa5cd67SKarl Rupp for (i=0;i<n_vertices;i++) array[vertices[i]] = zero; 14303b03a366Sstefano_zampini ierr = PetscMalloc((pcis->n-n_vertices)*sizeof(PetscInt),&idx_R_local);CHKERRQ(ierr); 14312fa5cd67SKarl Rupp for (i=0, n_R=0; i<pcis->n; i++) { 14322fa5cd67SKarl Rupp if (array[i] == one) { 14332fa5cd67SKarl Rupp idx_R_local[n_R] = i; 14342fa5cd67SKarl Rupp n_R++; 14352fa5cd67SKarl Rupp } 14362fa5cd67SKarl Rupp } 14370c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1438e6872a76SStefano Zampini ierr = PetscFree(vertices);CHKERRQ(ierr); 1439e269702eSStefano Zampini if (dbg_flag) { 14400c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 14410c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14420c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 14430c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 14443b03a366Sstefano_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); 1445534831adSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"pcbddc->n_vertices = %d, pcbddc->n_constraints = %d\n",pcbddc->n_vertices,pcbddc->n_constraints);CHKERRQ(ierr); 14460c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14470c7d97c5SJed Brown } 1448534831adSStefano Zampini 14490c7d97c5SJed Brown /* Allocate needed vectors */ 1450534831adSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 14513972b0daSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 14520c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_D,&pcbddc->vec4_D);CHKERRQ(ierr); 14530c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_R);CHKERRQ(ierr); 14540c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_R,n_R,n_R);CHKERRQ(ierr); 14550c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 1456d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 14570c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_P);CHKERRQ(ierr); 14580c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_P,pcbddc->local_primal_size,pcbddc->local_primal_size);CHKERRQ(ierr); 14590c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 14600c7d97c5SJed Brown 14610c7d97c5SJed Brown /* Creating some index sets needed */ 14620c7d97c5SJed Brown /* For submatrices */ 1463da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n_R,idx_R_local,PETSC_OWN_POINTER,&is_R_local);CHKERRQ(ierr); 1464da1bb401SStefano Zampini 14650c7d97c5SJed Brown /* For VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 14660c7d97c5SJed Brown { 1467e6872a76SStefano Zampini IS is_aux1,is_aux2; 14680c7d97c5SJed Brown PetscInt *aux_array1; 14690c7d97c5SJed Brown PetscInt *aux_array2; 14702e8d2280SStefano Zampini PetscInt *idx_I_local; 14710c7d97c5SJed Brown 14723b03a366Sstefano_zampini ierr = PetscMalloc((pcis->n_B-n_vertices)*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 14733b03a366Sstefano_zampini ierr = PetscMalloc((pcis->n_B-n_vertices)*sizeof(PetscInt),&aux_array2);CHKERRQ(ierr); 14740c7d97c5SJed Brown 14752e8d2280SStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&idx_I_local);CHKERRQ(ierr); 14760c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14772fa5cd67SKarl Rupp for (i=0; i<n_D; i++) array[idx_I_local[i]] = 0; 14782e8d2280SStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&idx_I_local);CHKERRQ(ierr); 14792fa5cd67SKarl Rupp for (i=0, j=0; i<n_R; i++) { 14802fa5cd67SKarl Rupp if (array[idx_R_local[i]] == one) { 14812fa5cd67SKarl Rupp aux_array1[j] = i; 14822fa5cd67SKarl Rupp j++; 14832fa5cd67SKarl Rupp } 14842fa5cd67SKarl Rupp } 14850c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1486da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 14872e8d2280SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14882e8d2280SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14890c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 14902fa5cd67SKarl Rupp for (i=0, j=0; i<n_B; i++) { 14912fa5cd67SKarl Rupp if (array[i] == one) { 14922fa5cd67SKarl Rupp aux_array2[j] = i; j++; 14932fa5cd67SKarl Rupp } 14942fa5cd67SKarl Rupp } 14953828260eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1496da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_COPY_VALUES,&is_aux2);CHKERRQ(ierr); 14970c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 14980c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 14990c7d97c5SJed Brown ierr = PetscFree(aux_array2);CHKERRQ(ierr); 15000c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 15010c7d97c5SJed Brown ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 15020c7d97c5SJed Brown 150329622bf0SStefano Zampini if (pcbddc->inexact_prec_type || dbg_flag ) { 15040c7d97c5SJed Brown ierr = PetscMalloc(n_D*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 15050c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 15062fa5cd67SKarl Rupp for (i=0, j=0; i<n_R; i++) { 15072fa5cd67SKarl Rupp if (array[idx_R_local[i]] == zero) { 15082fa5cd67SKarl Rupp aux_array1[j] = i; 15092fa5cd67SKarl Rupp j++; 15102fa5cd67SKarl Rupp } 15112fa5cd67SKarl Rupp } 15120c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1513da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 15140c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 15150c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 15160c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 15170c7d97c5SJed Brown } 15180c7d97c5SJed Brown } 15190c7d97c5SJed Brown 1520304d26faSStefano Zampini /* setup local solvers */ 1521304d26faSStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,pcis->is_I_local,is_R_local);CHKERRQ(ierr); 15220c7d97c5SJed Brown 15230c7d97c5SJed Brown /* Assemble all remaining stuff needed to apply BDDC */ 15240c7d97c5SJed Brown { 15250c7d97c5SJed Brown Mat A_RV,A_VR,A_VV; 15260bdf917eSStefano Zampini Mat M1; 15270c7d97c5SJed Brown Mat C_CR; 15283b03a366Sstefano_zampini Mat AUXMAT; 15290c7d97c5SJed Brown Vec vec1_C; 15300c7d97c5SJed Brown Vec vec2_C; 15310c7d97c5SJed Brown Vec vec1_V; 15320c7d97c5SJed Brown Vec vec2_V; 1533e6872a76SStefano Zampini IS is_C_local,is_V_local,is_aux1; 1534e6872a76SStefano Zampini ISLocalToGlobalMapping BtoNmap; 15350c7d97c5SJed Brown PetscInt *nnz; 1536e6872a76SStefano Zampini PetscInt *idx_V_B; 15370c7d97c5SJed Brown PetscInt *auxindices; 153853cdbc3dSStefano Zampini PetscInt index; 15390c7d97c5SJed Brown PetscScalar* array2; 15400c7d97c5SJed Brown MatFactorInfo matinfo; 154115aaf578SStefano Zampini PetscBool setsym=PETSC_FALSE,issym=PETSC_FALSE; 15420c7d97c5SJed Brown 15430c7d97c5SJed Brown /* Allocating some extra storage just to be safe */ 15440c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 15450c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&auxindices);CHKERRQ(ierr); 15462fa5cd67SKarl Rupp for (i=0;i<pcis->n;i++) auxindices[i]=i; 15470c7d97c5SJed Brown 1548e6872a76SStefano Zampini ierr = PCBDDCGetPrimalVerticesLocalIdx(pc,&n_vertices,&vertices);CHKERRQ(ierr); 1549e6872a76SStefano Zampini /* vertices in boundary numbering */ 1550e6872a76SStefano Zampini ierr = PetscMalloc(n_vertices*sizeof(PetscInt),&idx_V_B);CHKERRQ(ierr); 1551e6872a76SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_B_local,&BtoNmap);CHKERRQ(ierr); 1552e6872a76SStefano Zampini ierr = ISGlobalToLocalMappingApply(BtoNmap,IS_GTOLM_DROP,n_vertices,vertices,&i,idx_V_B);CHKERRQ(ierr); 1553e6872a76SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&BtoNmap);CHKERRQ(ierr); 1554e6872a76SStefano Zampini if (i != n_vertices) { 1555e6872a76SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",n_vertices,i); 1556e6872a76SStefano Zampini } 1557e6872a76SStefano Zampini 15580c7d97c5SJed Brown /* some work vectors on vertices and/or constraints */ 15593b03a366Sstefano_zampini if (n_vertices) { 15600c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_V);CHKERRQ(ierr); 15613b03a366Sstefano_zampini ierr = VecSetSizes(vec1_V,n_vertices,n_vertices);CHKERRQ(ierr); 15620c7d97c5SJed Brown ierr = VecSetType(vec1_V,impVecType);CHKERRQ(ierr); 15630c7d97c5SJed Brown ierr = VecDuplicate(vec1_V,&vec2_V);CHKERRQ(ierr); 15640c7d97c5SJed Brown } 1565534831adSStefano Zampini if (n_constraints) { 15660c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_C);CHKERRQ(ierr); 1567534831adSStefano Zampini ierr = VecSetSizes(vec1_C,n_constraints,n_constraints);CHKERRQ(ierr); 15680c7d97c5SJed Brown ierr = VecSetType(vec1_C,impVecType);CHKERRQ(ierr); 15690c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&vec2_C);CHKERRQ(ierr); 15700c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&pcbddc->vec1_C);CHKERRQ(ierr); 15710c7d97c5SJed Brown } 15720c7d97c5SJed Brown /* Precompute stuffs needed for preprocessing and application of BDDC*/ 15733b03a366Sstefano_zampini if (n_constraints) { 15740c7d97c5SJed Brown ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->local_auxmat2);CHKERRQ(ierr); 15753b03a366Sstefano_zampini ierr = MatSetSizes(pcbddc->local_auxmat2,n_R,n_constraints,n_R,n_constraints);CHKERRQ(ierr); 15760c7d97c5SJed Brown ierr = MatSetType(pcbddc->local_auxmat2,impMatType);CHKERRQ(ierr); 15770298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(pcbddc->local_auxmat2,NULL);CHKERRQ(ierr); 15780c7d97c5SJed Brown 157957a90decSStefano Zampini /* Create Constraint matrix on R nodes: C_{CR} */ 1580e6872a76SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_C_local);CHKERRQ(ierr); 158157a90decSStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_C_local,is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 158257a90decSStefano Zampini ierr = ISDestroy(&is_C_local);CHKERRQ(ierr); 158357a90decSStefano Zampini 15840c7d97c5SJed Brown /* Assemble local_auxmat2 = - A_{RR}^{-1} C^T_{CR} needed by BDDC application */ 15853b03a366Sstefano_zampini for (i=0;i<n_constraints;i++) { 15863b03a366Sstefano_zampini ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 15873b03a366Sstefano_zampini /* Get row of constraint matrix in R numbering */ 158857a90decSStefano Zampini ierr = VecGetArray(pcbddc->vec1_R,&array);CHKERRQ(ierr); 158957a90decSStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 15902fa5cd67SKarl Rupp for (j=0;j<size_of_constraint;j++) array[row_cmat_indices[j]] = -row_cmat_values[j]; 159157a90decSStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 159257a90decSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_R,&array);CHKERRQ(ierr); 15932fa5cd67SKarl Rupp 15943b03a366Sstefano_zampini /* Solve for row of constraint matrix in R numbering */ 159553cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 15962fa5cd67SKarl Rupp 15973b03a366Sstefano_zampini /* Set values */ 15980c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 15993b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->local_auxmat2,n_R,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 16000c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 16010c7d97c5SJed Brown } 16020c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16030c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16040c7d97c5SJed Brown 16050c7d97c5SJed Brown /* Assemble AUXMAT = ( LUFactor )( -C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 16060c7d97c5SJed Brown ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AUXMAT);CHKERRQ(ierr); 1607d49ef151SStefano Zampini ierr = MatFactorInfoInitialize(&matinfo);CHKERRQ(ierr); 16083b03a366Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,0,1,&is_aux1);CHKERRQ(ierr); 16090c7d97c5SJed Brown ierr = MatLUFactor(AUXMAT,is_aux1,is_aux1,&matinfo);CHKERRQ(ierr); 16100c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 16110c7d97c5SJed Brown 16123b03a366Sstefano_zampini /* Assemble explicitly M1 = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} needed in preproc */ 1613d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M1);CHKERRQ(ierr); 16143b03a366Sstefano_zampini ierr = MatSetSizes(M1,n_constraints,n_constraints,n_constraints,n_constraints);CHKERRQ(ierr); 16150c7d97c5SJed Brown ierr = MatSetType(M1,impMatType);CHKERRQ(ierr); 16160298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(M1,NULL);CHKERRQ(ierr); 16173b03a366Sstefano_zampini for (i=0;i<n_constraints;i++) { 16180c7d97c5SJed Brown ierr = VecSet(vec1_C,zero);CHKERRQ(ierr); 16190c7d97c5SJed Brown ierr = VecSetValue(vec1_C,i,one,INSERT_VALUES);CHKERRQ(ierr); 16200c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_C);CHKERRQ(ierr); 16210c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_C);CHKERRQ(ierr); 16220c7d97c5SJed Brown ierr = MatSolve(AUXMAT,vec1_C,vec2_C);CHKERRQ(ierr); 16230c7d97c5SJed Brown ierr = VecScale(vec2_C,m_one);CHKERRQ(ierr); 16240c7d97c5SJed Brown ierr = VecGetArray(vec2_C,&array);CHKERRQ(ierr); 16253b03a366Sstefano_zampini ierr = MatSetValues(M1,n_constraints,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 16260c7d97c5SJed Brown ierr = VecRestoreArray(vec2_C,&array);CHKERRQ(ierr); 16270c7d97c5SJed Brown } 16280c7d97c5SJed Brown ierr = MatAssemblyBegin(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16290c7d97c5SJed Brown ierr = MatAssemblyEnd(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16300c7d97c5SJed Brown ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 16310c7d97c5SJed Brown /* Assemble local_auxmat1 = M1*C_{CR} needed by BDDC application in KSP and in preproc */ 16320c7d97c5SJed Brown ierr = MatMatMult(M1,C_CR,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 16330c7d97c5SJed Brown 16340c7d97c5SJed Brown } 16350c7d97c5SJed Brown 16360c7d97c5SJed Brown /* Get submatrices from subdomain matrix */ 16373b03a366Sstefano_zampini if (n_vertices) { 163815aaf578SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n_vertices,vertices,PETSC_COPY_VALUES,&is_V_local);CHKERRQ(ierr); 1639534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_R_local,is_V_local,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 1640534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_V_local,is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 1641534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_V_local,is_V_local,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 164215aaf578SStefano Zampini ierr = ISDestroy(&is_V_local);CHKERRQ(ierr); 16430c7d97c5SJed Brown } 16440c7d97c5SJed Brown 16450c7d97c5SJed Brown /* Matrix of coarse basis functions (local) */ 1646d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 16470c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 16480c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_B,impMatType);CHKERRQ(ierr); 16490298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_phi_B,NULL);CHKERRQ(ierr); 165029622bf0SStefano Zampini if (pcbddc->inexact_prec_type || dbg_flag ) { 1651d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 16520c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 16530c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_D,impMatType);CHKERRQ(ierr); 16540298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_phi_D,NULL);CHKERRQ(ierr); 16550c7d97c5SJed Brown } 16560c7d97c5SJed Brown 1657e269702eSStefano Zampini if (dbg_flag) { 16585b08dc53SStefano Zampini ierr = PetscMalloc(2*pcbddc->local_primal_size*sizeof(*coarsefunctions_errors),&coarsefunctions_errors);CHKERRQ(ierr); 16595b08dc53SStefano Zampini ierr = PetscMalloc(2*pcbddc->local_primal_size*sizeof(*constraints_errors),&constraints_errors);CHKERRQ(ierr); 16600c7d97c5SJed Brown } 16613b03a366Sstefano_zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 16620c7d97c5SJed Brown ierr = PetscMalloc ((pcbddc->local_primal_size)*(pcbddc->local_primal_size)*sizeof(PetscScalar),&coarse_submat_vals);CHKERRQ(ierr); 16630c7d97c5SJed Brown 16640c7d97c5SJed Brown /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 16653b03a366Sstefano_zampini for (i=0;i<n_vertices;i++){ 16660c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 16670c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 16680c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 16690c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 16700c7d97c5SJed Brown /* solution of saddle point problem */ 16710bdf917eSStefano Zampini ierr = MatMult(A_RV,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 16720bdf917eSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 16730c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_R,m_one);CHKERRQ(ierr); 16743b03a366Sstefano_zampini if (n_constraints) { 16750c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec1_R,vec1_C);CHKERRQ(ierr); 16760c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 16770c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 16780c7d97c5SJed Brown } 16790c7d97c5SJed Brown ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); 16800c7d97c5SJed Brown ierr = MatMultAdd(A_VV,vec1_V,vec2_V,vec2_V);CHKERRQ(ierr); 16810c7d97c5SJed Brown 16820c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 16830c7d97c5SJed Brown /* coarse basis functions */ 16840c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 16850c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16860c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16870c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 16883b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 16890c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 16900c7d97c5SJed Brown ierr = MatSetValue(pcbddc->coarse_phi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 169129622bf0SStefano Zampini if ( pcbddc->inexact_prec_type || dbg_flag ) { 16920c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16930c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16940c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 16953b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 16960c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 16970c7d97c5SJed Brown } 16980c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 16990c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 17002fa5cd67SKarl Rupp for (j=0; j<n_vertices; j++) coarse_submat_vals[i*pcbddc->local_primal_size+j] = array[j]; /* WARNING -> column major ordering */ 17010c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 17023b03a366Sstefano_zampini if (n_constraints) { 17030c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 17042fa5cd67SKarl 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 */ 17050c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 17060c7d97c5SJed Brown } 17070c7d97c5SJed Brown 1708e269702eSStefano Zampini if ( dbg_flag ) { 17090c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 1710d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 17110c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 17120c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 17132fa5cd67SKarl Rupp for (j=0;j<n_R;j++) array[idx_R_local[j]] = array2[j]; 17143b03a366Sstefano_zampini array[ vertices[i] ] = one; 17150c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 17160c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 17170c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers (i.e. primal nodes) */ 1718d49ef151SStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 17190c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 17200c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 17212fa5cd67SKarl Rupp for (j=0;j<n_vertices;j++) array2[j]=array[j]; 17220c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 17233b03a366Sstefano_zampini if (n_constraints) { 17240c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 17252fa5cd67SKarl Rupp for (j=0;j<n_constraints;j++) array2[j+n_vertices]=array[j]; 17260c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 17270c7d97c5SJed Brown } 17280c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 17290c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_P,m_one);CHKERRQ(ierr); 17300c7d97c5SJed Brown /* check saddle point solution */ 1731534831adSStefano Zampini ierr = MatMult(pcbddc->local_mat,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 17323b03a366Sstefano_zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 17333b03a366Sstefano_zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[i]);CHKERRQ(ierr); 17343b03a366Sstefano_zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 17350c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 17363b03a366Sstefano_zampini array[i]=array[i]+m_one; /* shift by the identity matrix */ 17370c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 17383b03a366Sstefano_zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[i]);CHKERRQ(ierr); 17390c7d97c5SJed Brown } 17400c7d97c5SJed Brown } 17410c7d97c5SJed Brown 17423b03a366Sstefano_zampini for (i=0;i<n_constraints;i++){ 1743d49ef151SStefano Zampini ierr = VecSet(vec2_C,zero);CHKERRQ(ierr); 17440c7d97c5SJed Brown ierr = VecSetValue(vec2_C,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 17450c7d97c5SJed Brown ierr = VecAssemblyBegin(vec2_C);CHKERRQ(ierr); 17460c7d97c5SJed Brown ierr = VecAssemblyEnd(vec2_C);CHKERRQ(ierr); 17470c7d97c5SJed Brown /* solution of saddle point problem */ 17480c7d97c5SJed Brown ierr = MatMult(M1,vec2_C,vec1_C);CHKERRQ(ierr); 17490c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 17500c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 17513b03a366Sstefano_zampini if (n_vertices) { ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); } 17520c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 17530c7d97c5SJed Brown /* coarse basis functions */ 17543b03a366Sstefano_zampini index=i+n_vertices; 17550c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 17560c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17570c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17580c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 175953cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 17600c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 176129622bf0SStefano Zampini if ( pcbddc->inexact_prec_type || dbg_flag ) { 17620c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17630c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17640c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 176553cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 17660c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 17670c7d97c5SJed Brown } 17680c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 17693b03a366Sstefano_zampini if (n_vertices) { 17700c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 17712fa5cd67SKarl Rupp for (j=0; j<n_vertices; j++) coarse_submat_vals[index*pcbddc->local_primal_size+j]=array[j]; /* WARNING -> column major ordering */ 17720c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 17730c7d97c5SJed Brown } 17740c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 17752fa5cd67SKarl 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 */ 17760c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 17770c7d97c5SJed Brown 1778e269702eSStefano Zampini if ( dbg_flag ) { 17790c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 178053cdbc3dSStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 17810c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 17820c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 17832fa5cd67SKarl Rupp for (j=0;j<n_R;j++) array[idx_R_local[j]] = array2[j]; 17840c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 17850c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 17860c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers */ 178753cdbc3dSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 17880c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 17893b03a366Sstefano_zampini if ( n_vertices) { 17900c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 17912fa5cd67SKarl Rupp for (j=0;j<n_vertices;j++) array2[j]=-array[j]; 17920c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 17930c7d97c5SJed Brown } 17940c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 17953b03a366Sstefano_zampini for (j=0;j<n_constraints;j++) {array2[j+n_vertices]=-array[j];} 17960c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 17970c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 17983972b0daSStefano Zampini /* check saddle point solution */ 1799534831adSStefano Zampini ierr = MatMult(pcbddc->local_mat,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 18003b03a366Sstefano_zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 180153cdbc3dSStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[index]);CHKERRQ(ierr); 18023b03a366Sstefano_zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 18030c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 180453cdbc3dSStefano Zampini array[index]=array[index]+m_one; /* shift by the identity matrix */ 18050c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 180653cdbc3dSStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[index]);CHKERRQ(ierr); 18070c7d97c5SJed Brown } 18080c7d97c5SJed Brown } 18090c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18100c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 181129622bf0SStefano Zampini if ( pcbddc->inexact_prec_type || dbg_flag ) { 18120c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18130c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18140c7d97c5SJed Brown } 181515aaf578SStefano Zampini /* compute other basis functions for non-symmetric problems */ 181615aaf578SStefano Zampini ierr = MatIsSymmetricKnown(pc->pmat,&setsym,&issym);CHKERRQ(ierr); 181715aaf578SStefano Zampini if ( !setsym || (setsym && !issym) ) { 181815aaf578SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 181915aaf578SStefano Zampini ierr = MatSetSizes(pcbddc->coarse_psi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 182015aaf578SStefano Zampini ierr = MatSetType(pcbddc->coarse_psi_B,impMatType);CHKERRQ(ierr); 182115aaf578SStefano Zampini ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_psi_B,NULL);CHKERRQ(ierr); 182215aaf578SStefano Zampini if (pcbddc->inexact_prec_type || dbg_flag ) { 182315aaf578SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 182415aaf578SStefano Zampini ierr = MatSetSizes(pcbddc->coarse_psi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 182515aaf578SStefano Zampini ierr = MatSetType(pcbddc->coarse_psi_D,impMatType);CHKERRQ(ierr); 182615aaf578SStefano Zampini ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_psi_D,NULL);CHKERRQ(ierr); 182715aaf578SStefano Zampini } 182815aaf578SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 182915aaf578SStefano Zampini if (n_constraints) { 183015aaf578SStefano Zampini ierr = VecSet(vec1_C,zero);CHKERRQ(ierr); 183115aaf578SStefano Zampini ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 183215aaf578SStefano Zampini for (j=0;j<n_constraints;j++) { 183315aaf578SStefano Zampini array[j]=coarse_submat_vals[(j+n_vertices)*pcbddc->local_primal_size+i]; 183415aaf578SStefano Zampini } 183515aaf578SStefano Zampini ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 183615aaf578SStefano Zampini } 183715aaf578SStefano Zampini if (i<n_vertices) { 183815aaf578SStefano Zampini ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 183915aaf578SStefano Zampini ierr = VecSetValue(vec1_V,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 184015aaf578SStefano Zampini ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 184115aaf578SStefano Zampini ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 184215aaf578SStefano Zampini ierr = MatMultTranspose(A_VR,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 184315aaf578SStefano Zampini if (n_constraints) { 184415aaf578SStefano Zampini ierr = MatMultTransposeAdd(C_CR,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 184515aaf578SStefano Zampini } 184615aaf578SStefano Zampini } else { 184715aaf578SStefano Zampini ierr = MatMultTranspose(C_CR,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 184815aaf578SStefano Zampini } 184915aaf578SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 185015aaf578SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 185115aaf578SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 185215aaf578SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 185315aaf578SStefano Zampini ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 185415aaf578SStefano Zampini ierr = MatSetValues(pcbddc->coarse_psi_B,n_B,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 185515aaf578SStefano Zampini ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 185615aaf578SStefano Zampini if (i<n_vertices) { 185715aaf578SStefano Zampini ierr = MatSetValue(pcbddc->coarse_psi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 185815aaf578SStefano Zampini } 185915aaf578SStefano Zampini if ( pcbddc->inexact_prec_type || dbg_flag ) { 186015aaf578SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 186115aaf578SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 186215aaf578SStefano Zampini ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 186315aaf578SStefano Zampini ierr = MatSetValues(pcbddc->coarse_psi_D,n_D,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 186415aaf578SStefano Zampini ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 186515aaf578SStefano Zampini } 186615aaf578SStefano Zampini 186715aaf578SStefano Zampini if ( dbg_flag ) { 186815aaf578SStefano Zampini /* assemble subdomain vector on nodes */ 186915aaf578SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 187015aaf578SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 187115aaf578SStefano Zampini ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 187215aaf578SStefano Zampini for (j=0;j<n_R;j++) array[idx_R_local[j]] = array2[j]; 187315aaf578SStefano Zampini if (i<n_vertices) array[vertices[i]] = one; 187415aaf578SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 187515aaf578SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 187615aaf578SStefano Zampini /* assemble subdomain vector of lagrange multipliers */ 187715aaf578SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 187815aaf578SStefano Zampini for (j=0;j<pcbddc->local_primal_size;j++) { 187915aaf578SStefano Zampini array[j]=-coarse_submat_vals[j*pcbddc->local_primal_size+i]; 188015aaf578SStefano Zampini } 188115aaf578SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 188215aaf578SStefano Zampini /* check saddle point solution */ 188315aaf578SStefano Zampini ierr = MatMultTranspose(pcbddc->local_mat,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 188415aaf578SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 188515aaf578SStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[i+pcbddc->local_primal_size]);CHKERRQ(ierr); 188615aaf578SStefano Zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 188715aaf578SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 188815aaf578SStefano Zampini array[i]=array[i]+m_one; /* shift by the identity matrix */ 188915aaf578SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 189015aaf578SStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[i+pcbddc->local_primal_size]);CHKERRQ(ierr); 189115aaf578SStefano Zampini } 189215aaf578SStefano Zampini } 189315aaf578SStefano Zampini ierr = MatAssemblyBegin(pcbddc->coarse_psi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 189415aaf578SStefano Zampini ierr = MatAssemblyEnd(pcbddc->coarse_psi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 189515aaf578SStefano Zampini if ( pcbddc->inexact_prec_type || dbg_flag ) { 189615aaf578SStefano Zampini ierr = MatAssemblyBegin(pcbddc->coarse_psi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 189715aaf578SStefano Zampini ierr = MatAssemblyEnd(pcbddc->coarse_psi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 189815aaf578SStefano Zampini } 189915aaf578SStefano Zampini } 190015aaf578SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 19010c7d97c5SJed Brown /* Checking coarse_sub_mat and coarse basis functios */ 190215aaf578SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 190315aaf578SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 19049d2fce94SStefano Zampini if (dbg_flag) { 19050c7d97c5SJed Brown Mat coarse_sub_mat; 19060c7d97c5SJed Brown Mat TM1,TM2,TM3,TM4; 190715aaf578SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 190815aaf578SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 190915aaf578SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 191019fd82e9SBarry Smith MatType checkmattype=MATSEQAIJ; 19115b08dc53SStefano Zampini PetscReal real_value; 19120c7d97c5SJed Brown 1913c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 1914c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 1915c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 1916c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 1917c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 1918c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 191915aaf578SStefano Zampini if (pcbddc->coarse_psi_B) { 192015aaf578SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 192115aaf578SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 192215aaf578SStefano Zampini } 1923c042a7c3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 19240c7d97c5SJed Brown 19250c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 19260c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Check coarse sub mat and local basis functions\n");CHKERRQ(ierr); 19270c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 192815aaf578SStefano Zampini if (pcbddc->coarse_psi_B) { 192915aaf578SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 193015aaf578SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 193115aaf578SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 193215aaf578SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 193315aaf578SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 193415aaf578SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 193515aaf578SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 193615aaf578SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 193715aaf578SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 193815aaf578SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 193915aaf578SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 194015aaf578SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 194115aaf578SStefano Zampini } else { 194253cdbc3dSStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 194353cdbc3dSStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 194453cdbc3dSStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1945c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 194653cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 194753cdbc3dSStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1948c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 194953cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 195015aaf578SStefano Zampini } 195153cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 195253cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 195353cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 195415aaf578SStefano Zampini ierr = MatConvert(TM1,MATSEQDENSE,MAT_REUSE_MATRIX,&TM1);CHKERRQ(ierr); 195515aaf578SStefano Zampini ierr = MatAXPY(TM1,m_one,coarse_sub_mat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 19565b08dc53SStefano Zampini ierr = MatNorm(TM1,NORM_INFINITY,&real_value);CHKERRQ(ierr); 19570c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"----------------------------------\n");CHKERRQ(ierr); 19580c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d \n",PetscGlobalRank);CHKERRQ(ierr); 19595b08dc53SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"matrix error = % 1.14e\n",real_value);CHKERRQ(ierr); 196015aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"coarse functions (phi) errors\n");CHKERRQ(ierr); 196115aaf578SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 196215aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local %02d-th function error = % 1.14e\n",i,coarsefunctions_errors[i]);CHKERRQ(ierr); 196315aaf578SStefano Zampini } 196415aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"constraints (phi) errors\n");CHKERRQ(ierr); 196515aaf578SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 196615aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local %02d-th function error = % 1.14e\n",i,constraints_errors[i]);CHKERRQ(ierr); 196715aaf578SStefano Zampini } 196815aaf578SStefano Zampini if (pcbddc->coarse_psi_B) { 196915aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"coarse functions (psi) errors\n");CHKERRQ(ierr); 197015aaf578SStefano Zampini for (i=pcbddc->local_primal_size;i<2*pcbddc->local_primal_size;i++) { 197115aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local %02d-th function error = % 1.14e\n",i-pcbddc->local_primal_size,coarsefunctions_errors[i]);CHKERRQ(ierr); 197215aaf578SStefano Zampini } 197315aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"constraints (psi) errors\n");CHKERRQ(ierr); 197415aaf578SStefano Zampini for (i=pcbddc->local_primal_size;i<2*pcbddc->local_primal_size;i++) { 197515aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local %02d-th function error = % 1.14e\n",i-pcbddc->local_primal_size,constraints_errors[i]);CHKERRQ(ierr); 197615aaf578SStefano Zampini } 197715aaf578SStefano Zampini } 19780c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 197953cdbc3dSStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 198053cdbc3dSStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 198153cdbc3dSStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 198253cdbc3dSStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 198353cdbc3dSStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 198453cdbc3dSStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 198553cdbc3dSStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 198653cdbc3dSStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 198753cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 198853cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 198915aaf578SStefano Zampini if (pcbddc->coarse_psi_B) { 199015aaf578SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 199115aaf578SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 199215aaf578SStefano Zampini } 199315aaf578SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 19940c7d97c5SJed Brown ierr = PetscFree(coarsefunctions_errors);CHKERRQ(ierr); 19950c7d97c5SJed Brown ierr = PetscFree(constraints_errors);CHKERRQ(ierr); 19960c7d97c5SJed Brown } 19970c7d97c5SJed Brown /* free memory */ 19983b03a366Sstefano_zampini if (n_vertices) { 199915aaf578SStefano Zampini ierr = PetscFree(vertices);CHKERRQ(ierr); 20000c7d97c5SJed Brown ierr = VecDestroy(&vec1_V);CHKERRQ(ierr); 20010c7d97c5SJed Brown ierr = VecDestroy(&vec2_V);CHKERRQ(ierr); 20020c7d97c5SJed Brown ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 20030c7d97c5SJed Brown ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 20040c7d97c5SJed Brown ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 20050c7d97c5SJed Brown } 2006534831adSStefano Zampini if (n_constraints) { 20070c7d97c5SJed Brown ierr = VecDestroy(&vec1_C);CHKERRQ(ierr); 20080c7d97c5SJed Brown ierr = VecDestroy(&vec2_C);CHKERRQ(ierr); 20090c7d97c5SJed Brown ierr = MatDestroy(&M1);CHKERRQ(ierr); 20100c7d97c5SJed Brown ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 20110c7d97c5SJed Brown } 2012a929c220SStefano Zampini ierr = PetscFree(auxindices);CHKERRQ(ierr); 2013a929c220SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2014a929c220SStefano Zampini /* create coarse matrix and data structures for message passing associated actual choice of coarse problem type */ 2015674ae819SStefano Zampini ierr = PCBDDCSetUpCoarseEnvironment(pc,coarse_submat_vals);CHKERRQ(ierr); 2016a929c220SStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 20170c7d97c5SJed Brown } 20180c7d97c5SJed Brown /* free memory */ 20190c7d97c5SJed Brown ierr = ISDestroy(&is_R_local);CHKERRQ(ierr); 2020674ae819SStefano Zampini 20210c7d97c5SJed Brown PetscFunctionReturn(0); 20220c7d97c5SJed Brown } 20230c7d97c5SJed Brown 20240c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 20250c7d97c5SJed Brown 20267cbb387bSStefano Zampini /* BDDC requires metis 5.0.1 for multilevel */ 20277cbb387bSStefano Zampini #if defined(PETSC_HAVE_METIS) 20287cbb387bSStefano Zampini #include "metis.h" 20297cbb387bSStefano Zampini #define MetisInt idx_t 20307cbb387bSStefano Zampini #define MetisScalar real_t 20317cbb387bSStefano Zampini #endif 20327cbb387bSStefano Zampini 20330c7d97c5SJed Brown #undef __FUNCT__ 2034674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseEnvironment" 2035674ae819SStefano Zampini static PetscErrorCode PCBDDCSetUpCoarseEnvironment(PC pc,PetscScalar* coarse_submat_vals) 20360c7d97c5SJed Brown { 2037674ae819SStefano Zampini 2038674ae819SStefano Zampini 20390c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 20400c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 20410c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 2042ce94432eSBarry Smith MPI_Comm prec_comm; 20430c7d97c5SJed Brown MPI_Comm coarse_comm; 20440c7d97c5SJed Brown 2045674ae819SStefano Zampini MatNullSpace CoarseNullSpace; 2046674ae819SStefano Zampini 20470c7d97c5SJed Brown /* common to all choiches */ 20480c7d97c5SJed Brown PetscScalar *temp_coarse_mat_vals; 20490c7d97c5SJed Brown PetscScalar *ins_coarse_mat_vals; 20500c7d97c5SJed Brown PetscInt *ins_local_primal_indices; 20510c7d97c5SJed Brown PetscMPIInt *localsizes2,*localdispl2; 20520c7d97c5SJed Brown PetscMPIInt size_prec_comm; 20530c7d97c5SJed Brown PetscMPIInt rank_prec_comm; 20540c7d97c5SJed Brown PetscMPIInt active_rank=MPI_PROC_NULL; 20550c7d97c5SJed Brown PetscMPIInt master_proc=0; 20560c7d97c5SJed Brown PetscInt ins_local_primal_size; 20570c7d97c5SJed Brown /* specific to MULTILEVEL_BDDC */ 20585b08dc53SStefano Zampini PetscMPIInt *ranks_recv=0; 20590c7d97c5SJed Brown PetscMPIInt count_recv=0; 20605b08dc53SStefano Zampini PetscMPIInt rank_coarse_proc_send_to=-1; 20610c7d97c5SJed Brown PetscMPIInt coarse_color = MPI_UNDEFINED; 20620c7d97c5SJed Brown ISLocalToGlobalMapping coarse_ISLG; 20630c7d97c5SJed Brown /* some other variables */ 20640c7d97c5SJed Brown PetscErrorCode ierr; 206519fd82e9SBarry Smith MatType coarse_mat_type; 206619fd82e9SBarry Smith PCType coarse_pc_type; 206719fd82e9SBarry Smith KSPType coarse_ksp_type; 206853cdbc3dSStefano Zampini PC pc_temp; 20694fad6a16SStefano Zampini PetscInt i,j,k; 20703b03a366Sstefano_zampini PetscInt max_it_coarse_ksp=1; /* don't increase this value */ 2071e269702eSStefano Zampini /* verbose output viewer */ 2072e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 20735b08dc53SStefano Zampini PetscInt dbg_flag=pcbddc->dbg_flag; 2074142dfd88SStefano Zampini 2075ea7e1babSStefano Zampini PetscInt offset,offset2; 2076a929c220SStefano Zampini PetscMPIInt im_active,active_procs; 2077523858cfSStefano Zampini PetscInt *dnz,*onz; 2078142dfd88SStefano Zampini 2079142dfd88SStefano Zampini PetscBool setsym,issym=PETSC_FALSE; 20800c7d97c5SJed Brown 20810c7d97c5SJed Brown PetscFunctionBegin; 20824b2d0b89SJed Brown ierr = PetscObjectGetComm((PetscObject)pc,&prec_comm);CHKERRQ(ierr); 20830c7d97c5SJed Brown ins_local_primal_indices = 0; 20840c7d97c5SJed Brown ins_coarse_mat_vals = 0; 20850c7d97c5SJed Brown localsizes2 = 0; 20860c7d97c5SJed Brown localdispl2 = 0; 20870c7d97c5SJed Brown temp_coarse_mat_vals = 0; 20880c7d97c5SJed Brown coarse_ISLG = 0; 20890c7d97c5SJed Brown 209053cdbc3dSStefano Zampini ierr = MPI_Comm_size(prec_comm,&size_prec_comm);CHKERRQ(ierr); 209153cdbc3dSStefano Zampini ierr = MPI_Comm_rank(prec_comm,&rank_prec_comm);CHKERRQ(ierr); 2092142dfd88SStefano Zampini ierr = MatIsSymmetricKnown(pc->pmat,&setsym,&issym);CHKERRQ(ierr); 2093142dfd88SStefano Zampini 2094beed3852SStefano Zampini /* Assign global numbering to coarse dofs */ 2095beed3852SStefano Zampini { 2096674ae819SStefano Zampini PetscInt *auxlocal_primal,*aux_idx; 2097ef028eecSStefano Zampini PetscMPIInt mpi_local_primal_size; 2098ef028eecSStefano Zampini PetscScalar coarsesum,*array; 2099ef028eecSStefano Zampini 2100ef028eecSStefano Zampini mpi_local_primal_size = (PetscMPIInt)pcbddc->local_primal_size; 2101beed3852SStefano Zampini 2102beed3852SStefano Zampini /* Construct needed data structures for message passing */ 2103ffe5efe1SStefano Zampini j = 0; 2104142dfd88SStefano Zampini if (rank_prec_comm == 0 || pcbddc->coarse_problem_type == REPLICATED_BDDC || pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2105ffe5efe1SStefano Zampini j = size_prec_comm; 2106ffe5efe1SStefano Zampini } 2107ffe5efe1SStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->local_primal_sizes);CHKERRQ(ierr); 2108ffe5efe1SStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 2109beed3852SStefano Zampini /* Gather local_primal_size information for all processes */ 2110142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == REPLICATED_BDDC || pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 21115619798eSStefano Zampini ierr = MPI_Allgather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,prec_comm);CHKERRQ(ierr); 2112ffe5efe1SStefano Zampini } else { 2113ffe5efe1SStefano Zampini ierr = MPI_Gather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 2114ffe5efe1SStefano Zampini } 2115beed3852SStefano Zampini pcbddc->replicated_primal_size = 0; 2116ffe5efe1SStefano Zampini for (i=0; i<j; i++) { 2117beed3852SStefano Zampini pcbddc->local_primal_displacements[i] = pcbddc->replicated_primal_size ; 2118beed3852SStefano Zampini pcbddc->replicated_primal_size += pcbddc->local_primal_sizes[i]; 2119beed3852SStefano Zampini } 2120beed3852SStefano Zampini 2121da1bb401SStefano Zampini /* First let's count coarse dofs. 2122beed3852SStefano Zampini This code fragment assumes that the number of local constraints per connected component 2123beed3852SStefano Zampini is not greater than the number of nodes defined for the connected component 2124beed3852SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 2125ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscInt),&auxlocal_primal);CHKERRQ(ierr); 2126674ae819SStefano Zampini ierr = PCBDDCGetPrimalVerticesLocalIdx(pc,&i,&aux_idx);CHKERRQ(ierr); 2127674ae819SStefano Zampini ierr = PetscMemcpy(auxlocal_primal,aux_idx,i*sizeof(PetscInt));CHKERRQ(ierr); 2128674ae819SStefano Zampini ierr = PetscFree(aux_idx);CHKERRQ(ierr); 2129674ae819SStefano Zampini ierr = PCBDDCGetPrimalConstraintsLocalIdx(pc,&j,&aux_idx);CHKERRQ(ierr); 2130674ae819SStefano Zampini ierr = PetscMemcpy(&auxlocal_primal[i],aux_idx,j*sizeof(PetscInt));CHKERRQ(ierr); 2131674ae819SStefano Zampini ierr = PetscFree(aux_idx);CHKERRQ(ierr); 2132ef028eecSStefano Zampini /* Compute number of coarse dofs */ 2133674ae819SStefano Zampini ierr = PCBDDCSubsetNumbering(prec_comm,matis->mapping,pcbddc->local_primal_size,auxlocal_primal,NULL,&pcbddc->coarse_size,&pcbddc->local_primal_indices);CHKERRQ(ierr); 2134ef028eecSStefano Zampini 2135ef028eecSStefano Zampini if (dbg_flag) { 21362e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 21372e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 21382e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Check coarse indices\n");CHKERRQ(ierr); 21392e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 21402e8d2280SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 21412fa5cd67SKarl Rupp for (i=0;i<pcbddc->local_primal_size;i++) array[auxlocal_primal[i]]=1.0; 2142beed3852SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 21432e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 2144da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2145da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2146da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2147da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2148da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 21492e8d2280SStefano Zampini for (i=0;i<pcis->n;i++) { 21502e8d2280SStefano Zampini if (array[i] == 1.0) { 21512e8d2280SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,1,&i,&j);CHKERRQ(ierr); 21522e8d2280SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d: WRONG COARSE INDEX %d (local %d)\n",PetscGlobalRank,j,i);CHKERRQ(ierr); 21532e8d2280SStefano Zampini } 21542e8d2280SStefano Zampini } 21552e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 21562e8d2280SStefano Zampini for (i=0;i<pcis->n;i++) { 21575b08dc53SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 21582e8d2280SStefano Zampini } 2159da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 21602e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 2161da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2162da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2163da1bb401SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 21642e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem SHOULD be %lf\n",coarsesum);CHKERRQ(ierr); 21652e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 21662e8d2280SStefano Zampini } 2167142dfd88SStefano Zampini ierr = PetscFree(auxlocal_primal);CHKERRQ(ierr); 21680bdf917eSStefano Zampini } 21690bdf917eSStefano Zampini 21702e8d2280SStefano Zampini if (dbg_flag) { 21717cf533a6SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem is %d\n",pcbddc->coarse_size);CHKERRQ(ierr); 21729d9e44b6SStefano Zampini if (dbg_flag > 1) { 2173674ae819SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 21742e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2175674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 2176674ae819SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 2177674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_primal_indices[%d]=%d \n",i,pcbddc->local_primal_indices[i]); 2178674ae819SStefano Zampini } 21792e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 21802e8d2280SStefano Zampini } 21812e8d2280SStefano Zampini } 21822e8d2280SStefano Zampini 2183a929c220SStefano Zampini im_active = 0; 21842fa5cd67SKarl Rupp if (pcis->n) im_active = 1; 2185a929c220SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,prec_comm);CHKERRQ(ierr); 21860bdf917eSStefano Zampini 21870bdf917eSStefano Zampini /* adapt coarse problem type */ 21887cbb387bSStefano Zampini #if defined(PETSC_HAVE_METIS) 21894fad6a16SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 21904fad6a16SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 2191a929c220SStefano Zampini if ( (active_procs/pcbddc->coarsening_ratio) < 2 ) { 21920bdf917eSStefano Zampini if (dbg_flag) { 2193a929c220SStefano 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); 21940bdf917eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 21950bdf917eSStefano Zampini } 21960bdf917eSStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 2197142dfd88SStefano Zampini } 21984fad6a16SStefano Zampini } else { 21994fad6a16SStefano Zampini if (dbg_flag) { 2200a929c220SStefano 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); 22014fad6a16SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 22024fad6a16SStefano Zampini } 22034fad6a16SStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 22044fad6a16SStefano Zampini } 22054fad6a16SStefano Zampini } 22067cbb387bSStefano Zampini #else 22077cbb387bSStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 22087cbb387bSStefano Zampini #endif 2209beed3852SStefano Zampini 22100c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 22110c7d97c5SJed Brown 2212da1bb401SStefano Zampini case(MULTILEVEL_BDDC): /* we define a coarse mesh where subdomains are elements */ 22130c7d97c5SJed Brown { 22147cbb387bSStefano Zampini #if defined(PETSC_HAVE_METIS) 22150c7d97c5SJed Brown /* we need additional variables */ 22160c7d97c5SJed Brown MetisInt n_subdomains,n_parts,objval,ncon,faces_nvtxs; 22170c7d97c5SJed Brown MetisInt *metis_coarse_subdivision; 22180c7d97c5SJed Brown MetisInt options[METIS_NOPTIONS]; 22190c7d97c5SJed Brown PetscMPIInt size_coarse_comm,rank_coarse_comm; 22200c7d97c5SJed Brown PetscMPIInt procs_jumps_coarse_comm; 22210c7d97c5SJed Brown PetscMPIInt *coarse_subdivision; 22220c7d97c5SJed Brown PetscMPIInt *total_count_recv; 22230c7d97c5SJed Brown PetscMPIInt *total_ranks_recv; 22240c7d97c5SJed Brown PetscMPIInt *displacements_recv; 22250c7d97c5SJed Brown PetscMPIInt *my_faces_connectivity; 22260c7d97c5SJed Brown PetscMPIInt *petsc_faces_adjncy; 22270c7d97c5SJed Brown MetisInt *faces_adjncy; 22280c7d97c5SJed Brown MetisInt *faces_xadj; 22290c7d97c5SJed Brown PetscMPIInt *number_of_faces; 22300c7d97c5SJed Brown PetscMPIInt *faces_displacements; 22310c7d97c5SJed Brown PetscInt *array_int; 22320c7d97c5SJed Brown PetscMPIInt my_faces=0; 22330c7d97c5SJed Brown PetscMPIInt total_faces=0; 22343828260eSStefano Zampini PetscInt ranks_stretching_ratio; 22350c7d97c5SJed Brown 22360c7d97c5SJed Brown /* define some quantities */ 22370c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 22380c7d97c5SJed Brown coarse_mat_type = MATIS; 22390c7d97c5SJed Brown coarse_pc_type = PCBDDC; 2240142dfd88SStefano Zampini coarse_ksp_type = KSPRICHARDSON; 22410c7d97c5SJed Brown 22420c7d97c5SJed Brown /* details of coarse decomposition */ 2243a929c220SStefano Zampini n_subdomains = active_procs; 22440c7d97c5SJed Brown n_parts = n_subdomains/pcbddc->coarsening_ratio; 2245a929c220SStefano Zampini ranks_stretching_ratio = size_prec_comm/active_procs; 22463828260eSStefano Zampini procs_jumps_coarse_comm = pcbddc->coarsening_ratio*ranks_stretching_ratio; 22473828260eSStefano Zampini 2248a929c220SStefano Zampini #if 0 2249a929c220SStefano Zampini PetscMPIInt *old_ranks; 2250a929c220SStefano Zampini PetscInt *new_ranks,*jj,*ii; 2251a929c220SStefano Zampini MatPartitioning mat_part; 2252a929c220SStefano Zampini IS coarse_new_decomposition,is_numbering; 2253a929c220SStefano Zampini PetscViewer viewer_test; 2254a929c220SStefano Zampini MPI_Comm test_coarse_comm; 2255a929c220SStefano Zampini PetscMPIInt test_coarse_color; 2256a929c220SStefano Zampini Mat mat_adj; 2257a929c220SStefano Zampini /* Create new communicator for coarse problem splitting the old one */ 2258a929c220SStefano Zampini /* procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 2259a929c220SStefano Zampini key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator */ 2260a929c220SStefano Zampini test_coarse_color = ( im_active ? 0 : MPI_UNDEFINED ); 2261a929c220SStefano Zampini test_coarse_comm = MPI_COMM_NULL; 2262a929c220SStefano Zampini ierr = MPI_Comm_split(prec_comm,test_coarse_color,rank_prec_comm,&test_coarse_comm);CHKERRQ(ierr); 2263a929c220SStefano Zampini if (im_active) { 2264a929c220SStefano Zampini ierr = PetscMalloc(n_subdomains*sizeof(PetscMPIInt),&old_ranks); 2265a929c220SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscInt),&new_ranks); 2266a929c220SStefano Zampini ierr = MPI_Comm_rank(test_coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 2267a929c220SStefano Zampini ierr = MPI_Comm_size(test_coarse_comm,&j);CHKERRQ(ierr); 2268a929c220SStefano Zampini ierr = MPI_Allgather(&rank_prec_comm,1,MPIU_INT,old_ranks,1,MPIU_INT,test_coarse_comm);CHKERRQ(ierr); 2269674ae819SStefano Zampini for (i=0; i<size_prec_comm; i++) new_ranks[i] = -1; 2270674ae819SStefano Zampini for (i=0; i<n_subdomains; i++) new_ranks[old_ranks[i]] = i; 2271a929c220SStefano Zampini ierr = PetscViewerASCIIOpen(test_coarse_comm,"test_mat_part.out",&viewer_test);CHKERRQ(ierr); 2272a929c220SStefano Zampini k = pcis->n_neigh-1; 2273a929c220SStefano Zampini ierr = PetscMalloc(2*sizeof(PetscInt),&ii); 2274a929c220SStefano Zampini ii[0]=0; 2275a929c220SStefano Zampini ii[1]=k; 2276a929c220SStefano Zampini ierr = PetscMalloc(k*sizeof(PetscInt),&jj); 2277674ae819SStefano Zampini for (i=0; i<k; i++) jj[i]=new_ranks[pcis->neigh[i+1]]; 2278a929c220SStefano Zampini ierr = PetscSortInt(k,jj);CHKERRQ(ierr); 22790298fd71SBarry Smith ierr = MatCreateMPIAdj(test_coarse_comm,1,n_subdomains,ii,jj,NULL,&mat_adj);CHKERRQ(ierr); 2280a929c220SStefano Zampini ierr = MatView(mat_adj,viewer_test);CHKERRQ(ierr); 2281a929c220SStefano Zampini ierr = MatPartitioningCreate(test_coarse_comm,&mat_part);CHKERRQ(ierr); 2282a929c220SStefano Zampini ierr = MatPartitioningSetAdjacency(mat_part,mat_adj);CHKERRQ(ierr); 2283a929c220SStefano Zampini ierr = MatPartitioningSetFromOptions(mat_part);CHKERRQ(ierr); 2284a929c220SStefano Zampini printf("Setting Nparts %d\n",n_parts); 2285a929c220SStefano Zampini ierr = MatPartitioningSetNParts(mat_part,n_parts);CHKERRQ(ierr); 2286a929c220SStefano Zampini ierr = MatPartitioningView(mat_part,viewer_test);CHKERRQ(ierr); 2287a929c220SStefano Zampini ierr = MatPartitioningApply(mat_part,&coarse_new_decomposition);CHKERRQ(ierr); 2288a929c220SStefano Zampini ierr = ISView(coarse_new_decomposition,viewer_test);CHKERRQ(ierr); 2289a929c220SStefano Zampini ierr = ISPartitioningToNumbering(coarse_new_decomposition,&is_numbering);CHKERRQ(ierr); 2290a929c220SStefano Zampini ierr = ISView(is_numbering,viewer_test);CHKERRQ(ierr); 2291a929c220SStefano Zampini ierr = PetscViewerDestroy(&viewer_test);CHKERRQ(ierr); 2292a929c220SStefano Zampini ierr = ISDestroy(&coarse_new_decomposition);CHKERRQ(ierr); 2293a929c220SStefano Zampini ierr = ISDestroy(&is_numbering);CHKERRQ(ierr); 2294a929c220SStefano Zampini ierr = MatPartitioningDestroy(&mat_part);CHKERRQ(ierr); 2295a929c220SStefano Zampini ierr = PetscFree(old_ranks);CHKERRQ(ierr); 2296a929c220SStefano Zampini ierr = PetscFree(new_ranks);CHKERRQ(ierr); 2297a929c220SStefano Zampini ierr = MPI_Comm_free(&test_coarse_comm);CHKERRQ(ierr); 2298a929c220SStefano Zampini } 2299a929c220SStefano Zampini #endif 2300a929c220SStefano Zampini 23014fad6a16SStefano Zampini /* build CSR graph of subdomains' connectivity */ 23020c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&array_int);CHKERRQ(ierr); 23033828260eSStefano Zampini ierr = PetscMemzero(array_int,pcis->n*sizeof(PetscInt));CHKERRQ(ierr); 23040c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++){/* i=1 so I don't count myself -> faces nodes counts to 1 */ 23050c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++){ 23060c7d97c5SJed Brown array_int[ pcis->shared[i][j] ]+=1; 23070c7d97c5SJed Brown } 23080c7d97c5SJed Brown } 23090c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++){ 23100c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++){ 23117cf533a6SStefano Zampini if (array_int[ pcis->shared[i][j] ] > 0 ){ 23120c7d97c5SJed Brown my_faces++; 23130c7d97c5SJed Brown break; 23140c7d97c5SJed Brown } 23150c7d97c5SJed Brown } 23160c7d97c5SJed Brown } 23170c7d97c5SJed Brown 231853cdbc3dSStefano Zampini ierr = MPI_Reduce(&my_faces,&total_faces,1,MPIU_INT,MPI_SUM,master_proc,prec_comm);CHKERRQ(ierr); 23190c7d97c5SJed Brown ierr = PetscMalloc (my_faces*sizeof(PetscInt),&my_faces_connectivity);CHKERRQ(ierr); 23200c7d97c5SJed Brown my_faces=0; 23210c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++){ 23220c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++){ 23237cf533a6SStefano Zampini if (array_int[ pcis->shared[i][j] ] > 0 ){ 23240c7d97c5SJed Brown my_faces_connectivity[my_faces]=pcis->neigh[i]; 23250c7d97c5SJed Brown my_faces++; 23260c7d97c5SJed Brown break; 23270c7d97c5SJed Brown } 23280c7d97c5SJed Brown } 23290c7d97c5SJed Brown } 23300c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 23310c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(PetscMPIInt),&petsc_faces_adjncy);CHKERRQ(ierr); 23320c7d97c5SJed Brown ierr = PetscMalloc (size_prec_comm*sizeof(PetscMPIInt),&number_of_faces);CHKERRQ(ierr); 23330c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(MetisInt),&faces_adjncy);CHKERRQ(ierr); 23340c7d97c5SJed Brown ierr = PetscMalloc ((n_subdomains+1)*sizeof(MetisInt),&faces_xadj);CHKERRQ(ierr); 23350c7d97c5SJed Brown ierr = PetscMalloc ((size_prec_comm+1)*sizeof(PetscMPIInt),&faces_displacements);CHKERRQ(ierr); 23360c7d97c5SJed Brown } 233753cdbc3dSStefano Zampini ierr = MPI_Gather(&my_faces,1,MPIU_INT,&number_of_faces[0],1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 23380c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 23390c7d97c5SJed Brown faces_xadj[0]=0; 23400c7d97c5SJed Brown faces_displacements[0]=0; 23410c7d97c5SJed Brown j=0; 23420c7d97c5SJed Brown for (i=1;i<size_prec_comm+1;i++) { 23430c7d97c5SJed Brown faces_displacements[i]=faces_displacements[i-1]+number_of_faces[i-1]; 23440c7d97c5SJed Brown if (number_of_faces[i-1]) { 23450c7d97c5SJed Brown j++; 23460c7d97c5SJed Brown faces_xadj[j]=faces_xadj[j-1]+number_of_faces[i-1]; 23470c7d97c5SJed Brown } 23480c7d97c5SJed Brown } 23490c7d97c5SJed Brown } 235053cdbc3dSStefano 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); 23510c7d97c5SJed Brown ierr = PetscFree(my_faces_connectivity);CHKERRQ(ierr); 23520c7d97c5SJed Brown ierr = PetscFree(array_int);CHKERRQ(ierr); 23530c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 23543828260eSStefano Zampini for (i=0;i<total_faces;i++) faces_adjncy[i]=(MetisInt)(petsc_faces_adjncy[i]/ranks_stretching_ratio); /* cast to MetisInt */ 23550c7d97c5SJed Brown ierr = PetscFree(faces_displacements);CHKERRQ(ierr); 23560c7d97c5SJed Brown ierr = PetscFree(number_of_faces);CHKERRQ(ierr); 23570c7d97c5SJed Brown ierr = PetscFree(petsc_faces_adjncy);CHKERRQ(ierr); 23580c7d97c5SJed Brown } 23590c7d97c5SJed Brown 23600c7d97c5SJed Brown if ( rank_prec_comm == master_proc ) { 2361674ae819SStefano Zampini 23623828260eSStefano Zampini PetscInt heuristic_for_metis=3; 2363674ae819SStefano Zampini 23640c7d97c5SJed Brown ncon=1; 23650c7d97c5SJed Brown faces_nvtxs=n_subdomains; 23660c7d97c5SJed Brown /* partition graoh induced by face connectivity */ 23670c7d97c5SJed Brown ierr = PetscMalloc (n_subdomains*sizeof(MetisInt),&metis_coarse_subdivision);CHKERRQ(ierr); 23680c7d97c5SJed Brown ierr = METIS_SetDefaultOptions(options); 23690c7d97c5SJed Brown /* we need a contiguous partition of the coarse mesh */ 23700c7d97c5SJed Brown options[METIS_OPTION_CONTIG]=1; 23710c7d97c5SJed Brown options[METIS_OPTION_NITER]=30; 23724fad6a16SStefano Zampini if (pcbddc->coarsening_ratio > 1) { 23733828260eSStefano Zampini if (n_subdomains>n_parts*heuristic_for_metis) { 23743828260eSStefano Zampini options[METIS_OPTION_IPTYPE]=METIS_IPTYPE_EDGE; 23753828260eSStefano Zampini options[METIS_OPTION_OBJTYPE]=METIS_OBJTYPE_CUT; 23760c7d97c5SJed Brown ierr = METIS_PartGraphKway(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 2377674ae819SStefano 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); 23783828260eSStefano Zampini } else { 23793828260eSStefano Zampini ierr = METIS_PartGraphRecursive(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 2380674ae819SStefano 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); 23813828260eSStefano Zampini } 23824fad6a16SStefano Zampini } else { 23832fa5cd67SKarl Rupp for (i=0;i<n_subdomains;i++) metis_coarse_subdivision[i]=i; 23844fad6a16SStefano Zampini } 23850c7d97c5SJed Brown ierr = PetscFree(faces_xadj);CHKERRQ(ierr); 23860c7d97c5SJed Brown ierr = PetscFree(faces_adjncy);CHKERRQ(ierr); 23870bdf917eSStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&coarse_subdivision);CHKERRQ(ierr); 23882fa5cd67SKarl Rupp 23890c7d97c5SJed Brown /* copy/cast values avoiding possible type conflicts between PETSc, MPI and METIS */ 23902fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) coarse_subdivision[i]=MPI_PROC_NULL; 23912fa5cd67SKarl Rupp for (i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=(PetscInt)(metis_coarse_subdivision[i]); 23920c7d97c5SJed Brown ierr = PetscFree(metis_coarse_subdivision);CHKERRQ(ierr); 23930c7d97c5SJed Brown } 23940c7d97c5SJed Brown 23950c7d97c5SJed Brown /* Create new communicator for coarse problem splitting the old one */ 23960c7d97c5SJed Brown if ( !(rank_prec_comm%procs_jumps_coarse_comm) && rank_prec_comm < procs_jumps_coarse_comm*n_parts ){ 2397da1bb401SStefano Zampini coarse_color=0; /* for communicator splitting */ 2398da1bb401SStefano Zampini active_rank=rank_prec_comm; /* for insertion of matrix values */ 23990c7d97c5SJed Brown } 2400da1bb401SStefano Zampini /* procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 2401da1bb401SStefano Zampini key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator */ 240253cdbc3dSStefano Zampini ierr = MPI_Comm_split(prec_comm,coarse_color,rank_prec_comm,&coarse_comm);CHKERRQ(ierr); 24030c7d97c5SJed Brown 24040c7d97c5SJed Brown if ( coarse_color == 0 ) { 240553cdbc3dSStefano Zampini ierr = MPI_Comm_size(coarse_comm,&size_coarse_comm);CHKERRQ(ierr); 240653cdbc3dSStefano Zampini ierr = MPI_Comm_rank(coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 24070c7d97c5SJed Brown } else { 24080c7d97c5SJed Brown rank_coarse_comm = MPI_PROC_NULL; 24090c7d97c5SJed Brown } 24100c7d97c5SJed Brown 24117cf533a6SStefano Zampini /* master proc take care of arranging and distributing coarse information */ 24120c7d97c5SJed Brown if (rank_coarse_comm == master_proc) { 24130c7d97c5SJed Brown ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&displacements_recv);CHKERRQ(ierr); 24140bdf917eSStefano Zampini ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&total_count_recv);CHKERRQ(ierr); 24150bdf917eSStefano Zampini ierr = PetscMalloc (n_subdomains*sizeof(PetscMPIInt),&total_ranks_recv);CHKERRQ(ierr); 24160c7d97c5SJed Brown /* some initializations */ 24170c7d97c5SJed Brown displacements_recv[0]=0; 24180bdf917eSStefano Zampini ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 24190c7d97c5SJed Brown /* count from how many processes the j-th process of the coarse decomposition will receive data */ 24200bdf917eSStefano Zampini for (j=0;j<size_coarse_comm;j++) { 24210bdf917eSStefano Zampini for (i=0;i<size_prec_comm;i++) { 24222fa5cd67SKarl Rupp if (coarse_subdivision[i]==j) total_count_recv[j]++; 24230bdf917eSStefano Zampini } 24240bdf917eSStefano Zampini } 24250c7d97c5SJed Brown /* displacements needed for scatterv of total_ranks_recv */ 24262fa5cd67SKarl Rupp for (i=1; i<size_coarse_comm; i++) displacements_recv[i]=displacements_recv[i-1]+total_count_recv[i-1]; 24272fa5cd67SKarl Rupp 24280c7d97c5SJed Brown /* Now fill properly total_ranks_recv -> each coarse process will receive the ranks (in prec_comm communicator) of its friend (sending) processes */ 24290c7d97c5SJed Brown ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 24300c7d97c5SJed Brown for (j=0;j<size_coarse_comm;j++) { 24313828260eSStefano Zampini for (i=0;i<size_prec_comm;i++) { 24320c7d97c5SJed Brown if (coarse_subdivision[i]==j) { 24330c7d97c5SJed Brown total_ranks_recv[displacements_recv[j]+total_count_recv[j]]=i; 24343828260eSStefano Zampini total_count_recv[j]+=1; 24350c7d97c5SJed Brown } 24360c7d97c5SJed Brown } 24370c7d97c5SJed Brown } 2438da1bb401SStefano Zampini /*for (j=0;j<size_coarse_comm;j++) { 24393828260eSStefano Zampini printf("process %d in new rank will receive from %d processes (original ranks follows)\n",j,total_count_recv[j]); 24403828260eSStefano Zampini for (i=0;i<total_count_recv[j];i++) { 24413828260eSStefano Zampini printf("%d ",total_ranks_recv[displacements_recv[j]+i]); 24423828260eSStefano Zampini } 24433828260eSStefano Zampini printf("\n"); 2444da1bb401SStefano Zampini }*/ 24450c7d97c5SJed Brown 24460c7d97c5SJed Brown /* identify new decomposition in terms of ranks in the old communicator */ 24470bdf917eSStefano Zampini for (i=0;i<n_subdomains;i++) { 24480bdf917eSStefano Zampini coarse_subdivision[ranks_stretching_ratio*i]=coarse_subdivision[ranks_stretching_ratio*i]*procs_jumps_coarse_comm; 24490bdf917eSStefano Zampini } 2450da1bb401SStefano Zampini /*printf("coarse_subdivision in old end new ranks\n"); 2451674ae819SStefano Zampini for (i=0;i<size_prec_comm;i++) 24523828260eSStefano Zampini if (coarse_subdivision[i]!=MPI_PROC_NULL) { 24533828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]/procs_jumps_coarse_comm); 24543828260eSStefano Zampini } else { 24553828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]); 24563828260eSStefano Zampini } 2457da1bb401SStefano Zampini printf("\n");*/ 24580c7d97c5SJed Brown } 24590c7d97c5SJed Brown 24600c7d97c5SJed Brown /* Scatter new decomposition for send details */ 246153cdbc3dSStefano Zampini ierr = MPI_Scatter(&coarse_subdivision[0],1,MPIU_INT,&rank_coarse_proc_send_to,1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 24620c7d97c5SJed Brown /* Scatter receiving details to members of coarse decomposition */ 24630c7d97c5SJed Brown if ( coarse_color == 0) { 246453cdbc3dSStefano Zampini ierr = MPI_Scatter(&total_count_recv[0],1,MPIU_INT,&count_recv,1,MPIU_INT,master_proc,coarse_comm);CHKERRQ(ierr); 24650c7d97c5SJed Brown ierr = PetscMalloc (count_recv*sizeof(PetscMPIInt),&ranks_recv);CHKERRQ(ierr); 246653cdbc3dSStefano 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); 24670c7d97c5SJed Brown } 24680c7d97c5SJed Brown 2469da1bb401SStefano Zampini /*printf("I will send my matrix data to proc %d\n",rank_coarse_proc_send_to); 2470da1bb401SStefano Zampini if (coarse_color == 0) { 2471da1bb401SStefano Zampini printf("I will receive some matrix data from %d processes (ranks follows)\n",count_recv); 2472da1bb401SStefano Zampini for (i=0;i<count_recv;i++) 2473da1bb401SStefano Zampini printf("%d ",ranks_recv[i]); 2474da1bb401SStefano Zampini printf("\n"); 2475da1bb401SStefano Zampini }*/ 24760c7d97c5SJed Brown 24770c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 24780bdf917eSStefano Zampini ierr = PetscFree(coarse_subdivision);CHKERRQ(ierr); 2479da1bb401SStefano Zampini ierr = PetscFree(total_count_recv);CHKERRQ(ierr); 24800bdf917eSStefano Zampini ierr = PetscFree(total_ranks_recv);CHKERRQ(ierr); 24810c7d97c5SJed Brown ierr = PetscFree(displacements_recv);CHKERRQ(ierr); 24820c7d97c5SJed Brown } 24837cbb387bSStefano Zampini #endif 24840c7d97c5SJed Brown break; 24850c7d97c5SJed Brown } 24860c7d97c5SJed Brown 24870c7d97c5SJed Brown case(REPLICATED_BDDC): 24880c7d97c5SJed Brown 24890c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 24900c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 24910c7d97c5SJed Brown coarse_pc_type = PCLU; 249253cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 24930c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 24940c7d97c5SJed Brown active_rank = rank_prec_comm; 24950c7d97c5SJed Brown break; 24960c7d97c5SJed Brown 24970c7d97c5SJed Brown case(PARALLEL_BDDC): 24980c7d97c5SJed Brown 24990c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 2500674ae819SStefano Zampini coarse_mat_type = MATAIJ; 25010c7d97c5SJed Brown coarse_pc_type = PCREDUNDANT; 250253cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 25030c7d97c5SJed Brown coarse_comm = prec_comm; 25040c7d97c5SJed Brown active_rank = rank_prec_comm; 25050c7d97c5SJed Brown break; 25060c7d97c5SJed Brown 25070c7d97c5SJed Brown case(SEQUENTIAL_BDDC): 25080c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 2509674ae819SStefano Zampini coarse_mat_type = MATAIJ; 25100c7d97c5SJed Brown coarse_pc_type = PCLU; 251153cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 25120c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 25130c7d97c5SJed Brown active_rank = master_proc; 25140c7d97c5SJed Brown break; 25150c7d97c5SJed Brown } 25160c7d97c5SJed Brown 25170c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 25180c7d97c5SJed Brown 25190c7d97c5SJed Brown case(SCATTERS_BDDC): 25200c7d97c5SJed Brown { 25210c7d97c5SJed Brown if (pcbddc->coarse_problem_type==MULTILEVEL_BDDC) { 25220c7d97c5SJed Brown 25232e8d2280SStefano Zampini IS coarse_IS; 25242e8d2280SStefano Zampini 2525523858cfSStefano Zampini if(pcbddc->coarsening_ratio == 1) { 2526523858cfSStefano Zampini ins_local_primal_size = pcbddc->local_primal_size; 2527523858cfSStefano Zampini ins_local_primal_indices = pcbddc->local_primal_indices; 2528523858cfSStefano Zampini if (coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 2529523858cfSStefano Zampini /* nonzeros */ 2530523858cfSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&dnz);CHKERRQ(ierr); 2531523858cfSStefano Zampini ierr = PetscMemzero(dnz,ins_local_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 2532523858cfSStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 2533523858cfSStefano Zampini dnz[i] = ins_local_primal_size; 2534523858cfSStefano Zampini } 2535523858cfSStefano Zampini } else { 25360c7d97c5SJed Brown PetscMPIInt send_size; 2537ef028eecSStefano Zampini PetscMPIInt *send_buffer; 25380c7d97c5SJed Brown PetscInt *aux_ins_indices; 25390c7d97c5SJed Brown PetscInt ii,jj; 25400c7d97c5SJed Brown MPI_Request *requests; 2541ef028eecSStefano Zampini 2542523858cfSStefano Zampini ierr = PetscMalloc(count_recv*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 2543523858cfSStefano Zampini /* reusing pcbddc->local_primal_displacements and pcbddc->replicated_primal_size */ 2544523858cfSStefano Zampini ierr = PetscFree(pcbddc->local_primal_displacements);CHKERRQ(ierr); 2545523858cfSStefano Zampini ierr = PetscMalloc((count_recv+1)*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 2546523858cfSStefano Zampini pcbddc->replicated_primal_size = count_recv; 2547523858cfSStefano Zampini j = 0; 2548523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 2549523858cfSStefano Zampini pcbddc->local_primal_displacements[i] = j; 2550523858cfSStefano Zampini j += pcbddc->local_primal_sizes[ranks_recv[i]]; 2551523858cfSStefano Zampini } 2552523858cfSStefano Zampini pcbddc->local_primal_displacements[count_recv] = j; 2553523858cfSStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 25540c7d97c5SJed Brown /* allocate auxiliary space */ 2555523858cfSStefano Zampini ierr = PetscMalloc(count_recv*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 25560c7d97c5SJed Brown ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscInt),&aux_ins_indices);CHKERRQ(ierr); 25570c7d97c5SJed Brown ierr = PetscMemzero(aux_ins_indices,pcbddc->coarse_size*sizeof(PetscInt));CHKERRQ(ierr); 25580c7d97c5SJed Brown /* allocate stuffs for message massing */ 25590c7d97c5SJed Brown ierr = PetscMalloc((count_recv+1)*sizeof(MPI_Request),&requests);CHKERRQ(ierr); 2560523858cfSStefano Zampini for (i=0;i<count_recv+1;i++) { requests[i]=MPI_REQUEST_NULL; } 2561523858cfSStefano Zampini /* send indices to be inserted */ 2562523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 2563523858cfSStefano Zampini send_size = pcbddc->local_primal_sizes[ranks_recv[i]]; 2564523858cfSStefano 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); 2565523858cfSStefano Zampini } 2566523858cfSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 2567523858cfSStefano Zampini send_size = pcbddc->local_primal_size; 2568ef028eecSStefano Zampini ierr = PetscMalloc(send_size*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 2569ef028eecSStefano Zampini for (i=0;i<send_size;i++) { 2570ef028eecSStefano Zampini send_buffer[i]=(PetscMPIInt)pcbddc->local_primal_indices[i]; 2571ef028eecSStefano Zampini } 2572ef028eecSStefano Zampini ierr = MPI_Isend(send_buffer,send_size,MPIU_INT,rank_coarse_proc_send_to,999,prec_comm,&requests[count_recv]);CHKERRQ(ierr); 2573523858cfSStefano Zampini } 2574523858cfSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2575ef028eecSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 2576ef028eecSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 2577ef028eecSStefano Zampini } 25780c7d97c5SJed Brown j = 0; 25790c7d97c5SJed Brown for (i=0;i<count_recv;i++) { 25802e8d2280SStefano Zampini ii = pcbddc->local_primal_displacements[i+1]-pcbddc->local_primal_displacements[i]; 25812e8d2280SStefano Zampini localsizes2[i] = ii*ii; 25820c7d97c5SJed Brown localdispl2[i] = j; 25830c7d97c5SJed Brown j += localsizes2[i]; 2584523858cfSStefano Zampini jj = pcbddc->local_primal_displacements[i]; 25854fad6a16SStefano Zampini /* it counts the coarse subdomains sharing the coarse node */ 25862e8d2280SStefano Zampini for (k=0;k<ii;k++) { 25874fad6a16SStefano Zampini aux_ins_indices[pcbddc->replicated_local_primal_indices[jj+k]] += 1; 25880c7d97c5SJed Brown } 25894fad6a16SStefano Zampini } 2590523858cfSStefano Zampini /* temp_coarse_mat_vals used to store matrix values to be received */ 25910c7d97c5SJed Brown ierr = PetscMalloc(j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 25920c7d97c5SJed Brown /* evaluate how many values I will insert in coarse mat */ 25930c7d97c5SJed Brown ins_local_primal_size = 0; 2594ea7e1babSStefano Zampini for (i=0;i<pcbddc->coarse_size;i++) { 2595ea7e1babSStefano Zampini if (aux_ins_indices[i]) { 25960c7d97c5SJed Brown ins_local_primal_size++; 2597ea7e1babSStefano Zampini } 2598ea7e1babSStefano Zampini } 25990c7d97c5SJed Brown /* evaluate indices I will insert in coarse mat */ 26000c7d97c5SJed Brown ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 26010c7d97c5SJed Brown j = 0; 2602ea7e1babSStefano Zampini for(i=0;i<pcbddc->coarse_size;i++) { 2603ea7e1babSStefano Zampini if(aux_ins_indices[i]) { 26042e8d2280SStefano Zampini ins_local_primal_indices[j] = i; 26052e8d2280SStefano Zampini j++; 2606ea7e1babSStefano Zampini } 2607ea7e1babSStefano Zampini } 2608523858cfSStefano Zampini /* processes partecipating in coarse problem receive matrix data from their friends */ 2609523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 2610523858cfSStefano Zampini ierr = MPI_Irecv(&temp_coarse_mat_vals[localdispl2[i]],localsizes2[i],MPIU_SCALAR,ranks_recv[i],666,prec_comm,&requests[i]);CHKERRQ(ierr); 2611523858cfSStefano Zampini } 2612523858cfSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 2613523858cfSStefano Zampini send_size = pcbddc->local_primal_size*pcbddc->local_primal_size; 2614523858cfSStefano 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); 2615523858cfSStefano Zampini } 2616523858cfSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2617523858cfSStefano Zampini /* nonzeros */ 2618523858cfSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&dnz);CHKERRQ(ierr); 2619523858cfSStefano Zampini ierr = PetscMemzero(dnz,ins_local_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 26200c7d97c5SJed Brown /* use aux_ins_indices to realize a global to local mapping */ 26210c7d97c5SJed Brown j=0; 26220c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++){ 26230c7d97c5SJed Brown if(aux_ins_indices[i]==0){ 26240c7d97c5SJed Brown aux_ins_indices[i]=-1; 26250c7d97c5SJed Brown } else { 26260c7d97c5SJed Brown aux_ins_indices[i]=j; 26270c7d97c5SJed Brown j++; 26280c7d97c5SJed Brown } 26290c7d97c5SJed Brown } 26304fad6a16SStefano Zampini for (i=0;i<count_recv;i++) { 2631523858cfSStefano Zampini j = pcbddc->local_primal_sizes[ranks_recv[i]]; 2632523858cfSStefano Zampini for (k=0;k<j;k++) { 2633523858cfSStefano Zampini dnz[aux_ins_indices[pcbddc->replicated_local_primal_indices[pcbddc->local_primal_displacements[i]+k]]] += j; 26340c7d97c5SJed Brown } 26350c7d97c5SJed Brown } 2636523858cfSStefano Zampini /* check */ 2637523858cfSStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 2638523858cfSStefano Zampini if (dnz[i] > ins_local_primal_size) { 2639523858cfSStefano Zampini dnz[i] = ins_local_primal_size; 26400c7d97c5SJed Brown } 26410c7d97c5SJed Brown } 26420c7d97c5SJed Brown ierr = PetscFree(requests);CHKERRQ(ierr); 26430c7d97c5SJed Brown ierr = PetscFree(aux_ins_indices);CHKERRQ(ierr); 26440c7d97c5SJed Brown if (coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 26454fad6a16SStefano Zampini } 26460c7d97c5SJed Brown /* create local to global mapping needed by coarse MATIS */ 2647142dfd88SStefano Zampini if (coarse_comm != MPI_COMM_NULL ) {ierr = MPI_Comm_free(&coarse_comm);CHKERRQ(ierr);} 26480c7d97c5SJed Brown coarse_comm = prec_comm; 26490c7d97c5SJed Brown active_rank = rank_prec_comm; 26500c7d97c5SJed Brown ierr = ISCreateGeneral(coarse_comm,ins_local_primal_size,ins_local_primal_indices,PETSC_COPY_VALUES,&coarse_IS);CHKERRQ(ierr); 26510c7d97c5SJed Brown ierr = ISLocalToGlobalMappingCreateIS(coarse_IS,&coarse_ISLG);CHKERRQ(ierr); 26520c7d97c5SJed Brown ierr = ISDestroy(&coarse_IS);CHKERRQ(ierr); 26532e8d2280SStefano Zampini } else if (pcbddc->coarse_problem_type==PARALLEL_BDDC) { 26540c7d97c5SJed Brown /* arrays for values insertion */ 26550c7d97c5SJed Brown ins_local_primal_size = pcbddc->local_primal_size; 26562e8d2280SStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 26570c7d97c5SJed Brown ierr = PetscMalloc(ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 26580c7d97c5SJed Brown for (j=0;j<ins_local_primal_size;j++){ 26590c7d97c5SJed Brown ins_local_primal_indices[j]=pcbddc->local_primal_indices[j]; 26604fad6a16SStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 26614fad6a16SStefano Zampini ins_coarse_mat_vals[j*ins_local_primal_size+i]=coarse_submat_vals[j*ins_local_primal_size+i]; 26624fad6a16SStefano Zampini } 26630c7d97c5SJed Brown } 26640c7d97c5SJed Brown } 26650c7d97c5SJed Brown break; 2666674ae819SStefano Zampini 26670c7d97c5SJed Brown } 26680c7d97c5SJed Brown 26690c7d97c5SJed Brown case(GATHERS_BDDC): 26700c7d97c5SJed Brown { 2671674ae819SStefano Zampini 26720c7d97c5SJed Brown PetscMPIInt mysize,mysize2; 2673ef028eecSStefano Zampini PetscMPIInt *send_buffer; 26740c7d97c5SJed Brown 26750c7d97c5SJed Brown if (rank_prec_comm==active_rank) { 26760c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 26770bdf917eSStefano Zampini ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscScalar),&pcbddc->replicated_local_primal_values);CHKERRQ(ierr); 26780c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 26790c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 26800c7d97c5SJed Brown /* arrays for values insertion */ 26812fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) localsizes2[i]=pcbddc->local_primal_sizes[i]*pcbddc->local_primal_sizes[i]; 26820c7d97c5SJed Brown localdispl2[0]=0; 26832fa5cd67SKarl Rupp for (i=1;i<size_prec_comm;i++) localdispl2[i]=localsizes2[i-1]+localdispl2[i-1]; 26840c7d97c5SJed Brown j=0; 26852fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) j+=localsizes2[i]; 26860c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 26870c7d97c5SJed Brown } 26880c7d97c5SJed Brown 26890c7d97c5SJed Brown mysize=pcbddc->local_primal_size; 26900c7d97c5SJed Brown mysize2=pcbddc->local_primal_size*pcbddc->local_primal_size; 2691ef028eecSStefano Zampini ierr = PetscMalloc(mysize*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 26922fa5cd67SKarl Rupp for (i=0; i<mysize; i++) send_buffer[i]=(PetscMPIInt)pcbddc->local_primal_indices[i]; 26932fa5cd67SKarl Rupp 26940c7d97c5SJed Brown if (pcbddc->coarse_problem_type == SEQUENTIAL_BDDC){ 2695ef028eecSStefano 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); 269653cdbc3dSStefano 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); 26970c7d97c5SJed Brown } else { 2698ef028eecSStefano 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); 269953cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,prec_comm);CHKERRQ(ierr); 27000c7d97c5SJed Brown } 2701ef028eecSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 27020c7d97c5SJed Brown break; 2703da1bb401SStefano Zampini }/* switch on coarse problem and communications associated with finished */ 27040c7d97c5SJed Brown } 27050c7d97c5SJed Brown 27060c7d97c5SJed Brown /* Now create and fill up coarse matrix */ 27070c7d97c5SJed Brown if ( rank_prec_comm == active_rank ) { 2708142dfd88SStefano Zampini 2709142dfd88SStefano Zampini Mat matis_coarse_local_mat; 2710142dfd88SStefano Zampini 27110c7d97c5SJed Brown if (pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 27120c7d97c5SJed Brown ierr = MatCreate(coarse_comm,&pcbddc->coarse_mat);CHKERRQ(ierr); 27130c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_mat,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size);CHKERRQ(ierr); 27140c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_mat,coarse_mat_type);CHKERRQ(ierr); 2715674ae819SStefano Zampini ierr = MatSetOptionsPrefix(pcbddc->coarse_mat,"coarse_");CHKERRQ(ierr); 2716674ae819SStefano Zampini ierr = MatSetFromOptions(pcbddc->coarse_mat);CHKERRQ(ierr); 27173b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 2718da1bb401SStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 27193b03a366Sstefano_zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 27200c7d97c5SJed Brown } else { 27214fad6a16SStefano Zampini ierr = MatCreateIS(coarse_comm,1,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_ISLG,&pcbddc->coarse_mat);CHKERRQ(ierr); 27223b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 27230c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 2724674ae819SStefano Zampini ierr = MatSetOptionsPrefix(pcbddc->coarse_mat,"coarse_");CHKERRQ(ierr); 2725674ae819SStefano Zampini ierr = MatSetFromOptions(pcbddc->coarse_mat);CHKERRQ(ierr); 27263b03a366Sstefano_zampini ierr = MatSetUp(matis_coarse_local_mat);CHKERRQ(ierr); 2727da1bb401SStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 2728a0ba757dSStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 27290c7d97c5SJed Brown } 2730142dfd88SStefano Zampini /* preallocation */ 2731142dfd88SStefano Zampini if (pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 2732ef028eecSStefano Zampini 2733674ae819SStefano Zampini PetscInt lrows,lcols,bs; 2734ef028eecSStefano Zampini 2735142dfd88SStefano Zampini ierr = MatGetLocalSize(pcbddc->coarse_mat,&lrows,&lcols);CHKERRQ(ierr); 2736142dfd88SStefano Zampini ierr = MatPreallocateInitialize(coarse_comm,lrows,lcols,dnz,onz);CHKERRQ(ierr); 2737674ae819SStefano Zampini ierr = MatGetBlockSize(pcbddc->coarse_mat,&bs);CHKERRQ(ierr); 2738ef028eecSStefano Zampini 2739142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == PARALLEL_BDDC) { 2740ef028eecSStefano Zampini 2741ef028eecSStefano Zampini Vec vec_dnz,vec_onz; 2742ef028eecSStefano Zampini PetscScalar *my_dnz,*my_onz,*array; 2743ef028eecSStefano Zampini PetscInt *mat_ranges,*row_ownership; 2744ef028eecSStefano Zampini PetscInt coarse_index_row,coarse_index_col,owner; 2745ef028eecSStefano Zampini 2746ef028eecSStefano Zampini ierr = VecCreate(prec_comm,&vec_dnz);CHKERRQ(ierr); 2747674ae819SStefano Zampini ierr = VecSetBlockSize(vec_dnz,bs);CHKERRQ(ierr); 2748ef028eecSStefano Zampini ierr = VecSetSizes(vec_dnz,PETSC_DECIDE,pcbddc->coarse_size);CHKERRQ(ierr); 2749ef028eecSStefano Zampini ierr = VecSetType(vec_dnz,VECMPI);CHKERRQ(ierr); 2750ef028eecSStefano Zampini ierr = VecDuplicate(vec_dnz,&vec_onz);CHKERRQ(ierr); 2751ef028eecSStefano Zampini 2752ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscScalar),&my_dnz);CHKERRQ(ierr); 2753ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscScalar),&my_onz);CHKERRQ(ierr); 2754ef028eecSStefano Zampini ierr = PetscMemzero(my_dnz,pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 2755ef028eecSStefano Zampini ierr = PetscMemzero(my_onz,pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 2756ef028eecSStefano Zampini 2757ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscInt),&row_ownership);CHKERRQ(ierr); 2758ef028eecSStefano Zampini ierr = MatGetOwnershipRanges(pcbddc->coarse_mat,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 2759142dfd88SStefano Zampini for (i=0;i<size_prec_comm;i++) { 2760ef028eecSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 2761ef028eecSStefano Zampini row_ownership[j]=i; 2762142dfd88SStefano Zampini } 2763142dfd88SStefano Zampini } 2764ef028eecSStefano Zampini 2765ef028eecSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 2766ef028eecSStefano Zampini coarse_index_row = pcbddc->local_primal_indices[i]; 2767ef028eecSStefano Zampini owner = row_ownership[coarse_index_row]; 2768ef028eecSStefano Zampini for (j=i;j<pcbddc->local_primal_size;j++) { 2769ef028eecSStefano Zampini owner = row_ownership[coarse_index_row]; 2770ef028eecSStefano Zampini coarse_index_col = pcbddc->local_primal_indices[j]; 2771ef028eecSStefano Zampini if (coarse_index_col > mat_ranges[owner]-1 && coarse_index_col < mat_ranges[owner+1] ) { 2772ef028eecSStefano Zampini my_dnz[i] += 1.0; 2773142dfd88SStefano Zampini } else { 2774ef028eecSStefano Zampini my_onz[i] += 1.0; 2775142dfd88SStefano Zampini } 2776ef028eecSStefano Zampini if (i != j) { 2777ef028eecSStefano Zampini owner = row_ownership[coarse_index_col]; 2778ef028eecSStefano Zampini if (coarse_index_row > mat_ranges[owner]-1 && coarse_index_row < mat_ranges[owner+1] ) { 2779ef028eecSStefano Zampini my_dnz[j] += 1.0; 2780142dfd88SStefano Zampini } else { 2781ef028eecSStefano Zampini my_onz[j] += 1.0; 2782142dfd88SStefano Zampini } 2783142dfd88SStefano Zampini } 2784142dfd88SStefano Zampini } 2785142dfd88SStefano Zampini } 2786ef028eecSStefano Zampini ierr = VecSet(vec_dnz,0.0);CHKERRQ(ierr); 2787ef028eecSStefano Zampini ierr = VecSet(vec_onz,0.0);CHKERRQ(ierr); 2788a929c220SStefano Zampini if (pcbddc->local_primal_size) { 2789ef028eecSStefano Zampini ierr = VecSetValues(vec_dnz,pcbddc->local_primal_size,pcbddc->local_primal_indices,my_dnz,ADD_VALUES);CHKERRQ(ierr); 2790ef028eecSStefano Zampini ierr = VecSetValues(vec_onz,pcbddc->local_primal_size,pcbddc->local_primal_indices,my_onz,ADD_VALUES);CHKERRQ(ierr); 2791a929c220SStefano Zampini } 2792ef028eecSStefano Zampini ierr = VecAssemblyBegin(vec_dnz);CHKERRQ(ierr); 2793ef028eecSStefano Zampini ierr = VecAssemblyBegin(vec_onz);CHKERRQ(ierr); 2794ef028eecSStefano Zampini ierr = VecAssemblyEnd(vec_dnz);CHKERRQ(ierr); 2795ef028eecSStefano Zampini ierr = VecAssemblyEnd(vec_onz);CHKERRQ(ierr); 2796ef028eecSStefano Zampini j = mat_ranges[rank_prec_comm+1]-mat_ranges[rank_prec_comm]; 2797ef028eecSStefano Zampini ierr = VecGetArray(vec_dnz,&array);CHKERRQ(ierr); 27985b08dc53SStefano Zampini for (i=0; i<j; i++) dnz[i] = (PetscInt)PetscRealPart(array[i]); 27992fa5cd67SKarl Rupp 2800ef028eecSStefano Zampini ierr = VecRestoreArray(vec_dnz,&array);CHKERRQ(ierr); 2801ef028eecSStefano Zampini ierr = VecGetArray(vec_onz,&array);CHKERRQ(ierr); 28025b08dc53SStefano Zampini for (i=0;i<j;i++) onz[i] = (PetscInt)PetscRealPart(array[i]); 28032fa5cd67SKarl Rupp 2804ef028eecSStefano Zampini ierr = VecRestoreArray(vec_onz,&array);CHKERRQ(ierr); 2805ef028eecSStefano Zampini ierr = PetscFree(my_dnz);CHKERRQ(ierr); 2806ef028eecSStefano Zampini ierr = PetscFree(my_onz);CHKERRQ(ierr); 2807ef028eecSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 2808ef028eecSStefano Zampini ierr = VecDestroy(&vec_dnz);CHKERRQ(ierr); 2809ef028eecSStefano Zampini ierr = VecDestroy(&vec_onz);CHKERRQ(ierr); 2810142dfd88SStefano Zampini } else { 2811142dfd88SStefano Zampini for (k=0;k<size_prec_comm;k++){ 2812142dfd88SStefano Zampini offset=pcbddc->local_primal_displacements[k]; 2813142dfd88SStefano Zampini offset2=localdispl2[k]; 2814142dfd88SStefano Zampini ins_local_primal_size = pcbddc->local_primal_sizes[k]; 2815ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2816ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2817ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2818ef028eecSStefano Zampini } 2819142dfd88SStefano Zampini for (j=0;j<ins_local_primal_size;j++) { 2820142dfd88SStefano Zampini ierr = MatPreallocateSet(ins_local_primal_indices[j],ins_local_primal_size,ins_local_primal_indices,dnz,onz);CHKERRQ(ierr); 2821142dfd88SStefano Zampini } 2822ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2823142dfd88SStefano Zampini } 2824142dfd88SStefano Zampini } 28252fa5cd67SKarl Rupp 2826142dfd88SStefano Zampini /* check */ 2827142dfd88SStefano Zampini for (i=0;i<lrows;i++) { 28282fa5cd67SKarl Rupp if (dnz[i]>lcols) dnz[i]=lcols; 28292fa5cd67SKarl Rupp if (onz[i]>pcbddc->coarse_size-lcols) onz[i]=pcbddc->coarse_size-lcols; 2830142dfd88SStefano Zampini } 2831d9a4edebSJed Brown ierr = MatSeqAIJSetPreallocation(pcbddc->coarse_mat,0,dnz);CHKERRQ(ierr); 2832d9a4edebSJed Brown ierr = MatMPIAIJSetPreallocation(pcbddc->coarse_mat,0,dnz,0,onz);CHKERRQ(ierr); 2833142dfd88SStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 2834142dfd88SStefano Zampini } else { 2835523858cfSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis_coarse_local_mat,0,dnz);CHKERRQ(ierr); 2836523858cfSStefano Zampini ierr = PetscFree(dnz);CHKERRQ(ierr); 2837142dfd88SStefano Zampini } 2838142dfd88SStefano Zampini /* insert values */ 2839523858cfSStefano Zampini if (pcbddc->coarse_problem_type == PARALLEL_BDDC) { 28400c7d97c5SJed 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); 2841523858cfSStefano Zampini } else if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2842523858cfSStefano Zampini if (pcbddc->coarsening_ratio == 1) { 2843523858cfSStefano Zampini ins_coarse_mat_vals = coarse_submat_vals; 2844523858cfSStefano 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); 2845523858cfSStefano Zampini } else { 2846523858cfSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2847523858cfSStefano Zampini for (k=0;k<pcbddc->replicated_primal_size;k++) { 2848523858cfSStefano Zampini offset = pcbddc->local_primal_displacements[k]; 2849523858cfSStefano Zampini offset2 = localdispl2[k]; 2850523858cfSStefano Zampini ins_local_primal_size = pcbddc->local_primal_displacements[k+1]-pcbddc->local_primal_displacements[k]; 2851ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2852ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2853ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2854ef028eecSStefano Zampini } 2855523858cfSStefano Zampini ins_coarse_mat_vals = &temp_coarse_mat_vals[offset2]; 2856523858cfSStefano 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); 2857ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2858523858cfSStefano Zampini } 2859523858cfSStefano Zampini } 2860523858cfSStefano Zampini ins_local_primal_indices = 0; 2861523858cfSStefano Zampini ins_coarse_mat_vals = 0; 2862ea7e1babSStefano Zampini } else { 2863ea7e1babSStefano Zampini for (k=0;k<size_prec_comm;k++){ 2864ea7e1babSStefano Zampini offset=pcbddc->local_primal_displacements[k]; 2865ea7e1babSStefano Zampini offset2=localdispl2[k]; 2866ea7e1babSStefano Zampini ins_local_primal_size = pcbddc->local_primal_sizes[k]; 2867ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2868ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2869ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2870ef028eecSStefano Zampini } 2871ea7e1babSStefano Zampini ins_coarse_mat_vals = &temp_coarse_mat_vals[offset2]; 2872ea7e1babSStefano 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); 2873ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2874ea7e1babSStefano Zampini } 2875ea7e1babSStefano Zampini ins_local_primal_indices = 0; 2876ea7e1babSStefano Zampini ins_coarse_mat_vals = 0; 2877ea7e1babSStefano Zampini } 28780c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28790c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2880142dfd88SStefano Zampini /* symmetry of coarse matrix */ 2881142dfd88SStefano Zampini if (issym) { 2882142dfd88SStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 2883142dfd88SStefano Zampini } 28840c7d97c5SJed Brown ierr = MatGetVecs(pcbddc->coarse_mat,&pcbddc->coarse_vec,&pcbddc->coarse_rhs);CHKERRQ(ierr); 28850bdf917eSStefano Zampini } 28860bdf917eSStefano Zampini 28870bdf917eSStefano Zampini /* create loc to glob scatters if needed */ 28880bdf917eSStefano Zampini if (pcbddc->coarse_communications_type == SCATTERS_BDDC) { 28890bdf917eSStefano Zampini IS local_IS,global_IS; 28900bdf917eSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&local_IS);CHKERRQ(ierr); 28910bdf917eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_indices,PETSC_COPY_VALUES,&global_IS);CHKERRQ(ierr); 28920bdf917eSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,local_IS,pcbddc->coarse_vec,global_IS,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 28930bdf917eSStefano Zampini ierr = ISDestroy(&local_IS);CHKERRQ(ierr); 28940bdf917eSStefano Zampini ierr = ISDestroy(&global_IS);CHKERRQ(ierr); 28950bdf917eSStefano Zampini } 28960bdf917eSStefano Zampini 2897a929c220SStefano Zampini /* free memory no longer needed */ 2898a929c220SStefano Zampini if (coarse_ISLG) { ierr = ISLocalToGlobalMappingDestroy(&coarse_ISLG);CHKERRQ(ierr); } 2899a929c220SStefano Zampini if (ins_local_primal_indices) { ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); } 2900a929c220SStefano Zampini if (ins_coarse_mat_vals) { ierr = PetscFree(ins_coarse_mat_vals);CHKERRQ(ierr); } 2901a929c220SStefano Zampini if (localsizes2) { ierr = PetscFree(localsizes2);CHKERRQ(ierr); } 2902a929c220SStefano Zampini if (localdispl2) { ierr = PetscFree(localdispl2);CHKERRQ(ierr); } 2903a929c220SStefano Zampini if (temp_coarse_mat_vals) { ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr); } 2904a929c220SStefano Zampini 2905674ae819SStefano Zampini /* Compute coarse null space */ 2906674ae819SStefano Zampini CoarseNullSpace = 0; 29070bdf917eSStefano Zampini if (pcbddc->NullSpace) { 2908674ae819SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,&CoarseNullSpace);CHKERRQ(ierr); 29090bdf917eSStefano Zampini } 29100bdf917eSStefano Zampini 29110bdf917eSStefano Zampini /* KSP for coarse problem */ 29120bdf917eSStefano Zampini if (rank_prec_comm == active_rank) { 29132e8d2280SStefano Zampini PetscBool isbddc=PETSC_FALSE; 29140bdf917eSStefano Zampini 291553cdbc3dSStefano Zampini ierr = KSPCreate(coarse_comm,&pcbddc->coarse_ksp);CHKERRQ(ierr); 291653cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 291753cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 29183b03a366Sstefano_zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,max_it_coarse_ksp);CHKERRQ(ierr); 291953cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 292053cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 292153cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 29220c7d97c5SJed Brown /* Allow user's customization */ 2923da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,"coarse_");CHKERRQ(ierr); 29240c7d97c5SJed Brown /* Set Up PC for coarse problem BDDC */ 292553cdbc3dSStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 29264fad6a16SStefano Zampini i = pcbddc->current_level+1; 29274fad6a16SStefano Zampini ierr = PCBDDCSetLevel(pc_temp,i);CHKERRQ(ierr); 29284fad6a16SStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 29294fad6a16SStefano Zampini ierr = PCBDDCSetMaxLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 293053cdbc3dSStefano Zampini ierr = PCBDDCSetCoarseProblemType(pc_temp,MULTILEVEL_BDDC);CHKERRQ(ierr); 2931674ae819SStefano Zampini if (CoarseNullSpace) { 2932674ae819SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 2933674ae819SStefano Zampini } 29344fad6a16SStefano Zampini if (dbg_flag) { 29354fad6a16SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------Level %d: Setting up level %d---------------\n",pcbddc->current_level,i);CHKERRQ(ierr); 29364fad6a16SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 293753cdbc3dSStefano Zampini } 2938674ae819SStefano Zampini } else { 2939674ae819SStefano Zampini if (CoarseNullSpace) { 2940674ae819SStefano Zampini ierr = KSPSetNullSpace(pcbddc->coarse_ksp,CoarseNullSpace);CHKERRQ(ierr); 2941674ae819SStefano Zampini } 29424fad6a16SStefano Zampini } 29434fad6a16SStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 294453cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 2945142dfd88SStefano Zampini 29460298fd71SBarry Smith ierr = KSPGetTolerances(pcbddc->coarse_ksp,NULL,NULL,NULL,&j);CHKERRQ(ierr); 29472e8d2280SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 29482e8d2280SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 29492e8d2280SStefano Zampini if (j == 1) { 29502e8d2280SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 29512e8d2280SStefano Zampini if (isbddc) { 29522e8d2280SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc_temp,PETSC_FALSE);CHKERRQ(ierr); 29535619798eSStefano Zampini } 29545619798eSStefano Zampini } 29550c7d97c5SJed Brown } 2956a929c220SStefano Zampini /* Check coarse problem if requested */ 2957142dfd88SStefano Zampini if ( dbg_flag && rank_prec_comm == active_rank ) { 2958142dfd88SStefano Zampini KSP check_ksp; 2959142dfd88SStefano Zampini PC check_pc; 2960142dfd88SStefano Zampini Vec check_vec; 2961142dfd88SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min,lambda_max; 296219fd82e9SBarry Smith KSPType check_ksp_type; 29630c7d97c5SJed Brown 2964142dfd88SStefano Zampini /* Create ksp object suitable for extreme eigenvalues' estimation */ 2965142dfd88SStefano Zampini ierr = KSPCreate(coarse_comm,&check_ksp);CHKERRQ(ierr); 2966142dfd88SStefano Zampini ierr = KSPSetOperators(check_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 29670bdf917eSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 2968142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 29692fa5cd67SKarl Rupp if (issym) check_ksp_type = KSPCG; 29702fa5cd67SKarl Rupp else check_ksp_type = KSPGMRES; 2971142dfd88SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,PETSC_TRUE);CHKERRQ(ierr); 2972142dfd88SStefano Zampini } else { 2973142dfd88SStefano Zampini check_ksp_type = KSPPREONLY; 2974142dfd88SStefano Zampini } 2975142dfd88SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 2976142dfd88SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 2977142dfd88SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 2978142dfd88SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 2979142dfd88SStefano Zampini /* create random vec */ 2980142dfd88SStefano Zampini ierr = VecDuplicate(pcbddc->coarse_vec,&check_vec);CHKERRQ(ierr); 29810298fd71SBarry Smith ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 2982674ae819SStefano Zampini if (CoarseNullSpace) { 29831cb54aadSJed Brown ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 2984674ae819SStefano Zampini } 2985142dfd88SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,check_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 2986142dfd88SStefano Zampini /* solve coarse problem */ 2987142dfd88SStefano Zampini ierr = KSPSolve(check_ksp,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 2988674ae819SStefano Zampini if (CoarseNullSpace) { 29891cb54aadSJed Brown ierr = MatNullSpaceRemove(CoarseNullSpace,pcbddc->coarse_vec);CHKERRQ(ierr); 2990674ae819SStefano Zampini } 2991142dfd88SStefano Zampini /* check coarse problem residual error */ 2992142dfd88SStefano Zampini ierr = VecAXPY(check_vec,-1.0,pcbddc->coarse_vec);CHKERRQ(ierr); 2993142dfd88SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 2994142dfd88SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,check_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 2995142dfd88SStefano Zampini ierr = VecNorm(pcbddc->coarse_rhs,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 2996142dfd88SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 2997142dfd88SStefano Zampini /* get eigenvalue estimation if inexact */ 2998142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2999142dfd88SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); 3000142dfd88SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&k);CHKERRQ(ierr); 3001142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues estimated with %d iterations of %s.\n",k,check_ksp_type);CHKERRQ(ierr); 3002e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues: % 1.14e %1.14e\n",lambda_min,lambda_max);CHKERRQ(ierr); 30033b03a366Sstefano_zampini } 3004142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem exact infty_error : %1.14e\n",infty_error);CHKERRQ(ierr); 3005142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem residual infty_error: %1.14e\n",abs_infty_error);CHKERRQ(ierr); 3006142dfd88SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 300753cdbc3dSStefano Zampini } 3008674ae819SStefano Zampini if (dbg_flag) { 3009da1bb401SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 3010da1bb401SStefano Zampini } 3011674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 3012a0ba757dSStefano Zampini 30130c7d97c5SJed Brown PetscFunctionReturn(0); 30140c7d97c5SJed Brown } 30150c7d97c5SJed Brown 3016