153cdbc3dSStefano Zampini /* TODOLIST 2da1bb401SStefano Zampini DofSplitting and DM attached to pc? 3da1bb401SStefano Zampini Change SetNeumannBoundaries to SetNeumannBoundariesLocal and provide new SetNeumannBoundaries (same Dirichlet) 4a0ba757dSStefano Zampini change how to deal with the coarse problem (PCBDDCSetCoarseEnvironment): 5a0ba757dSStefano Zampini - simplify coarse problem structure -> PCBDDC or PCREDUDANT, nothing else -> same comm for all levels? 6a0ba757dSStefano Zampini - remove coarse enums and allow use of PCBDDCGetCoarseKSP 7674ae819SStefano Zampini - remove metis dependency -> use MatPartitioning for multilevel -> Assemble serial adjacency in PCBDDCAnalyzeInterface? 8a0ba757dSStefano Zampini code refactoring: 9a0ba757dSStefano Zampini - pick up better names for static functions 10a0ba757dSStefano Zampini change options structure: 11a0ba757dSStefano Zampini - insert BDDC into MG framework? 12a0ba757dSStefano Zampini provide other ops? Ask to developers 13a0ba757dSStefano Zampini remove all unused printf 14a0ba757dSStefano Zampini man pages 1553cdbc3dSStefano Zampini */ 160c7d97c5SJed Brown 1753cdbc3dSStefano Zampini /* ---------------------------------------------------------------------------------------------------------------------------------------------- 180c7d97c5SJed Brown Implementation of BDDC preconditioner based on: 190c7d97c5SJed Brown C. Dohrmann "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 2053cdbc3dSStefano Zampini ---------------------------------------------------------------------------------------------------------------------------------------------- */ 2153cdbc3dSStefano Zampini 22674ae819SStefano Zampini #include "bddc.h" /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 23674ae819SStefano Zampini #include "bddcprivate.h" 243b03a366Sstefano_zampini #include <petscblaslapack.h> 25674ae819SStefano Zampini 26674ae819SStefano Zampini /* prototypes for static functions contained in bddc.c */ 27674ae819SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet(PC,PetscBool); 28674ae819SStefano Zampini static PetscErrorCode PCBDDCSetLevel(PC,PetscInt); 29674ae819SStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC); 30674ae819SStefano Zampini static PetscErrorCode PCBDDCSetUpCoarseEnvironment(PC,PetscScalar*); 31674ae819SStefano Zampini 320c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 330c7d97c5SJed Brown #undef __FUNCT__ 340c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC" 350c7d97c5SJed Brown PetscErrorCode PCSetFromOptions_BDDC(PC pc) 360c7d97c5SJed Brown { 370c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 380c7d97c5SJed Brown PetscErrorCode ierr; 390c7d97c5SJed Brown 400c7d97c5SJed Brown PetscFunctionBegin; 410c7d97c5SJed Brown ierr = PetscOptionsHead("BDDC options");CHKERRQ(ierr); 420c7d97c5SJed Brown /* Verbose debugging of main data structures */ 439d9e44b6SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_check_level" ,"Verbose (debugging) output for PCBDDC" ,"none",pcbddc->dbg_flag ,&pcbddc->dbg_flag ,NULL);CHKERRQ(ierr); 440c7d97c5SJed Brown /* Some customization for default primal space */ 450298fd71SBarry Smith ierr = PetscOptionsBool("-pc_bddc_vertices_only" ,"Use only vertices in coarse space (i.e. discard constraints)","none",pcbddc->vertices_flag ,&pcbddc->vertices_flag ,NULL);CHKERRQ(ierr); 460298fd71SBarry Smith ierr = PetscOptionsBool("-pc_bddc_constraints_only","Use only constraints in coarse space (i.e. discard vertices)","none",pcbddc->constraints_flag,&pcbddc->constraints_flag,NULL);CHKERRQ(ierr); 470298fd71SBarry Smith ierr = PetscOptionsBool("-pc_bddc_faces_only" ,"Use only faces among constraints of coarse space (i.e. discard edges)" ,"none",pcbddc->faces_flag ,&pcbddc->faces_flag ,NULL);CHKERRQ(ierr); 480298fd71SBarry Smith ierr = PetscOptionsBool("-pc_bddc_edges_only" ,"Use only edges among constraints of coarse space (i.e. discard faces)" ,"none",pcbddc->edges_flag ,&pcbddc->edges_flag ,NULL);CHKERRQ(ierr); 490c7d97c5SJed Brown /* Coarse solver context */ 506c667b0aSStefano Zampini static const char * const avail_coarse_problems[] = {"sequential","replicated","parallel","multilevel","CoarseProblemType","PC_BDDC_",0}; /*order of choiches depends on ENUM defined in bddc.h */ 510298fd71SBarry Smith ierr = PetscOptionsEnum("-pc_bddc_coarse_problem_type","Set coarse problem type","none",avail_coarse_problems,(PetscEnum)pcbddc->coarse_problem_type,(PetscEnum*)&pcbddc->coarse_problem_type,NULL);CHKERRQ(ierr); 520c7d97c5SJed Brown /* Two different application of BDDC to the whole set of dofs, internal and interface */ 530298fd71SBarry Smith ierr = PetscOptionsBool("-pc_bddc_switch_preconditioning_type","Switch between M_2 (default) and M_3 preconditioners (as defined by Dohrmann)","none",pcbddc->inexact_prec_type,&pcbddc->inexact_prec_type,NULL);CHKERRQ(ierr); 54674ae819SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_change_of_basis","Use change of basis approach for primal space","none",pcbddc->use_change_of_basis,&pcbddc->use_change_of_basis,NULL);CHKERRQ(ierr); 55674ae819SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_change_on_faces","Use change of basis approach for face constraints","none",pcbddc->use_change_on_faces,&pcbddc->use_change_on_faces,NULL);CHKERRQ(ierr); 56674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 57674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 58674ae819SStefano Zampini } 590298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr); 600298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_max_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr); 61674ae819SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_deluxe_scaling","Use deluxe scaling for BDDC","none",pcbddc->use_deluxe_scaling,&pcbddc->use_deluxe_scaling,NULL);CHKERRQ(ierr); 620c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 630c7d97c5SJed Brown PetscFunctionReturn(0); 640c7d97c5SJed Brown } 650c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 66674ae819SStefano Zampini #undef __FUNCT__ 67674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS_BDDC" 68674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 69674ae819SStefano Zampini { 70674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 71674ae819SStefano Zampini PetscErrorCode ierr; 721e6b0712SBarry Smith 73674ae819SStefano Zampini PetscFunctionBegin; 74674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 75674ae819SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 76674ae819SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 77674ae819SStefano Zampini PetscFunctionReturn(0); 78674ae819SStefano Zampini } 79674ae819SStefano Zampini #undef __FUNCT__ 80674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS" 81674ae819SStefano Zampini /*@ 82674ae819SStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set user defined primal vertices in PCBDDC. 83674ae819SStefano Zampini 84674ae819SStefano Zampini Not collective 85674ae819SStefano Zampini 86674ae819SStefano Zampini Input Parameters: 87674ae819SStefano Zampini + pc - the preconditioning context 88674ae819SStefano Zampini - PrimalVertices - index sets of primal vertices in local numbering 89674ae819SStefano Zampini 90674ae819SStefano Zampini Level: intermediate 91674ae819SStefano Zampini 92674ae819SStefano Zampini Notes: 93674ae819SStefano Zampini 94674ae819SStefano Zampini .seealso: PCBDDC 95674ae819SStefano Zampini @*/ 96674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 97674ae819SStefano Zampini { 98674ae819SStefano Zampini PetscErrorCode ierr; 99674ae819SStefano Zampini 100674ae819SStefano Zampini PetscFunctionBegin; 101674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 102674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 103674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 104674ae819SStefano Zampini PetscFunctionReturn(0); 105674ae819SStefano Zampini } 106674ae819SStefano Zampini /* -------------------------------------------------------------------------- */ 1070c7d97c5SJed Brown #undef __FUNCT__ 1080c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType_BDDC" 10953cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetCoarseProblemType_BDDC(PC pc, CoarseProblemType CPT) 1100c7d97c5SJed Brown { 1110c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1120c7d97c5SJed Brown 1130c7d97c5SJed Brown PetscFunctionBegin; 1140c7d97c5SJed Brown pcbddc->coarse_problem_type = CPT; 1150c7d97c5SJed Brown PetscFunctionReturn(0); 1160c7d97c5SJed Brown } 1171e6b0712SBarry Smith 1180c7d97c5SJed Brown #undef __FUNCT__ 1190c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType" 12053cdbc3dSStefano Zampini /*@ 1219c0446d6SStefano Zampini PCBDDCSetCoarseProblemType - Set coarse problem type in PCBDDC. 12253cdbc3dSStefano Zampini 1239c0446d6SStefano Zampini Not collective 12453cdbc3dSStefano Zampini 12553cdbc3dSStefano Zampini Input Parameters: 12653cdbc3dSStefano Zampini + pc - the preconditioning context 12753cdbc3dSStefano Zampini - CoarseProblemType - pick a better name and explain what this is 12853cdbc3dSStefano Zampini 12953cdbc3dSStefano Zampini Level: intermediate 13053cdbc3dSStefano Zampini 13153cdbc3dSStefano Zampini Notes: 132da1bb401SStefano Zampini Not collective but all procs must call with same arguments. 13353cdbc3dSStefano Zampini 13453cdbc3dSStefano Zampini .seealso: PCBDDC 13553cdbc3dSStefano Zampini @*/ 1360c7d97c5SJed Brown PetscErrorCode PCBDDCSetCoarseProblemType(PC pc, CoarseProblemType CPT) 1370c7d97c5SJed Brown { 1380c7d97c5SJed Brown PetscErrorCode ierr; 1390c7d97c5SJed Brown 1400c7d97c5SJed Brown PetscFunctionBegin; 1410c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1420c7d97c5SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetCoarseProblemType_C",(PC,CoarseProblemType),(pc,CPT));CHKERRQ(ierr); 1430c7d97c5SJed Brown PetscFunctionReturn(0); 1440c7d97c5SJed Brown } 1450c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1460c7d97c5SJed Brown #undef __FUNCT__ 1474fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio_BDDC" 1484fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 1494fad6a16SStefano Zampini { 1504fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1514fad6a16SStefano Zampini 1524fad6a16SStefano Zampini PetscFunctionBegin; 1534fad6a16SStefano Zampini pcbddc->coarsening_ratio=k; 1544fad6a16SStefano Zampini PetscFunctionReturn(0); 1554fad6a16SStefano Zampini } 1561e6b0712SBarry Smith 1574fad6a16SStefano Zampini #undef __FUNCT__ 1584fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio" 1594fad6a16SStefano Zampini /*@ 1604fad6a16SStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel coarsening 1614fad6a16SStefano Zampini 1624fad6a16SStefano Zampini Logically collective on PC 1634fad6a16SStefano Zampini 1644fad6a16SStefano Zampini Input Parameters: 1654fad6a16SStefano Zampini + pc - the preconditioning context 1664fad6a16SStefano Zampini - k - coarsening ratio 1674fad6a16SStefano Zampini 1684fad6a16SStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level. 1694fad6a16SStefano Zampini 1704fad6a16SStefano Zampini Level: intermediate 1714fad6a16SStefano Zampini 1724fad6a16SStefano Zampini Notes: 1734fad6a16SStefano Zampini 1744fad6a16SStefano Zampini .seealso: PCBDDC 1754fad6a16SStefano Zampini @*/ 1764fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 1774fad6a16SStefano Zampini { 1784fad6a16SStefano Zampini PetscErrorCode ierr; 1794fad6a16SStefano Zampini 1804fad6a16SStefano Zampini PetscFunctionBegin; 1814fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1824fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 1834fad6a16SStefano Zampini PetscFunctionReturn(0); 1844fad6a16SStefano Zampini } 1854fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 1861e6b0712SBarry Smith 1874fad6a16SStefano Zampini #undef __FUNCT__ 1884fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetMaxLevels_BDDC" 1894fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetMaxLevels_BDDC(PC pc,PetscInt max_levels) 1904fad6a16SStefano Zampini { 1914fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1924fad6a16SStefano Zampini 1934fad6a16SStefano Zampini PetscFunctionBegin; 1944fad6a16SStefano Zampini pcbddc->max_levels=max_levels; 1954fad6a16SStefano Zampini PetscFunctionReturn(0); 1964fad6a16SStefano Zampini } 1971e6b0712SBarry Smith 1984fad6a16SStefano Zampini #undef __FUNCT__ 1994fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetMaxLevels" 2004fad6a16SStefano Zampini /*@ 2014fad6a16SStefano Zampini PCBDDCSetMaxLevels - Sets the maximum number of levels within the multilevel approach. 2024fad6a16SStefano Zampini 2034fad6a16SStefano Zampini Logically collective on PC 2044fad6a16SStefano Zampini 2054fad6a16SStefano Zampini Input Parameters: 2064fad6a16SStefano Zampini + pc - the preconditioning context 2074fad6a16SStefano Zampini - max_levels - the maximum number of levels 2084fad6a16SStefano Zampini 2094fad6a16SStefano Zampini Default value is 1, i.e. coarse problem will be solved inexactly with one application 2104fad6a16SStefano Zampini of PCBDDC preconditioner if the multilevel approach is requested. 2114fad6a16SStefano Zampini 2124fad6a16SStefano Zampini Level: intermediate 2134fad6a16SStefano Zampini 2144fad6a16SStefano Zampini Notes: 2154fad6a16SStefano Zampini 2164fad6a16SStefano Zampini .seealso: PCBDDC 2174fad6a16SStefano Zampini @*/ 2184fad6a16SStefano Zampini PetscErrorCode PCBDDCSetMaxLevels(PC pc,PetscInt max_levels) 2194fad6a16SStefano Zampini { 2204fad6a16SStefano Zampini PetscErrorCode ierr; 2214fad6a16SStefano Zampini 2224fad6a16SStefano Zampini PetscFunctionBegin; 2234fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2244fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetMaxLevels_C",(PC,PetscInt),(pc,max_levels));CHKERRQ(ierr); 2254fad6a16SStefano Zampini PetscFunctionReturn(0); 2264fad6a16SStefano Zampini } 2274fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 2281e6b0712SBarry Smith 2294fad6a16SStefano Zampini #undef __FUNCT__ 2300bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace_BDDC" 2310bdf917eSStefano Zampini static PetscErrorCode PCBDDCSetNullSpace_BDDC(PC pc,MatNullSpace NullSpace) 2320bdf917eSStefano Zampini { 2330bdf917eSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2340bdf917eSStefano Zampini PetscErrorCode ierr; 2350bdf917eSStefano Zampini 2360bdf917eSStefano Zampini PetscFunctionBegin; 2370bdf917eSStefano Zampini ierr = PetscObjectReference((PetscObject)NullSpace);CHKERRQ(ierr); 2380bdf917eSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 2390bdf917eSStefano Zampini pcbddc->NullSpace=NullSpace; 2400bdf917eSStefano Zampini PetscFunctionReturn(0); 2410bdf917eSStefano Zampini } 2421e6b0712SBarry Smith 2430bdf917eSStefano Zampini #undef __FUNCT__ 2440bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace" 2450bdf917eSStefano Zampini /*@ 2460bdf917eSStefano Zampini PCBDDCSetNullSpace - Set NullSpace of global operator of BDDC preconditioned mat. 2470bdf917eSStefano Zampini 2480bdf917eSStefano Zampini Logically collective on PC and MatNullSpace 2490bdf917eSStefano Zampini 2500bdf917eSStefano Zampini Input Parameters: 2510bdf917eSStefano Zampini + pc - the preconditioning context 2520bdf917eSStefano Zampini - NullSpace - Null space of the linear operator to be preconditioned. 2530bdf917eSStefano Zampini 2540bdf917eSStefano Zampini Level: intermediate 2550bdf917eSStefano Zampini 2560bdf917eSStefano Zampini Notes: 2570bdf917eSStefano Zampini 2580bdf917eSStefano Zampini .seealso: PCBDDC 2590bdf917eSStefano Zampini @*/ 2600bdf917eSStefano Zampini PetscErrorCode PCBDDCSetNullSpace(PC pc,MatNullSpace NullSpace) 2610bdf917eSStefano Zampini { 2620bdf917eSStefano Zampini PetscErrorCode ierr; 2630bdf917eSStefano Zampini 2640bdf917eSStefano Zampini PetscFunctionBegin; 2650bdf917eSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 266674ae819SStefano Zampini PetscValidHeaderSpecific(NullSpace,MAT_NULLSPACE_CLASSID,2); 2670bdf917eSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNullSpace_C",(PC,MatNullSpace),(pc,NullSpace));CHKERRQ(ierr); 2680bdf917eSStefano Zampini PetscFunctionReturn(0); 2690bdf917eSStefano Zampini } 2700bdf917eSStefano Zampini /* -------------------------------------------------------------------------- */ 2711e6b0712SBarry Smith 2720bdf917eSStefano Zampini #undef __FUNCT__ 2733b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC" 2743b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 2753b03a366Sstefano_zampini { 2763b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2773b03a366Sstefano_zampini PetscErrorCode ierr; 2783b03a366Sstefano_zampini 2793b03a366Sstefano_zampini PetscFunctionBegin; 2803b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 28136e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 28236e030ebSStefano Zampini pcbddc->DirichletBoundaries=DirichletBoundaries; 2833b03a366Sstefano_zampini PetscFunctionReturn(0); 2843b03a366Sstefano_zampini } 2851e6b0712SBarry Smith 2863b03a366Sstefano_zampini #undef __FUNCT__ 2873b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries" 2883b03a366Sstefano_zampini /*@ 289da1bb401SStefano Zampini PCBDDCSetDirichletBoundaries - Set index set defining subdomain part (in local ordering) 290da1bb401SStefano Zampini of Dirichlet boundaries for the global problem. 2913b03a366Sstefano_zampini 2923b03a366Sstefano_zampini Not collective 2933b03a366Sstefano_zampini 2943b03a366Sstefano_zampini Input Parameters: 2953b03a366Sstefano_zampini + pc - the preconditioning context 2960298fd71SBarry Smith - DirichletBoundaries - sequential index set defining the subdomain part of Dirichlet boundaries (can be NULL) 2973b03a366Sstefano_zampini 2983b03a366Sstefano_zampini Level: intermediate 2993b03a366Sstefano_zampini 3003b03a366Sstefano_zampini Notes: 3013b03a366Sstefano_zampini 3023b03a366Sstefano_zampini .seealso: PCBDDC 3033b03a366Sstefano_zampini @*/ 3043b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 3053b03a366Sstefano_zampini { 3063b03a366Sstefano_zampini PetscErrorCode ierr; 3073b03a366Sstefano_zampini 3083b03a366Sstefano_zampini PetscFunctionBegin; 3093b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 310674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 3113b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 3123b03a366Sstefano_zampini PetscFunctionReturn(0); 3133b03a366Sstefano_zampini } 3143b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 3151e6b0712SBarry Smith 3163b03a366Sstefano_zampini #undef __FUNCT__ 3170c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 31853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 3190c7d97c5SJed Brown { 3200c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 32153cdbc3dSStefano Zampini PetscErrorCode ierr; 3220c7d97c5SJed Brown 3230c7d97c5SJed Brown PetscFunctionBegin; 32453cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 32536e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 32636e030ebSStefano Zampini pcbddc->NeumannBoundaries=NeumannBoundaries; 3270c7d97c5SJed Brown PetscFunctionReturn(0); 3280c7d97c5SJed Brown } 3291e6b0712SBarry Smith 3300c7d97c5SJed Brown #undef __FUNCT__ 3310c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 33257527edcSJed Brown /*@ 333da1bb401SStefano Zampini PCBDDCSetNeumannBoundaries - Set index set defining subdomain part (in local ordering) 334da1bb401SStefano Zampini of Neumann boundaries for the global problem. 33557527edcSJed Brown 3369c0446d6SStefano Zampini Not collective 33757527edcSJed Brown 33857527edcSJed Brown Input Parameters: 33957527edcSJed Brown + pc - the preconditioning context 3400298fd71SBarry Smith - NeumannBoundaries - sequential index set defining the subdomain part of Neumann boundaries (can be NULL) 34157527edcSJed Brown 34257527edcSJed Brown Level: intermediate 34357527edcSJed Brown 34457527edcSJed Brown Notes: 34557527edcSJed Brown 34657527edcSJed Brown .seealso: PCBDDC 34757527edcSJed Brown @*/ 34853cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 3490c7d97c5SJed Brown { 3500c7d97c5SJed Brown PetscErrorCode ierr; 3510c7d97c5SJed Brown 3520c7d97c5SJed Brown PetscFunctionBegin; 3530c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 354674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 35553cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 35653cdbc3dSStefano Zampini PetscFunctionReturn(0); 35753cdbc3dSStefano Zampini } 35853cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 3591e6b0712SBarry Smith 36053cdbc3dSStefano Zampini #undef __FUNCT__ 361da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC" 362da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 363da1bb401SStefano Zampini { 364da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 365da1bb401SStefano Zampini 366da1bb401SStefano Zampini PetscFunctionBegin; 367da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 368da1bb401SStefano Zampini PetscFunctionReturn(0); 369da1bb401SStefano Zampini } 3701e6b0712SBarry Smith 371da1bb401SStefano Zampini #undef __FUNCT__ 372da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries" 373da1bb401SStefano Zampini /*@ 374da1bb401SStefano Zampini PCBDDCGetDirichletBoundaries - Get index set defining subdomain part (in local ordering) 375da1bb401SStefano Zampini of Dirichlet boundaries for the global problem. 376da1bb401SStefano Zampini 377da1bb401SStefano Zampini Not collective 378da1bb401SStefano Zampini 379da1bb401SStefano Zampini Input Parameters: 380da1bb401SStefano Zampini + pc - the preconditioning context 381da1bb401SStefano Zampini 382da1bb401SStefano Zampini Output Parameters: 383da1bb401SStefano Zampini + DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 384da1bb401SStefano Zampini 385da1bb401SStefano Zampini Level: intermediate 386da1bb401SStefano Zampini 387da1bb401SStefano Zampini Notes: 388da1bb401SStefano Zampini 389da1bb401SStefano Zampini .seealso: PCBDDC 390da1bb401SStefano Zampini @*/ 391da1bb401SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 392da1bb401SStefano Zampini { 393da1bb401SStefano Zampini PetscErrorCode ierr; 394da1bb401SStefano Zampini 395da1bb401SStefano Zampini PetscFunctionBegin; 396da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 397da1bb401SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 398da1bb401SStefano Zampini PetscFunctionReturn(0); 399da1bb401SStefano Zampini } 400da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 4011e6b0712SBarry Smith 402da1bb401SStefano Zampini #undef __FUNCT__ 40353cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 40453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 40553cdbc3dSStefano Zampini { 40653cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 40753cdbc3dSStefano Zampini 40853cdbc3dSStefano Zampini PetscFunctionBegin; 40953cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 41053cdbc3dSStefano Zampini PetscFunctionReturn(0); 41153cdbc3dSStefano Zampini } 4121e6b0712SBarry Smith 41353cdbc3dSStefano Zampini #undef __FUNCT__ 41453cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 41553cdbc3dSStefano Zampini /*@ 416da1bb401SStefano Zampini PCBDDCGetNeumannBoundaries - Get index set defining subdomain part (in local ordering) 417da1bb401SStefano Zampini of Neumann boundaries for the global problem. 41853cdbc3dSStefano Zampini 4199c0446d6SStefano Zampini Not collective 42053cdbc3dSStefano Zampini 42153cdbc3dSStefano Zampini Input Parameters: 42253cdbc3dSStefano Zampini + pc - the preconditioning context 42353cdbc3dSStefano Zampini 42453cdbc3dSStefano Zampini Output Parameters: 42553cdbc3dSStefano Zampini + NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 42653cdbc3dSStefano Zampini 42753cdbc3dSStefano Zampini Level: intermediate 42853cdbc3dSStefano Zampini 42953cdbc3dSStefano Zampini Notes: 43053cdbc3dSStefano Zampini 43153cdbc3dSStefano Zampini .seealso: PCBDDC 43253cdbc3dSStefano Zampini @*/ 43353cdbc3dSStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 43453cdbc3dSStefano Zampini { 43553cdbc3dSStefano Zampini PetscErrorCode ierr; 43653cdbc3dSStefano Zampini 43753cdbc3dSStefano Zampini PetscFunctionBegin; 43853cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 43953cdbc3dSStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 4400c7d97c5SJed Brown PetscFunctionReturn(0); 4410c7d97c5SJed Brown } 44236e030ebSStefano Zampini /* -------------------------------------------------------------------------- */ 4431e6b0712SBarry Smith 44436e030ebSStefano Zampini #undef __FUNCT__ 445da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC" 4461a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 44736e030ebSStefano Zampini { 44836e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 449da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 450da1bb401SStefano Zampini PetscErrorCode ierr; 45136e030ebSStefano Zampini 45236e030ebSStefano Zampini PetscFunctionBegin; 453674ae819SStefano Zampini /* free old CSR */ 454674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 455674ae819SStefano Zampini /* get CSR into graph structure */ 456da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 457674ae819SStefano Zampini ierr = PetscMalloc((nvtxs+1)*sizeof(PetscInt),&mat_graph->xadj);CHKERRQ(ierr); 458674ae819SStefano Zampini ierr = PetscMalloc(xadj[nvtxs]*sizeof(PetscInt),&mat_graph->adjncy);CHKERRQ(ierr); 459674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 460674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 461da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 4621a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 4631a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 464674ae819SStefano Zampini } 465575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 46636e030ebSStefano Zampini PetscFunctionReturn(0); 46736e030ebSStefano Zampini } 4681e6b0712SBarry Smith 46936e030ebSStefano Zampini #undef __FUNCT__ 470da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph" 47136e030ebSStefano Zampini /*@ 472da1bb401SStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set CSR graph of local matrix for use of PCBDDC. 47336e030ebSStefano Zampini 47436e030ebSStefano Zampini Not collective 47536e030ebSStefano Zampini 47636e030ebSStefano Zampini Input Parameters: 47736e030ebSStefano Zampini + pc - the preconditioning context 478da1bb401SStefano Zampini - nvtxs - number of local vertices of the graph 479da1bb401SStefano Zampini - xadj, adjncy - the CSR graph 480da1bb401SStefano Zampini - copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER. In the former case the user must free the array passed in; 481da1bb401SStefano Zampini in the latter case, memory must be obtained with PetscMalloc. 48236e030ebSStefano Zampini 48336e030ebSStefano Zampini Level: intermediate 48436e030ebSStefano Zampini 48536e030ebSStefano Zampini Notes: 48636e030ebSStefano Zampini 48736e030ebSStefano Zampini .seealso: PCBDDC 48836e030ebSStefano Zampini @*/ 4891a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 49036e030ebSStefano Zampini { 491575ad6abSStefano Zampini void (*f)(void) = 0; 49236e030ebSStefano Zampini PetscErrorCode ierr; 49336e030ebSStefano Zampini 49436e030ebSStefano Zampini PetscFunctionBegin; 49536e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 496674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 497674ae819SStefano Zampini PetscValidIntPointer(xadj,4); 498674ae819SStefano Zampini if (copymode != PETSC_COPY_VALUES && copymode != PETSC_OWN_POINTER) { 499674ae819SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d in %s\n",copymode,__FUNCT__); 500da1bb401SStefano Zampini } 501674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 502575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 503575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 504575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 505575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 506575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 507575ad6abSStefano Zampini } 50836e030ebSStefano Zampini PetscFunctionReturn(0); 50936e030ebSStefano Zampini } 5109c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 5111e6b0712SBarry Smith 5129c0446d6SStefano Zampini #undef __FUNCT__ 5139c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 5149c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 5159c0446d6SStefano Zampini { 5169c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5179c0446d6SStefano Zampini PetscInt i; 5189c0446d6SStefano Zampini PetscErrorCode ierr; 5199c0446d6SStefano Zampini 5209c0446d6SStefano Zampini PetscFunctionBegin; 521da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 5229c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 5239c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 5249c0446d6SStefano Zampini } 525d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 526da1bb401SStefano Zampini /* allocate space then set */ 5279c0446d6SStefano Zampini ierr = PetscMalloc(n_is*sizeof(IS),&pcbddc->ISForDofs);CHKERRQ(ierr); 5289c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 529da1bb401SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 530da1bb401SStefano Zampini pcbddc->ISForDofs[i]=ISForDofs[i]; 5319c0446d6SStefano Zampini } 5329c0446d6SStefano Zampini pcbddc->n_ISForDofs=n_is; 5339c0446d6SStefano Zampini PetscFunctionReturn(0); 5349c0446d6SStefano Zampini } 5351e6b0712SBarry Smith 5369c0446d6SStefano Zampini #undef __FUNCT__ 5379c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 5389c0446d6SStefano Zampini /*@ 539da1bb401SStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of local mat. 5409c0446d6SStefano Zampini 5419c0446d6SStefano Zampini Not collective 5429c0446d6SStefano Zampini 5439c0446d6SStefano Zampini Input Parameters: 5449c0446d6SStefano Zampini + pc - the preconditioning context 545da1bb401SStefano Zampini - n - number of index sets defining the fields 546da1bb401SStefano Zampini - IS[] - array of IS describing the fields 5479c0446d6SStefano Zampini 5489c0446d6SStefano Zampini Level: intermediate 5499c0446d6SStefano Zampini 5509c0446d6SStefano Zampini Notes: 5519c0446d6SStefano Zampini 5529c0446d6SStefano Zampini .seealso: PCBDDC 5539c0446d6SStefano Zampini @*/ 5549c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 5559c0446d6SStefano Zampini { 5569c0446d6SStefano Zampini PetscErrorCode ierr; 5579c0446d6SStefano Zampini 5589c0446d6SStefano Zampini PetscFunctionBegin; 5599c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5609c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 5619c0446d6SStefano Zampini PetscFunctionReturn(0); 5629c0446d6SStefano Zampini } 563da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 564534831adSStefano Zampini #undef __FUNCT__ 565534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC" 566534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 567534831adSStefano Zampini /* 568534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 569534831adSStefano Zampini guess if a transformation of basis approach has been selected. 5709c0446d6SStefano Zampini 571534831adSStefano Zampini Input Parameter: 572534831adSStefano Zampini + pc - the preconditioner contex 573534831adSStefano Zampini 574534831adSStefano Zampini Application Interface Routine: PCPreSolve() 575534831adSStefano Zampini 576534831adSStefano Zampini Notes: 577534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 578534831adSStefano Zampini the user, but instead is called by KSPSolve(). 579534831adSStefano Zampini */ 580534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 581534831adSStefano Zampini { 582534831adSStefano Zampini PetscErrorCode ierr; 583534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 584534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 585534831adSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 586534831adSStefano Zampini Mat temp_mat; 5873972b0daSStefano Zampini IS dirIS; 5883972b0daSStefano Zampini PetscInt dirsize,i,*is_indices; 5893972b0daSStefano Zampini PetscScalar *array_x,*array_diagonal; 5903972b0daSStefano Zampini Vec used_vec; 5913972b0daSStefano Zampini PetscBool guess_nonzero; 592534831adSStefano Zampini 593534831adSStefano Zampini PetscFunctionBegin; 5943972b0daSStefano Zampini if (x) { 5953972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 5963972b0daSStefano Zampini used_vec = x; 5973972b0daSStefano Zampini } else { 5983972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 5993972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 6003972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 6013972b0daSStefano Zampini } 6023972b0daSStefano Zampini /* hack into ksp data structure PCPreSolve comes earlier in src/ksp/ksp/interface/itfunc.c */ 6033972b0daSStefano Zampini if (ksp) { 6043972b0daSStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&guess_nonzero);CHKERRQ(ierr); 6053972b0daSStefano Zampini if ( !guess_nonzero ) { 6063972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 6073972b0daSStefano Zampini } 6083972b0daSStefano Zampini } 6093972b0daSStefano Zampini /* store the original rhs */ 6103972b0daSStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 6113972b0daSStefano Zampini 6123972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 6133972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 6143972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 6153972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6163972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6173972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6183972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6193972b0daSStefano Zampini ierr = PCBDDCGetDirichletBoundaries(pc,&dirIS);CHKERRQ(ierr); 6203972b0daSStefano Zampini if (dirIS) { 6213972b0daSStefano Zampini ierr = ISGetSize(dirIS,&dirsize);CHKERRQ(ierr); 6223972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 6233972b0daSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 6243972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6252fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 6263972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6273972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 6283972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 6293972b0daSStefano Zampini } 6303972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6313972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 632b76ba322SStefano Zampini 6333972b0daSStefano Zampini /* remove the computed solution from the rhs */ 6343972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 6353972b0daSStefano Zampini ierr = MatMultAdd(pc->pmat,used_vec,rhs,rhs);CHKERRQ(ierr); 6363972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 637b76ba322SStefano Zampini 638b76ba322SStefano Zampini /* store partially computed solution and set initial guess */ 6393972b0daSStefano Zampini if (x) { 6403972b0daSStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 6413972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 642*15aaf578SStefano Zampini if (pcbddc->use_exact_dirichlet && !pcbddc->coarse_psi_B) { 643b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 644b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 645b76ba322SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 646b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 647b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 648b76ba322SStefano Zampini if (ksp) { 649b76ba322SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 650b76ba322SStefano Zampini } 651b76ba322SStefano Zampini } 6523972b0daSStefano Zampini } 653b76ba322SStefano Zampini 654b76ba322SStefano Zampini /* rhs change of basis */ 655674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 656b76ba322SStefano Zampini /* swap pointers for local matrices */ 657b76ba322SStefano Zampini temp_mat = matis->A; 658b76ba322SStefano Zampini matis->A = pcbddc->local_mat; 659b76ba322SStefano Zampini pcbddc->local_mat = temp_mat; 660b76ba322SStefano Zampini /* Get local rhs and apply transformation of basis */ 661b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 662b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 663b76ba322SStefano Zampini /* from original basis to modified basis */ 664b76ba322SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 665b76ba322SStefano Zampini /* put back modified values into the global vec using INSERT_VALUES copy mode */ 666b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 667b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 668674ae819SStefano Zampini } 6690bdf917eSStefano Zampini if (ksp && pcbddc->NullSpace) { 6700298fd71SBarry Smith ierr = MatNullSpaceRemove(pcbddc->NullSpace,used_vec,NULL);CHKERRQ(ierr); 6710298fd71SBarry Smith ierr = MatNullSpaceRemove(pcbddc->NullSpace,rhs,NULL);CHKERRQ(ierr); 672b76ba322SStefano Zampini } 6730bdf917eSStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 674534831adSStefano Zampini PetscFunctionReturn(0); 675534831adSStefano Zampini } 676534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 677534831adSStefano Zampini #undef __FUNCT__ 678534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC" 679534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 680534831adSStefano Zampini /* 681534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 682534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 683534831adSStefano Zampini 684534831adSStefano Zampini Input Parameter: 685534831adSStefano Zampini + pc - the preconditioner contex 686534831adSStefano Zampini 687534831adSStefano Zampini Application Interface Routine: PCPostSolve() 688534831adSStefano Zampini 689534831adSStefano Zampini Notes: 690534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 691534831adSStefano Zampini the user, but instead is called by KSPSolve(). 692534831adSStefano Zampini */ 693534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 694534831adSStefano Zampini { 695534831adSStefano Zampini PetscErrorCode ierr; 696534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 697534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 698534831adSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 699534831adSStefano Zampini Mat temp_mat; 700534831adSStefano Zampini 701534831adSStefano Zampini PetscFunctionBegin; 702674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 703534831adSStefano Zampini /* swap pointers for local matrices */ 704534831adSStefano Zampini temp_mat = matis->A; 705534831adSStefano Zampini matis->A = pcbddc->local_mat; 706534831adSStefano Zampini pcbddc->local_mat = temp_mat; 707534831adSStefano Zampini /* restore rhs to its original state */ 7083425bc38SStefano Zampini if (rhs) { 7093425bc38SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,rhs);CHKERRQ(ierr); 7103425bc38SStefano Zampini } 711534831adSStefano Zampini /* Get Local boundary and apply transformation of basis to solution vector */ 712534831adSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 713534831adSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 714534831adSStefano Zampini /* from modified basis to original basis */ 715534831adSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 716534831adSStefano Zampini /* put back modified values into the global vec using INSERT_VALUES copy mode */ 717534831adSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 718534831adSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 719534831adSStefano Zampini } 7203972b0daSStefano Zampini /* add solution removed in presolve */ 7213425bc38SStefano Zampini if (x) { 7223425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 7233425bc38SStefano Zampini } 724534831adSStefano Zampini PetscFunctionReturn(0); 725534831adSStefano Zampini } 726534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 72753cdbc3dSStefano Zampini #undef __FUNCT__ 72853cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 7290c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 7300c7d97c5SJed Brown /* 7310c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 7320c7d97c5SJed Brown by setting data structures and options. 7330c7d97c5SJed Brown 7340c7d97c5SJed Brown Input Parameter: 73553cdbc3dSStefano Zampini + pc - the preconditioner context 7360c7d97c5SJed Brown 7370c7d97c5SJed Brown Application Interface Routine: PCSetUp() 7380c7d97c5SJed Brown 7390c7d97c5SJed Brown Notes: 7400c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 7410c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 7420c7d97c5SJed Brown */ 74353cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 7440c7d97c5SJed Brown { 7450c7d97c5SJed Brown PetscErrorCode ierr; 7460c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 747674ae819SStefano Zampini MatStructure flag; 748674ae819SStefano Zampini PetscBool computeis,computetopography,computesolvers; 7490c7d97c5SJed Brown 7500c7d97c5SJed Brown PetscFunctionBegin; 751674ae819SStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other nonoverlapping preconditioners */ 7523b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 7539c0446d6SStefano Zampini So, we set to pcnone the Neumann problem of pcis in order to avoid unneeded computation 7540c7d97c5SJed Brown Also, we decide to directly build the (same) Dirichlet problem */ 7550c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localN_pc_type","none");CHKERRQ(ierr); 7560c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localD_pc_type","none");CHKERRQ(ierr); 7573b03a366Sstefano_zampini /* Get stdout for dbg */ 758674ae819SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->dbg_viewer) { 759ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pc),&pcbddc->dbg_viewer);CHKERRQ(ierr); 760e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 761e269702eSStefano Zampini } 762674ae819SStefano Zampini /* first attempt to split work */ 763674ae819SStefano Zampini if (pc->setupcalled) { 764674ae819SStefano Zampini computeis = PETSC_FALSE; 765674ae819SStefano Zampini ierr = PCGetOperators(pc,NULL,NULL,&flag);CHKERRQ(ierr); 766674ae819SStefano Zampini if (flag == SAME_PRECONDITIONER) { 767674ae819SStefano Zampini computetopography = PETSC_FALSE; 768674ae819SStefano Zampini computesolvers = PETSC_FALSE; 769674ae819SStefano Zampini } else if (flag == SAME_NONZERO_PATTERN) { 770674ae819SStefano Zampini computetopography = PETSC_FALSE; 771674ae819SStefano Zampini computesolvers = PETSC_TRUE; 772674ae819SStefano Zampini } else { /* DIFFERENT_NONZERO_PATTERN */ 773674ae819SStefano Zampini computetopography = PETSC_TRUE; 774674ae819SStefano Zampini computesolvers = PETSC_TRUE; 775674ae819SStefano Zampini } 776674ae819SStefano Zampini } else { 777674ae819SStefano Zampini computeis = PETSC_TRUE; 778674ae819SStefano Zampini computetopography = PETSC_TRUE; 779674ae819SStefano Zampini computesolvers = PETSC_TRUE; 780674ae819SStefano Zampini } 781674ae819SStefano Zampini /* Set up all the "iterative substructuring" common block */ 782674ae819SStefano Zampini if (computeis) { 783674ae819SStefano Zampini ierr = PCISSetUp(pc);CHKERRQ(ierr); 784674ae819SStefano Zampini } 785674ae819SStefano Zampini /* Analyze interface and set up local constraint and change of basis matrices */ 786674ae819SStefano Zampini if (computetopography) { 787674ae819SStefano Zampini /* reset data */ 788674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 789674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 790674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 791674ae819SStefano Zampini } 792674ae819SStefano Zampini if (computesolvers) { 793674ae819SStefano Zampini /* reset data */ 794674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 795674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 7960c7d97c5SJed Brown /* Create coarse and local stuffs used for evaluating action of preconditioner */ 7970c7d97c5SJed Brown ierr = PCBDDCCoarseSetUp(pc);CHKERRQ(ierr); 798674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 7990c7d97c5SJed Brown } 8000c7d97c5SJed Brown PetscFunctionReturn(0); 8010c7d97c5SJed Brown } 8020c7d97c5SJed Brown 8030c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 8040c7d97c5SJed Brown /* 8050c7d97c5SJed Brown PCApply_BDDC - Applies the BDDC preconditioner to a vector. 8060c7d97c5SJed Brown 8070c7d97c5SJed Brown Input Parameters: 8080c7d97c5SJed Brown . pc - the preconditioner context 8090c7d97c5SJed Brown . r - input vector (global) 8100c7d97c5SJed Brown 8110c7d97c5SJed Brown Output Parameter: 8120c7d97c5SJed Brown . z - output vector (global) 8130c7d97c5SJed Brown 8140c7d97c5SJed Brown Application Interface Routine: PCApply() 8150c7d97c5SJed Brown */ 8160c7d97c5SJed Brown #undef __FUNCT__ 8170c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 81853cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 8190c7d97c5SJed Brown { 8200c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 8210c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 8220c7d97c5SJed Brown PetscErrorCode ierr; 8233b03a366Sstefano_zampini const PetscScalar one = 1.0; 8243b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 8252617d88aSStefano Zampini const PetscScalar zero = 0.0; 8260c7d97c5SJed Brown 8270c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 8280c7d97c5SJed Brown NN interface preconditioner changed to BDDC 82929622bf0SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->inexact_prec_type = PETSC_TRUE) */ 8300c7d97c5SJed Brown 8310c7d97c5SJed Brown PetscFunctionBegin; 832*15aaf578SStefano Zampini if (!pcbddc->use_exact_dirichlet || pcbddc->coarse_psi_B) { 8330c7d97c5SJed Brown /* First Dirichlet solve */ 8340c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8350c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 83653cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 8370c7d97c5SJed Brown /* 8380c7d97c5SJed Brown Assembling right hand side for BDDC operator 839674ae819SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE) 840674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 8410c7d97c5SJed Brown */ 8420c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 8430c7d97c5SJed Brown ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 84429622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 8450c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 8460c7d97c5SJed Brown ierr = VecCopy(r,z);CHKERRQ(ierr); 8470c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8480c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 849674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 850b76ba322SStefano Zampini } else { 8510bdf917eSStefano Zampini ierr = VecSet(pcis->vec1_D,zero);CHKERRQ(ierr); 852b76ba322SStefano Zampini ierr = VecSet(pcis->vec2_D,zero);CHKERRQ(ierr); 853674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 854b76ba322SStefano Zampini } 855b76ba322SStefano Zampini 8562617d88aSStefano Zampini /* Apply interface preconditioner 8572617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 8582617d88aSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc);CHKERRQ(ierr); 8592617d88aSStefano Zampini 860674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 861674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 8620c7d97c5SJed Brown 8633b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 8640c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8650c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8660c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 86729622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 86853cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr); 8690c7d97c5SJed Brown ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr); 87029622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); } 8710c7d97c5SJed Brown ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr); 8720c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8730c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8740c7d97c5SJed Brown PetscFunctionReturn(0); 8750c7d97c5SJed Brown } 876da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 877674ae819SStefano Zampini 878da1bb401SStefano Zampini #undef __FUNCT__ 879da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC" 880da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 881da1bb401SStefano Zampini { 882da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 883da1bb401SStefano Zampini PetscErrorCode ierr; 884da1bb401SStefano Zampini 885da1bb401SStefano Zampini PetscFunctionBegin; 886da1bb401SStefano Zampini /* free data created by PCIS */ 887da1bb401SStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 888674ae819SStefano Zampini /* free BDDC custom data */ 889674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 890674ae819SStefano Zampini /* destroy objects related to topography */ 891674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 892674ae819SStefano Zampini /* free allocated graph structure */ 893da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr); 894674ae819SStefano Zampini /* free data for scaling operator */ 895674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 896674ae819SStefano Zampini /* free solvers stuff */ 897674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 8983425bc38SStefano Zampini /* remove functions */ 899674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 900bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 901bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetMaxLevels_C",NULL);CHKERRQ(ierr); 902bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",NULL);CHKERRQ(ierr); 903bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 904bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 905bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 906bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 907bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseProblemType_C",NULL);CHKERRQ(ierr); 908bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 909bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 910bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 911bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 912bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 913674ae819SStefano Zampini /* Free the private data structure */ 914674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 915da1bb401SStefano Zampini PetscFunctionReturn(0); 916da1bb401SStefano Zampini } 9173425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 9181e6b0712SBarry Smith 9193425bc38SStefano Zampini #undef __FUNCT__ 9203425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC" 9213425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 9223425bc38SStefano Zampini { 923674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 9243425bc38SStefano Zampini PC_IS* pcis; 9253425bc38SStefano Zampini PC_BDDC* pcbddc; 9263425bc38SStefano Zampini PetscErrorCode ierr; 9270c7d97c5SJed Brown 9283425bc38SStefano Zampini PetscFunctionBegin; 9293425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 9303425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 9313425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 9323425bc38SStefano Zampini 9333425bc38SStefano Zampini /* change of basis for physical rhs if needed 9343425bc38SStefano Zampini It also changes the rhs in case of dirichlet boundaries */ 9350298fd71SBarry Smith (*mat_ctx->pc->ops->presolve)(mat_ctx->pc,NULL,standard_rhs,NULL); 9363425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 9373425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9383425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 939674ae819SStefano Zampini /* scale rhs since it should be unassembled : TODO use counter scaling? (also below) */ 9403425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9413425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 942674ae819SStefano Zampini /* Apply partition of unity */ 9433425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 944674ae819SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 94529622bf0SStefano Zampini if (!pcbddc->inexact_prec_type) { 9463425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 9473425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 9483425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 9493425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 9503425bc38SStefano Zampini ierr = VecSet(standard_rhs,0.0);CHKERRQ(ierr); 9513425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9523425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 953674ae819SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 9543425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9553425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9563425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 9573425bc38SStefano Zampini } 9583425bc38SStefano Zampini /* BDDC rhs */ 9593425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 96029622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { 9613425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 9623425bc38SStefano Zampini } 9633425bc38SStefano Zampini /* apply BDDC */ 9643425bc38SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr); 9653425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 9663425bc38SStefano Zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 9673425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 9683425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9693425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9703425bc38SStefano Zampini /* restore original rhs */ 9713425bc38SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,standard_rhs);CHKERRQ(ierr); 9723425bc38SStefano Zampini PetscFunctionReturn(0); 9733425bc38SStefano Zampini } 9741e6b0712SBarry Smith 9753425bc38SStefano Zampini #undef __FUNCT__ 9763425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS" 9773425bc38SStefano Zampini /*@ 9783425bc38SStefano Zampini PCBDDCMatFETIDPGetRHS - Get rhs for FETIDP linear system. 9793425bc38SStefano Zampini 9803425bc38SStefano Zampini Collective 9813425bc38SStefano Zampini 9823425bc38SStefano Zampini Input Parameters: 9833425bc38SStefano Zampini + fetidp_mat - the FETIDP mat obtained by a call to PCBDDCCreateFETIDPOperators 9843425bc38SStefano Zampini + standard_rhs - the rhs of your linear system 9853425bc38SStefano Zampini 9863425bc38SStefano Zampini Output Parameters: 9873425bc38SStefano Zampini + fetidp_flux_rhs - the rhs of the FETIDP linear system 9883425bc38SStefano Zampini 9893425bc38SStefano Zampini Level: developer 9903425bc38SStefano Zampini 9913425bc38SStefano Zampini Notes: 9923425bc38SStefano Zampini 9933425bc38SStefano Zampini .seealso: PCBDDC 9943425bc38SStefano Zampini @*/ 9953425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 9963425bc38SStefano Zampini { 997674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 9983425bc38SStefano Zampini PetscErrorCode ierr; 9993425bc38SStefano Zampini 10003425bc38SStefano Zampini PetscFunctionBegin; 10013425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10023425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 10033425bc38SStefano Zampini PetscFunctionReturn(0); 10043425bc38SStefano Zampini } 10053425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 10061e6b0712SBarry Smith 10073425bc38SStefano Zampini #undef __FUNCT__ 10083425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC" 10093425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 10103425bc38SStefano Zampini { 1011674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 10123425bc38SStefano Zampini PC_IS* pcis; 10133425bc38SStefano Zampini PC_BDDC* pcbddc; 10143425bc38SStefano Zampini PetscErrorCode ierr; 10153425bc38SStefano Zampini 10163425bc38SStefano Zampini PetscFunctionBegin; 10173425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10183425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 10193425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 10203425bc38SStefano Zampini 10213425bc38SStefano Zampini /* apply B_delta^T */ 10223425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10233425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10243425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 10253425bc38SStefano Zampini /* compute rhs for BDDC application */ 10263425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 102729622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { 10283425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 10293425bc38SStefano Zampini } 10303425bc38SStefano Zampini /* apply BDDC */ 10313425bc38SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr); 10323425bc38SStefano Zampini /* put values into standard global vector */ 10333425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10343425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 103529622bf0SStefano Zampini if (!pcbddc->inexact_prec_type) { 10363425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 10373425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 10383425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_D,-1.0,pcis->vec1_D);CHKERRQ(ierr); 10393425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 10403425bc38SStefano Zampini } 10413425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10423425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10433425bc38SStefano Zampini /* final change of basis if needed 10443425bc38SStefano Zampini Is also sums the dirichlet part removed during RHS assembling */ 10450298fd71SBarry Smith (*mat_ctx->pc->ops->postsolve)(mat_ctx->pc,NULL,NULL,standard_sol); 10463425bc38SStefano Zampini PetscFunctionReturn(0); 10473425bc38SStefano Zampini 10483425bc38SStefano Zampini } 10491e6b0712SBarry Smith 10503425bc38SStefano Zampini #undef __FUNCT__ 10513425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution" 10523425bc38SStefano Zampini /*@ 10533425bc38SStefano Zampini PCBDDCMatFETIDPGetSolution - Get Solution for FETIDP linear system. 10543425bc38SStefano Zampini 10553425bc38SStefano Zampini Collective 10563425bc38SStefano Zampini 10573425bc38SStefano Zampini Input Parameters: 10583425bc38SStefano Zampini + fetidp_mat - the FETIDP mat obtained by a call to PCBDDCCreateFETIDPOperators 10593425bc38SStefano Zampini + fetidp_flux_sol - the solution of the FETIDP linear system 10603425bc38SStefano Zampini 10613425bc38SStefano Zampini Output Parameters: 10623425bc38SStefano Zampini + standard_sol - the solution on the global domain 10633425bc38SStefano Zampini 10643425bc38SStefano Zampini Level: developer 10653425bc38SStefano Zampini 10663425bc38SStefano Zampini Notes: 10673425bc38SStefano Zampini 10683425bc38SStefano Zampini .seealso: PCBDDC 10693425bc38SStefano Zampini @*/ 10703425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 10713425bc38SStefano Zampini { 1072674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 10733425bc38SStefano Zampini PetscErrorCode ierr; 10743425bc38SStefano Zampini 10753425bc38SStefano Zampini PetscFunctionBegin; 10763425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10773425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 10783425bc38SStefano Zampini PetscFunctionReturn(0); 10793425bc38SStefano Zampini } 10803425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 10811e6b0712SBarry Smith 1082f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec); 1083f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat); 1084f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec); 1085f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC); 1086674ae819SStefano Zampini 10873425bc38SStefano Zampini #undef __FUNCT__ 10883425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC" 10893425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 10903425bc38SStefano Zampini { 1091674ae819SStefano Zampini 1092674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 10933425bc38SStefano Zampini Mat newmat; 1094674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 10953425bc38SStefano Zampini PC newpc; 1096ce94432eSBarry Smith MPI_Comm comm; 10973425bc38SStefano Zampini PetscErrorCode ierr; 10983425bc38SStefano Zampini 10993425bc38SStefano Zampini PetscFunctionBegin; 1100ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 11013425bc38SStefano Zampini /* FETIDP linear matrix */ 11023425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 11033425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 11043425bc38SStefano Zampini ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 11053425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 11063425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 11073425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 11083425bc38SStefano Zampini /* FETIDP preconditioner */ 11093425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 11103425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 11113425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 11123425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 11133425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 11143425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 11153425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 11163425bc38SStefano Zampini ierr = PCSetOperators(newpc,newmat,newmat,SAME_PRECONDITIONER);CHKERRQ(ierr); 11173425bc38SStefano Zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 11183425bc38SStefano Zampini /* return pointers for objects created */ 11193425bc38SStefano Zampini *fetidp_mat=newmat; 11203425bc38SStefano Zampini *fetidp_pc=newpc; 11213425bc38SStefano Zampini PetscFunctionReturn(0); 11223425bc38SStefano Zampini } 11231e6b0712SBarry Smith 11243425bc38SStefano Zampini #undef __FUNCT__ 11253425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators" 11263425bc38SStefano Zampini /*@ 11273425bc38SStefano Zampini PCBDDCCreateFETIDPOperators - Create operators for FETIDP. 11283425bc38SStefano Zampini 11293425bc38SStefano Zampini Collective 11303425bc38SStefano Zampini 11313425bc38SStefano Zampini Input Parameters: 11323425bc38SStefano Zampini + pc - the BDDC preconditioning context (setup must be already called) 11333425bc38SStefano Zampini 11343425bc38SStefano Zampini Level: developer 11353425bc38SStefano Zampini 11363425bc38SStefano Zampini Notes: 11373425bc38SStefano Zampini 11383425bc38SStefano Zampini .seealso: PCBDDC 11393425bc38SStefano Zampini @*/ 11403425bc38SStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 11413425bc38SStefano Zampini { 11423425bc38SStefano Zampini PetscErrorCode ierr; 11433425bc38SStefano Zampini 11443425bc38SStefano Zampini PetscFunctionBegin; 11453425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 11463425bc38SStefano Zampini if (pc->setupcalled) { 11473425bc38SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,Mat*,PC*),(pc,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 1148f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n"); 11493425bc38SStefano Zampini PetscFunctionReturn(0); 11503425bc38SStefano Zampini } 11510c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1152da1bb401SStefano Zampini /*MC 1153da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 11540c7d97c5SJed Brown 1155da1bb401SStefano Zampini Options Database Keys: 1156da1bb401SStefano Zampini . -pcbddc ??? - 1157da1bb401SStefano Zampini 1158da1bb401SStefano Zampini Level: intermediate 1159da1bb401SStefano Zampini 1160da1bb401SStefano Zampini Notes: The matrix used with this preconditioner must be of type MATIS 1161da1bb401SStefano Zampini 1162da1bb401SStefano Zampini Unlike more 'conventional' interface preconditioners, this iterates over ALL the 1163da1bb401SStefano Zampini degrees of freedom, NOT just those on the interface (this allows the use of approximate solvers 1164da1bb401SStefano Zampini on the subdomains). 1165da1bb401SStefano Zampini 1166da1bb401SStefano Zampini Options for the coarse grid preconditioner can be set with - 1167da1bb401SStefano Zampini Options for the Dirichlet subproblem can be set with - 1168da1bb401SStefano Zampini Options for the Neumann subproblem can be set with - 1169da1bb401SStefano Zampini 1170da1bb401SStefano Zampini Contributed by Stefano Zampini 1171da1bb401SStefano Zampini 1172da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 1173da1bb401SStefano Zampini M*/ 1174b2573a8aSBarry Smith 1175da1bb401SStefano Zampini #undef __FUNCT__ 1176da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC" 11778cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 1178da1bb401SStefano Zampini { 1179da1bb401SStefano Zampini PetscErrorCode ierr; 1180da1bb401SStefano Zampini PC_BDDC *pcbddc; 1181da1bb401SStefano Zampini 1182da1bb401SStefano Zampini PetscFunctionBegin; 1183da1bb401SStefano Zampini /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 1184da1bb401SStefano Zampini ierr = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr); 1185da1bb401SStefano Zampini pc->data = (void*)pcbddc; 1186da1bb401SStefano Zampini 1187da1bb401SStefano Zampini /* create PCIS data structure */ 1188da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 1189da1bb401SStefano Zampini 1190da1bb401SStefano Zampini /* BDDC specific */ 1191674ae819SStefano Zampini pcbddc->user_primal_vertices = 0; 11920bdf917eSStefano Zampini pcbddc->NullSpace = 0; 11933972b0daSStefano Zampini pcbddc->temp_solution = 0; 1194534831adSStefano Zampini pcbddc->original_rhs = 0; 1195534831adSStefano Zampini pcbddc->local_mat = 0; 1196534831adSStefano Zampini pcbddc->ChangeOfBasisMatrix = 0; 1197674ae819SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 1198674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 1199da1bb401SStefano Zampini pcbddc->coarse_vec = 0; 1200da1bb401SStefano Zampini pcbddc->coarse_rhs = 0; 1201da1bb401SStefano Zampini pcbddc->coarse_ksp = 0; 1202da1bb401SStefano Zampini pcbddc->coarse_phi_B = 0; 1203da1bb401SStefano Zampini pcbddc->coarse_phi_D = 0; 1204*15aaf578SStefano Zampini pcbddc->coarse_psi_B = 0; 1205*15aaf578SStefano Zampini pcbddc->coarse_psi_D = 0; 1206da1bb401SStefano Zampini pcbddc->vec1_P = 0; 1207da1bb401SStefano Zampini pcbddc->vec1_R = 0; 1208da1bb401SStefano Zampini pcbddc->vec2_R = 0; 1209da1bb401SStefano Zampini pcbddc->local_auxmat1 = 0; 1210da1bb401SStefano Zampini pcbddc->local_auxmat2 = 0; 1211da1bb401SStefano Zampini pcbddc->R_to_B = 0; 1212da1bb401SStefano Zampini pcbddc->R_to_D = 0; 1213da1bb401SStefano Zampini pcbddc->ksp_D = 0; 1214da1bb401SStefano Zampini pcbddc->ksp_R = 0; 1215da1bb401SStefano Zampini pcbddc->local_primal_indices = 0; 121629622bf0SStefano Zampini pcbddc->inexact_prec_type = PETSC_FALSE; 1217da1bb401SStefano Zampini pcbddc->NeumannBoundaries = 0; 1218da1bb401SStefano Zampini pcbddc->ISForDofs = 0; 1219da1bb401SStefano Zampini pcbddc->ConstraintMatrix = 0; 1220da1bb401SStefano Zampini pcbddc->use_nnsp_true = PETSC_FALSE; 1221da1bb401SStefano Zampini pcbddc->local_primal_sizes = 0; 1222da1bb401SStefano Zampini pcbddc->local_primal_displacements = 0; 1223da1bb401SStefano Zampini pcbddc->coarse_loc_to_glob = 0; 12249d9e44b6SStefano Zampini pcbddc->dbg_flag = 0; 1225da1bb401SStefano Zampini pcbddc->coarsening_ratio = 8; 1226b76ba322SStefano Zampini pcbddc->use_exact_dirichlet = PETSC_TRUE; 12274fad6a16SStefano Zampini pcbddc->current_level = 0; 12284fad6a16SStefano Zampini pcbddc->max_levels = 1; 1229674ae819SStefano Zampini pcbddc->replicated_local_primal_indices = 0; 1230674ae819SStefano Zampini pcbddc->replicated_local_primal_values = 0; 1231da1bb401SStefano Zampini 1232674ae819SStefano Zampini /* create local graph structure */ 1233674ae819SStefano Zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 1234674ae819SStefano Zampini 1235674ae819SStefano Zampini /* scaling */ 1236674ae819SStefano Zampini pcbddc->use_deluxe_scaling = PETSC_FALSE; 1237674ae819SStefano Zampini pcbddc->work_scaling = 0; 1238da1bb401SStefano Zampini 1239da1bb401SStefano Zampini /* function pointers */ 1240da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 1241da1bb401SStefano Zampini pc->ops->applytranspose = 0; 1242da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 1243da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 1244da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 1245da1bb401SStefano Zampini pc->ops->view = 0; 1246da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 1247da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 1248da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 1249534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 1250534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 1251da1bb401SStefano Zampini 1252da1bb401SStefano Zampini /* composing function */ 1253674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 1254bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 1255bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetMaxLevels_C",PCBDDCSetMaxLevels_BDDC);CHKERRQ(ierr); 1256bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",PCBDDCSetNullSpace_BDDC);CHKERRQ(ierr); 1257bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 1258bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 1259bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 1260bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 1261bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseProblemType_C",PCBDDCSetCoarseProblemType_BDDC);CHKERRQ(ierr); 1262bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 1263bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 1264bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 1265bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 1266bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 1267da1bb401SStefano Zampini PetscFunctionReturn(0); 1268da1bb401SStefano Zampini } 12693425bc38SStefano Zampini 1270da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 1271da1bb401SStefano Zampini /* All static functions from now on */ 1272da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 127329622bf0SStefano Zampini 127429622bf0SStefano Zampini #undef __FUNCT__ 12752e8d2280SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet" 12762e8d2280SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool use) 12772e8d2280SStefano Zampini { 12782e8d2280SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 12792e8d2280SStefano Zampini 12802e8d2280SStefano Zampini PetscFunctionBegin; 12812e8d2280SStefano Zampini pcbddc->use_exact_dirichlet=use; 12822e8d2280SStefano Zampini PetscFunctionReturn(0); 12832e8d2280SStefano Zampini } 12842e8d2280SStefano Zampini 12852e8d2280SStefano Zampini #undef __FUNCT__ 12864fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel" 12874fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 12884fad6a16SStefano Zampini { 12894fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 12904fad6a16SStefano Zampini 12914fad6a16SStefano Zampini PetscFunctionBegin; 12924fad6a16SStefano Zampini pcbddc->current_level=level; 12934fad6a16SStefano Zampini PetscFunctionReturn(0); 12944fad6a16SStefano Zampini } 12953425bc38SStefano Zampini 12963b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 12970c7d97c5SJed Brown #undef __FUNCT__ 12980c7d97c5SJed Brown #define __FUNCT__ "PCBDDCCoarseSetUp" 129953cdbc3dSStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC pc) 13000c7d97c5SJed Brown { 13010c7d97c5SJed Brown PetscErrorCode ierr; 1302674ae819SStefano Zampini 13030c7d97c5SJed Brown PC_IS* pcis = (PC_IS*)(pc->data); 13040c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 13050c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 13060c7d97c5SJed Brown IS is_R_local; 130719fd82e9SBarry Smith VecType impVecType; 130819fd82e9SBarry Smith MatType impMatType; 13090c7d97c5SJed Brown PetscInt n_R=0; 13100c7d97c5SJed Brown PetscInt n_D=0; 13110c7d97c5SJed Brown PetscInt n_B=0; 13120c7d97c5SJed Brown PetscScalar zero=0.0; 13130c7d97c5SJed Brown PetscScalar one=1.0; 13140c7d97c5SJed Brown PetscScalar m_one=-1.0; 13150c7d97c5SJed Brown PetscScalar* array; 13160c7d97c5SJed Brown PetscScalar *coarse_submat_vals; 13170c7d97c5SJed Brown PetscInt *idx_R_local; 13180c7d97c5SJed Brown PetscScalar *coarsefunctions_errors; 13190c7d97c5SJed Brown PetscScalar *constraints_errors; 13200c7d97c5SJed Brown /* auxiliary indices */ 1321534831adSStefano Zampini PetscInt i,j,k; 1322e269702eSStefano Zampini /* for verbose output of bddc */ 1323e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 1324e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 1325a0ba757dSStefano Zampini /* for counting coarse dofs */ 1326534831adSStefano Zampini PetscInt n_vertices,n_constraints; 13273b03a366Sstefano_zampini PetscInt size_of_constraint; 13283b03a366Sstefano_zampini PetscInt *row_cmat_indices; 13293b03a366Sstefano_zampini PetscScalar *row_cmat_values; 1330e6872a76SStefano Zampini PetscInt *vertices; 13310c7d97c5SJed Brown 13320c7d97c5SJed Brown PetscFunctionBegin; 13330c7d97c5SJed Brown /* Set Non-overlapping dimensions */ 13340c7d97c5SJed Brown n_B = pcis->n_B; n_D = pcis->n - n_B; 1335534831adSStefano Zampini 1336534831adSStefano Zampini /* transform local matrices if needed */ 1337674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 1338e6872a76SStefano Zampini Mat change_mat_all; 1339e6872a76SStefano Zampini PetscInt *nnz,*is_indices,*temp_indices; 1340e6872a76SStefano Zampini 1341534831adSStefano Zampini ierr = PetscMalloc(pcis->n*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 1342534831adSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 13432fa5cd67SKarl Rupp for (i=0;i<n_D;i++) nnz[is_indices[i]] = 1; 1344534831adSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1345534831adSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1346534831adSStefano Zampini k=1; 1347534831adSStefano Zampini for (i=0;i<n_B;i++) { 13480298fd71SBarry Smith ierr = MatGetRow(pcbddc->ChangeOfBasisMatrix,i,&j,NULL,NULL);CHKERRQ(ierr); 1349534831adSStefano Zampini nnz[is_indices[i]]=j; 13502fa5cd67SKarl Rupp if (k < j) k = j; 13510298fd71SBarry Smith ierr = MatRestoreRow(pcbddc->ChangeOfBasisMatrix,i,&j,NULL,NULL);CHKERRQ(ierr); 1352534831adSStefano Zampini } 1353534831adSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1354534831adSStefano Zampini /* assemble change of basis matrix on the whole set of local dofs */ 1355534831adSStefano Zampini ierr = PetscMalloc(k*sizeof(PetscInt),&temp_indices);CHKERRQ(ierr); 1356534831adSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&change_mat_all);CHKERRQ(ierr); 1357534831adSStefano Zampini ierr = MatSetSizes(change_mat_all,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 1358534831adSStefano Zampini ierr = MatSetType(change_mat_all,MATSEQAIJ);CHKERRQ(ierr); 1359534831adSStefano Zampini ierr = MatSeqAIJSetPreallocation(change_mat_all,0,nnz);CHKERRQ(ierr); 1360534831adSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1361534831adSStefano Zampini for (i=0;i<n_D;i++) { 1362534831adSStefano Zampini ierr = MatSetValue(change_mat_all,is_indices[i],is_indices[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 1363534831adSStefano Zampini } 1364534831adSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1365534831adSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1366534831adSStefano Zampini for (i=0;i<n_B;i++) { 1367534831adSStefano Zampini ierr = MatGetRow(pcbddc->ChangeOfBasisMatrix,i,&j,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 13682fa5cd67SKarl Rupp for (k=0; k<j; k++) temp_indices[k]=is_indices[row_cmat_indices[k]]; 1369534831adSStefano Zampini ierr = MatSetValues(change_mat_all,1,&is_indices[i],j,temp_indices,row_cmat_values,INSERT_VALUES);CHKERRQ(ierr); 1370534831adSStefano Zampini ierr = MatRestoreRow(pcbddc->ChangeOfBasisMatrix,i,&j,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 1371534831adSStefano Zampini } 1372534831adSStefano Zampini ierr = MatAssemblyBegin(change_mat_all,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1373534831adSStefano Zampini ierr = MatAssemblyEnd(change_mat_all,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13745ce978abSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ? PtAP not provided */ 13755ce978abSStefano Zampini ierr = MatGetBlockSize(matis->A,&i);CHKERRQ(ierr); 13765ce978abSStefano Zampini if (i==1) { 1377534831adSStefano Zampini ierr = MatPtAP(matis->A,change_mat_all,MAT_INITIAL_MATRIX,1.0,&pcbddc->local_mat);CHKERRQ(ierr); 13785ce978abSStefano Zampini } else { 13795ce978abSStefano Zampini Mat work_mat; 13805ce978abSStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 13815ce978abSStefano Zampini ierr = MatPtAP(work_mat,change_mat_all,MAT_INITIAL_MATRIX,1.0,&pcbddc->local_mat);CHKERRQ(ierr); 13825ce978abSStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 13835ce978abSStefano Zampini } 1384534831adSStefano Zampini ierr = MatDestroy(&change_mat_all);CHKERRQ(ierr); 1385534831adSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 1386534831adSStefano Zampini ierr = PetscFree(temp_indices);CHKERRQ(ierr); 1387534831adSStefano Zampini } else { 1388534831adSStefano Zampini /* without change of basis, the local matrix is unchanged */ 1389534831adSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 1390534831adSStefano Zampini pcbddc->local_mat = matis->A; 1391534831adSStefano Zampini } 1392*15aaf578SStefano Zampini /* need to rebuild PCIS matrices during SNES or TS -> TODO move this to PCIS code */ 1393*15aaf578SStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 1394*15aaf578SStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 1395*15aaf578SStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 1396*15aaf578SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 1397*15aaf578SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 1398*15aaf578SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 1399674ae819SStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 1400674ae819SStefano Zampini if (pcbddc->NullSpace && pcbddc->use_change_of_basis) { 1401674ae819SStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 14020bdf917eSStefano Zampini } 1403a0ba757dSStefano Zampini 1404e6872a76SStefano Zampini /* Set types for local objects needed by BDDC precondtioner */ 1405e6872a76SStefano Zampini impMatType = MATSEQDENSE; 1406e6872a76SStefano Zampini impVecType = VECSEQ; 1407e6872a76SStefano Zampini /* get vertex indices from constraint matrix */ 1408e6872a76SStefano Zampini ierr = PCBDDCGetPrimalVerticesLocalIdx(pc,&n_vertices,&vertices);CHKERRQ(ierr); 1409e6872a76SStefano Zampini /* Set number of constraints */ 1410e6872a76SStefano Zampini n_constraints = pcbddc->local_primal_size-n_vertices; 14110c7d97c5SJed Brown /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 14120c7d97c5SJed Brown ierr = VecSet(pcis->vec1_N,one);CHKERRQ(ierr); 14130c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14142fa5cd67SKarl Rupp for (i=0;i<n_vertices;i++) array[vertices[i]] = zero; 14153b03a366Sstefano_zampini ierr = PetscMalloc((pcis->n-n_vertices)*sizeof(PetscInt),&idx_R_local);CHKERRQ(ierr); 14162fa5cd67SKarl Rupp for (i=0, n_R=0; i<pcis->n; i++) { 14172fa5cd67SKarl Rupp if (array[i] == one) { 14182fa5cd67SKarl Rupp idx_R_local[n_R] = i; 14192fa5cd67SKarl Rupp n_R++; 14202fa5cd67SKarl Rupp } 14212fa5cd67SKarl Rupp } 14220c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1423e6872a76SStefano Zampini ierr = PetscFree(vertices);CHKERRQ(ierr); 1424e269702eSStefano Zampini if (dbg_flag) { 14250c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 14260c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14270c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 14280c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 14293b03a366Sstefano_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); 1430534831adSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"pcbddc->n_vertices = %d, pcbddc->n_constraints = %d\n",pcbddc->n_vertices,pcbddc->n_constraints);CHKERRQ(ierr); 14310c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14320c7d97c5SJed Brown } 1433534831adSStefano Zampini 14340c7d97c5SJed Brown /* Allocate needed vectors */ 1435534831adSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 14363972b0daSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 14370c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_D,&pcbddc->vec4_D);CHKERRQ(ierr); 14380c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_R);CHKERRQ(ierr); 14390c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_R,n_R,n_R);CHKERRQ(ierr); 14400c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 1441d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 14420c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_P);CHKERRQ(ierr); 14430c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_P,pcbddc->local_primal_size,pcbddc->local_primal_size);CHKERRQ(ierr); 14440c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 14450c7d97c5SJed Brown 14460c7d97c5SJed Brown /* Creating some index sets needed */ 14470c7d97c5SJed Brown /* For submatrices */ 1448da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n_R,idx_R_local,PETSC_OWN_POINTER,&is_R_local);CHKERRQ(ierr); 1449da1bb401SStefano Zampini 14500c7d97c5SJed Brown /* For VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 14510c7d97c5SJed Brown { 1452e6872a76SStefano Zampini IS is_aux1,is_aux2; 14530c7d97c5SJed Brown PetscInt *aux_array1; 14540c7d97c5SJed Brown PetscInt *aux_array2; 14552e8d2280SStefano Zampini PetscInt *idx_I_local; 14560c7d97c5SJed Brown 14573b03a366Sstefano_zampini ierr = PetscMalloc((pcis->n_B-n_vertices)*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 14583b03a366Sstefano_zampini ierr = PetscMalloc((pcis->n_B-n_vertices)*sizeof(PetscInt),&aux_array2);CHKERRQ(ierr); 14590c7d97c5SJed Brown 14602e8d2280SStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&idx_I_local);CHKERRQ(ierr); 14610c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14622fa5cd67SKarl Rupp for (i=0; i<n_D; i++) array[idx_I_local[i]] = 0; 14632e8d2280SStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&idx_I_local);CHKERRQ(ierr); 14642fa5cd67SKarl Rupp for (i=0, j=0; i<n_R; i++) { 14652fa5cd67SKarl Rupp if (array[idx_R_local[i]] == one) { 14662fa5cd67SKarl Rupp aux_array1[j] = i; 14672fa5cd67SKarl Rupp j++; 14682fa5cd67SKarl Rupp } 14692fa5cd67SKarl Rupp } 14700c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1471da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 14722e8d2280SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14732e8d2280SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14740c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 14752fa5cd67SKarl Rupp for (i=0, j=0; i<n_B; i++) { 14762fa5cd67SKarl Rupp if (array[i] == one) { 14772fa5cd67SKarl Rupp aux_array2[j] = i; j++; 14782fa5cd67SKarl Rupp } 14792fa5cd67SKarl Rupp } 14803828260eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1481da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_COPY_VALUES,&is_aux2);CHKERRQ(ierr); 14820c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 14830c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 14840c7d97c5SJed Brown ierr = PetscFree(aux_array2);CHKERRQ(ierr); 14850c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 14860c7d97c5SJed Brown ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 14870c7d97c5SJed Brown 148829622bf0SStefano Zampini if (pcbddc->inexact_prec_type || dbg_flag ) { 14890c7d97c5SJed Brown ierr = PetscMalloc(n_D*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 14900c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14912fa5cd67SKarl Rupp for (i=0, j=0; i<n_R; i++) { 14922fa5cd67SKarl Rupp if (array[idx_R_local[i]] == zero) { 14932fa5cd67SKarl Rupp aux_array1[j] = i; 14942fa5cd67SKarl Rupp j++; 14952fa5cd67SKarl Rupp } 14962fa5cd67SKarl Rupp } 14970c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1498da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 14990c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 15000c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 15010c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 15020c7d97c5SJed Brown } 15030c7d97c5SJed Brown } 15040c7d97c5SJed Brown 15050c7d97c5SJed Brown /* Creating PC contexts for local Dirichlet and Neumann problems */ 15060c7d97c5SJed Brown { 15070c7d97c5SJed Brown Mat A_RR; 150853cdbc3dSStefano Zampini PC pc_temp; 1509674ae819SStefano Zampini MatStructure matstruct; 1510674ae819SStefano Zampini /* Matrix for Dirichlet problem is A_II */ 1511674ae819SStefano Zampini /* HACK (TODO) A_II can be changed between nonlinear iterations */ 1512e6872a76SStefano Zampini if (pc->setupcalled) { /* we dont need to rebuild dirichlet problem the first time we build BDDC */ 1513674ae819SStefano Zampini ierr = PCGetOperators(pc,NULL,NULL,&matstruct);CHKERRQ(ierr); 1514674ae819SStefano Zampini if (matstruct == SAME_NONZERO_PATTERN) { 1515e6872a76SStefano Zampini ierr = MatGetSubMatrix(matis->A,pcis->is_I_local,pcis->is_I_local,MAT_REUSE_MATRIX,&pcis->A_II);CHKERRQ(ierr); 1516674ae819SStefano Zampini } else { 1517674ae819SStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 1518e6872a76SStefano Zampini ierr = MatGetSubMatrix(matis->A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_II);CHKERRQ(ierr); 1519e6872a76SStefano Zampini } 1520674ae819SStefano Zampini } 152153cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 152253cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 152353cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II,SAME_PRECONDITIONER);CHKERRQ(ierr); 152453cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 1525da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,"dirichlet_");CHKERRQ(ierr); 15260c7d97c5SJed Brown /* default */ 152753cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 152853cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 15290c7d97c5SJed Brown /* Allow user's customization */ 153053cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 1531950d796eSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero */ 1532950d796eSStefano Zampini if (!n_D) { 15332e8d2280SStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 1534950d796eSStefano Zampini } 153553cdbc3dSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 153653cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 15373972b0daSStefano Zampini /* set ksp_D into pcis data */ 15383972b0daSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 15393972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 15403972b0daSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 15410c7d97c5SJed Brown /* Matrix for Neumann problem is A_RR -> we need to create it */ 1542534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_R_local,is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 154353cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 154453cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 154553cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR,SAME_PRECONDITIONER);CHKERRQ(ierr); 154653cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 1547da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,"neumann_");CHKERRQ(ierr); 15480c7d97c5SJed Brown /* default */ 154953cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 155053cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 15510c7d97c5SJed Brown /* Allow user's customization */ 155253cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 1553950d796eSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero */ 1554674ae819SStefano Zampini if (!n_R) { 15552e8d2280SStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 1556950d796eSStefano Zampini } 155753cdbc3dSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 155853cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 1559674ae819SStefano Zampini /* check Dirichlet and Neumann solvers and adapt them if a nullspace correction is needed */ 1560b76ba322SStefano Zampini { 15610c7d97c5SJed Brown Vec temp_vec; 1562b76ba322SStefano Zampini PetscReal value; 1563e6872a76SStefano Zampini PetscInt use_exact,use_exact_reduced; 15640c7d97c5SJed Brown 1565a0ba757dSStefano Zampini ierr = VecDuplicate(pcis->vec1_D,&temp_vec);CHKERRQ(ierr); 15660298fd71SBarry Smith ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 1567a0ba757dSStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 1568a0ba757dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,temp_vec);CHKERRQ(ierr); 1569a0ba757dSStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcis->vec1_D);CHKERRQ(ierr); 1570a0ba757dSStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 157129622bf0SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1572b76ba322SStefano Zampini use_exact = 1; 15732fa5cd67SKarl Rupp if (PetscAbsReal(value) > 1.e-4) use_exact = 0; 1574ce94432eSBarry Smith ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_INT,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1575e6872a76SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,(PetscBool)use_exact_reduced);CHKERRQ(ierr); 1576b76ba322SStefano Zampini if (dbg_flag) { 1577a0ba757dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1578a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1579a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Checking solution of Dirichlet and Neumann problems\n");CHKERRQ(ierr); 1580a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Dirichlet solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 1581674ae819SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 158229622bf0SStefano Zampini } 1583674ae819SStefano Zampini if (n_D && pcbddc->NullSpace && !use_exact_reduced && !pcbddc->inexact_prec_type) { 1584674ae819SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,pcis->is_I_local); 158529622bf0SStefano Zampini } 1586d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&temp_vec);CHKERRQ(ierr); 15870298fd71SBarry Smith ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 1588d49ef151SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 1589d49ef151SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,temp_vec);CHKERRQ(ierr); 1590d49ef151SStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 1591d49ef151SStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 1592e269702eSStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 159329622bf0SStefano Zampini use_exact = 1; 15942fa5cd67SKarl Rupp if (PetscAbsReal(value) > 1.e-4) use_exact = 0; 1595ce94432eSBarry Smith ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_INT,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 159629622bf0SStefano Zampini if (dbg_flag) { 15970c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Neumann solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 1598d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 15990c7d97c5SJed Brown } 1600e6872a76SStefano Zampini if (n_R && pcbddc->NullSpace && !use_exact_reduced) { /* is it the right logic? */ 1601674ae819SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,is_R_local); 160229622bf0SStefano Zampini } 1603b76ba322SStefano Zampini } 16040c7d97c5SJed Brown /* free Neumann problem's matrix */ 16050c7d97c5SJed Brown ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 16060c7d97c5SJed Brown } 16070c7d97c5SJed Brown 16080c7d97c5SJed Brown /* Assemble all remaining stuff needed to apply BDDC */ 16090c7d97c5SJed Brown { 16100c7d97c5SJed Brown Mat A_RV,A_VR,A_VV; 16110bdf917eSStefano Zampini Mat M1; 16120c7d97c5SJed Brown Mat C_CR; 16133b03a366Sstefano_zampini Mat AUXMAT; 16140c7d97c5SJed Brown Vec vec1_C; 16150c7d97c5SJed Brown Vec vec2_C; 16160c7d97c5SJed Brown Vec vec1_V; 16170c7d97c5SJed Brown Vec vec2_V; 1618e6872a76SStefano Zampini IS is_C_local,is_V_local,is_aux1; 1619e6872a76SStefano Zampini ISLocalToGlobalMapping BtoNmap; 16200c7d97c5SJed Brown PetscInt *nnz; 1621e6872a76SStefano Zampini PetscInt *idx_V_B; 16220c7d97c5SJed Brown PetscInt *auxindices; 162353cdbc3dSStefano Zampini PetscInt index; 16240c7d97c5SJed Brown PetscScalar* array2; 16250c7d97c5SJed Brown MatFactorInfo matinfo; 1626*15aaf578SStefano Zampini PetscBool setsym=PETSC_FALSE,issym=PETSC_FALSE; 16270c7d97c5SJed Brown 16280c7d97c5SJed Brown /* Allocating some extra storage just to be safe */ 16290c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 16300c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&auxindices);CHKERRQ(ierr); 16312fa5cd67SKarl Rupp for (i=0;i<pcis->n;i++) auxindices[i]=i; 16320c7d97c5SJed Brown 1633e6872a76SStefano Zampini ierr = PCBDDCGetPrimalVerticesLocalIdx(pc,&n_vertices,&vertices);CHKERRQ(ierr); 1634e6872a76SStefano Zampini /* vertices in boundary numbering */ 1635e6872a76SStefano Zampini ierr = PetscMalloc(n_vertices*sizeof(PetscInt),&idx_V_B);CHKERRQ(ierr); 1636e6872a76SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_B_local,&BtoNmap);CHKERRQ(ierr); 1637e6872a76SStefano Zampini ierr = ISGlobalToLocalMappingApply(BtoNmap,IS_GTOLM_DROP,n_vertices,vertices,&i,idx_V_B);CHKERRQ(ierr); 1638e6872a76SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&BtoNmap);CHKERRQ(ierr); 1639e6872a76SStefano Zampini if (i != n_vertices) { 1640e6872a76SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",n_vertices,i); 1641e6872a76SStefano Zampini } 1642e6872a76SStefano Zampini 16430c7d97c5SJed Brown /* some work vectors on vertices and/or constraints */ 16443b03a366Sstefano_zampini if (n_vertices) { 16450c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_V);CHKERRQ(ierr); 16463b03a366Sstefano_zampini ierr = VecSetSizes(vec1_V,n_vertices,n_vertices);CHKERRQ(ierr); 16470c7d97c5SJed Brown ierr = VecSetType(vec1_V,impVecType);CHKERRQ(ierr); 16480c7d97c5SJed Brown ierr = VecDuplicate(vec1_V,&vec2_V);CHKERRQ(ierr); 16490c7d97c5SJed Brown } 1650534831adSStefano Zampini if (n_constraints) { 16510c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_C);CHKERRQ(ierr); 1652534831adSStefano Zampini ierr = VecSetSizes(vec1_C,n_constraints,n_constraints);CHKERRQ(ierr); 16530c7d97c5SJed Brown ierr = VecSetType(vec1_C,impVecType);CHKERRQ(ierr); 16540c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&vec2_C);CHKERRQ(ierr); 16550c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&pcbddc->vec1_C);CHKERRQ(ierr); 16560c7d97c5SJed Brown } 16570c7d97c5SJed Brown /* Precompute stuffs needed for preprocessing and application of BDDC*/ 16583b03a366Sstefano_zampini if (n_constraints) { 16590c7d97c5SJed Brown ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->local_auxmat2);CHKERRQ(ierr); 16603b03a366Sstefano_zampini ierr = MatSetSizes(pcbddc->local_auxmat2,n_R,n_constraints,n_R,n_constraints);CHKERRQ(ierr); 16610c7d97c5SJed Brown ierr = MatSetType(pcbddc->local_auxmat2,impMatType);CHKERRQ(ierr); 16620298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(pcbddc->local_auxmat2,NULL);CHKERRQ(ierr); 16630c7d97c5SJed Brown 166457a90decSStefano Zampini /* Create Constraint matrix on R nodes: C_{CR} */ 1665e6872a76SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_C_local);CHKERRQ(ierr); 166657a90decSStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_C_local,is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 166757a90decSStefano Zampini ierr = ISDestroy(&is_C_local);CHKERRQ(ierr); 166857a90decSStefano Zampini 16690c7d97c5SJed Brown /* Assemble local_auxmat2 = - A_{RR}^{-1} C^T_{CR} needed by BDDC application */ 16703b03a366Sstefano_zampini for (i=0;i<n_constraints;i++) { 16713b03a366Sstefano_zampini ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 16723b03a366Sstefano_zampini /* Get row of constraint matrix in R numbering */ 167357a90decSStefano Zampini ierr = VecGetArray(pcbddc->vec1_R,&array);CHKERRQ(ierr); 167457a90decSStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 16752fa5cd67SKarl Rupp for (j=0;j<size_of_constraint;j++) array[row_cmat_indices[j]] = -row_cmat_values[j]; 167657a90decSStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 167757a90decSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_R,&array);CHKERRQ(ierr); 16782fa5cd67SKarl Rupp 16793b03a366Sstefano_zampini /* Solve for row of constraint matrix in R numbering */ 168053cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 16812fa5cd67SKarl Rupp 16823b03a366Sstefano_zampini /* Set values */ 16830c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 16843b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->local_auxmat2,n_R,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 16850c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 16860c7d97c5SJed Brown } 16870c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16880c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16890c7d97c5SJed Brown 16900c7d97c5SJed Brown /* Assemble AUXMAT = ( LUFactor )( -C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 16910c7d97c5SJed Brown ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AUXMAT);CHKERRQ(ierr); 1692d49ef151SStefano Zampini ierr = MatFactorInfoInitialize(&matinfo);CHKERRQ(ierr); 16933b03a366Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,0,1,&is_aux1);CHKERRQ(ierr); 16940c7d97c5SJed Brown ierr = MatLUFactor(AUXMAT,is_aux1,is_aux1,&matinfo);CHKERRQ(ierr); 16950c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 16960c7d97c5SJed Brown 16973b03a366Sstefano_zampini /* Assemble explicitly M1 = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} needed in preproc */ 1698d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M1);CHKERRQ(ierr); 16993b03a366Sstefano_zampini ierr = MatSetSizes(M1,n_constraints,n_constraints,n_constraints,n_constraints);CHKERRQ(ierr); 17000c7d97c5SJed Brown ierr = MatSetType(M1,impMatType);CHKERRQ(ierr); 17010298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(M1,NULL);CHKERRQ(ierr); 17023b03a366Sstefano_zampini for (i=0;i<n_constraints;i++) { 17030c7d97c5SJed Brown ierr = VecSet(vec1_C,zero);CHKERRQ(ierr); 17040c7d97c5SJed Brown ierr = VecSetValue(vec1_C,i,one,INSERT_VALUES);CHKERRQ(ierr); 17050c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_C);CHKERRQ(ierr); 17060c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_C);CHKERRQ(ierr); 17070c7d97c5SJed Brown ierr = MatSolve(AUXMAT,vec1_C,vec2_C);CHKERRQ(ierr); 17080c7d97c5SJed Brown ierr = VecScale(vec2_C,m_one);CHKERRQ(ierr); 17090c7d97c5SJed Brown ierr = VecGetArray(vec2_C,&array);CHKERRQ(ierr); 17103b03a366Sstefano_zampini ierr = MatSetValues(M1,n_constraints,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 17110c7d97c5SJed Brown ierr = VecRestoreArray(vec2_C,&array);CHKERRQ(ierr); 17120c7d97c5SJed Brown } 17130c7d97c5SJed Brown ierr = MatAssemblyBegin(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17140c7d97c5SJed Brown ierr = MatAssemblyEnd(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17150c7d97c5SJed Brown ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 17160c7d97c5SJed Brown /* Assemble local_auxmat1 = M1*C_{CR} needed by BDDC application in KSP and in preproc */ 17170c7d97c5SJed Brown ierr = MatMatMult(M1,C_CR,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 17180c7d97c5SJed Brown 17190c7d97c5SJed Brown } 17200c7d97c5SJed Brown 17210c7d97c5SJed Brown /* Get submatrices from subdomain matrix */ 17223b03a366Sstefano_zampini if (n_vertices) { 1723*15aaf578SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n_vertices,vertices,PETSC_COPY_VALUES,&is_V_local);CHKERRQ(ierr); 1724534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_R_local,is_V_local,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 1725534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_V_local,is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 1726534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_V_local,is_V_local,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 1727*15aaf578SStefano Zampini ierr = ISDestroy(&is_V_local);CHKERRQ(ierr); 17280c7d97c5SJed Brown } 17290c7d97c5SJed Brown 17300c7d97c5SJed Brown /* Matrix of coarse basis functions (local) */ 1731d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 17320c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 17330c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_B,impMatType);CHKERRQ(ierr); 17340298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_phi_B,NULL);CHKERRQ(ierr); 173529622bf0SStefano Zampini if (pcbddc->inexact_prec_type || dbg_flag ) { 1736d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 17370c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 17380c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_D,impMatType);CHKERRQ(ierr); 17390298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_phi_D,NULL);CHKERRQ(ierr); 17400c7d97c5SJed Brown } 17410c7d97c5SJed Brown 1742e269702eSStefano Zampini if (dbg_flag) { 1743*15aaf578SStefano Zampini ierr = PetscMalloc(2*pcbddc->local_primal_size*sizeof(PetscScalar),&coarsefunctions_errors);CHKERRQ(ierr); 1744*15aaf578SStefano Zampini ierr = PetscMalloc(2*pcbddc->local_primal_size*sizeof(PetscScalar),&constraints_errors);CHKERRQ(ierr); 17450c7d97c5SJed Brown } 17463b03a366Sstefano_zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 17470c7d97c5SJed Brown ierr = PetscMalloc ((pcbddc->local_primal_size)*(pcbddc->local_primal_size)*sizeof(PetscScalar),&coarse_submat_vals);CHKERRQ(ierr); 17480c7d97c5SJed Brown 17490c7d97c5SJed Brown /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 17503b03a366Sstefano_zampini for (i=0;i<n_vertices;i++){ 17510c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 17520c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 17530c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 17540c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 17550c7d97c5SJed Brown /* solution of saddle point problem */ 17560bdf917eSStefano Zampini ierr = MatMult(A_RV,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 17570bdf917eSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 17580c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_R,m_one);CHKERRQ(ierr); 17593b03a366Sstefano_zampini if (n_constraints) { 17600c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec1_R,vec1_C);CHKERRQ(ierr); 17610c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 17620c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 17630c7d97c5SJed Brown } 17640c7d97c5SJed Brown ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); 17650c7d97c5SJed Brown ierr = MatMultAdd(A_VV,vec1_V,vec2_V,vec2_V);CHKERRQ(ierr); 17660c7d97c5SJed Brown 17670c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 17680c7d97c5SJed Brown /* coarse basis functions */ 17690c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 17700c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17710c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17720c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 17733b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 17740c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 17750c7d97c5SJed Brown ierr = MatSetValue(pcbddc->coarse_phi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 177629622bf0SStefano Zampini if ( pcbddc->inexact_prec_type || dbg_flag ) { 17770c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17780c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17790c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 17803b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 17810c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 17820c7d97c5SJed Brown } 17830c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 17840c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 17852fa5cd67SKarl Rupp for (j=0; j<n_vertices; j++) coarse_submat_vals[i*pcbddc->local_primal_size+j] = array[j]; /* WARNING -> column major ordering */ 17860c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 17873b03a366Sstefano_zampini if (n_constraints) { 17880c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 17892fa5cd67SKarl 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 */ 17900c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 17910c7d97c5SJed Brown } 17920c7d97c5SJed Brown 1793e269702eSStefano Zampini if ( dbg_flag ) { 17940c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 1795d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 17960c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 17970c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 17982fa5cd67SKarl Rupp for (j=0;j<n_R;j++) array[idx_R_local[j]] = array2[j]; 17993b03a366Sstefano_zampini array[ vertices[i] ] = one; 18000c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 18010c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 18020c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers (i.e. primal nodes) */ 1803d49ef151SStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 18040c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 18050c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 18062fa5cd67SKarl Rupp for (j=0;j<n_vertices;j++) array2[j]=array[j]; 18070c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 18083b03a366Sstefano_zampini if (n_constraints) { 18090c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 18102fa5cd67SKarl Rupp for (j=0;j<n_constraints;j++) array2[j+n_vertices]=array[j]; 18110c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 18120c7d97c5SJed Brown } 18130c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 18140c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_P,m_one);CHKERRQ(ierr); 18150c7d97c5SJed Brown /* check saddle point solution */ 1816534831adSStefano Zampini ierr = MatMult(pcbddc->local_mat,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 18173b03a366Sstefano_zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 18183b03a366Sstefano_zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[i]);CHKERRQ(ierr); 18193b03a366Sstefano_zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 18200c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 18213b03a366Sstefano_zampini array[i]=array[i]+m_one; /* shift by the identity matrix */ 18220c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 18233b03a366Sstefano_zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[i]);CHKERRQ(ierr); 18240c7d97c5SJed Brown } 18250c7d97c5SJed Brown } 18260c7d97c5SJed Brown 18273b03a366Sstefano_zampini for (i=0;i<n_constraints;i++){ 1828d49ef151SStefano Zampini ierr = VecSet(vec2_C,zero);CHKERRQ(ierr); 18290c7d97c5SJed Brown ierr = VecSetValue(vec2_C,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 18300c7d97c5SJed Brown ierr = VecAssemblyBegin(vec2_C);CHKERRQ(ierr); 18310c7d97c5SJed Brown ierr = VecAssemblyEnd(vec2_C);CHKERRQ(ierr); 18320c7d97c5SJed Brown /* solution of saddle point problem */ 18330c7d97c5SJed Brown ierr = MatMult(M1,vec2_C,vec1_C);CHKERRQ(ierr); 18340c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 18350c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 18363b03a366Sstefano_zampini if (n_vertices) { ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); } 18370c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 18380c7d97c5SJed Brown /* coarse basis functions */ 18393b03a366Sstefano_zampini index=i+n_vertices; 18400c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 18410c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18420c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18430c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 184453cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 18450c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 184629622bf0SStefano Zampini if ( pcbddc->inexact_prec_type || dbg_flag ) { 18470c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18480c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18490c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 185053cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 18510c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 18520c7d97c5SJed Brown } 18530c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 18543b03a366Sstefano_zampini if (n_vertices) { 18550c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 18562fa5cd67SKarl Rupp for (j=0; j<n_vertices; j++) coarse_submat_vals[index*pcbddc->local_primal_size+j]=array[j]; /* WARNING -> column major ordering */ 18570c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 18580c7d97c5SJed Brown } 18590c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 18602fa5cd67SKarl 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 */ 18610c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 18620c7d97c5SJed Brown 1863e269702eSStefano Zampini if ( dbg_flag ) { 18640c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 186553cdbc3dSStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 18660c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 18670c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 18682fa5cd67SKarl Rupp for (j=0;j<n_R;j++) array[idx_R_local[j]] = array2[j]; 18690c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 18700c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 18710c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers */ 187253cdbc3dSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 18730c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 18743b03a366Sstefano_zampini if ( n_vertices) { 18750c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 18762fa5cd67SKarl Rupp for (j=0;j<n_vertices;j++) array2[j]=-array[j]; 18770c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 18780c7d97c5SJed Brown } 18790c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 18803b03a366Sstefano_zampini for (j=0;j<n_constraints;j++) {array2[j+n_vertices]=-array[j];} 18810c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 18820c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 18833972b0daSStefano Zampini /* check saddle point solution */ 1884534831adSStefano Zampini ierr = MatMult(pcbddc->local_mat,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 18853b03a366Sstefano_zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 188653cdbc3dSStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[index]);CHKERRQ(ierr); 18873b03a366Sstefano_zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 18880c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 188953cdbc3dSStefano Zampini array[index]=array[index]+m_one; /* shift by the identity matrix */ 18900c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 189153cdbc3dSStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[index]);CHKERRQ(ierr); 18920c7d97c5SJed Brown } 18930c7d97c5SJed Brown } 18940c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18950c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 189629622bf0SStefano Zampini if ( pcbddc->inexact_prec_type || dbg_flag ) { 18970c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18980c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18990c7d97c5SJed Brown } 1900*15aaf578SStefano Zampini /* compute other basis functions for non-symmetric problems */ 1901*15aaf578SStefano Zampini ierr = MatIsSymmetricKnown(pc->pmat,&setsym,&issym);CHKERRQ(ierr); 1902*15aaf578SStefano Zampini if ( !setsym || (setsym && !issym) ) { 1903*15aaf578SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 1904*15aaf578SStefano Zampini ierr = MatSetSizes(pcbddc->coarse_psi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 1905*15aaf578SStefano Zampini ierr = MatSetType(pcbddc->coarse_psi_B,impMatType);CHKERRQ(ierr); 1906*15aaf578SStefano Zampini ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_psi_B,NULL);CHKERRQ(ierr); 1907*15aaf578SStefano Zampini if (pcbddc->inexact_prec_type || dbg_flag ) { 1908*15aaf578SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1909*15aaf578SStefano Zampini ierr = MatSetSizes(pcbddc->coarse_psi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 1910*15aaf578SStefano Zampini ierr = MatSetType(pcbddc->coarse_psi_D,impMatType);CHKERRQ(ierr); 1911*15aaf578SStefano Zampini ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_psi_D,NULL);CHKERRQ(ierr); 1912*15aaf578SStefano Zampini } 1913*15aaf578SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 1914*15aaf578SStefano Zampini if (n_constraints) { 1915*15aaf578SStefano Zampini ierr = VecSet(vec1_C,zero);CHKERRQ(ierr); 1916*15aaf578SStefano Zampini ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 1917*15aaf578SStefano Zampini for (j=0;j<n_constraints;j++) { 1918*15aaf578SStefano Zampini array[j]=coarse_submat_vals[(j+n_vertices)*pcbddc->local_primal_size+i]; 1919*15aaf578SStefano Zampini } 1920*15aaf578SStefano Zampini ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 1921*15aaf578SStefano Zampini } 1922*15aaf578SStefano Zampini if (i<n_vertices) { 1923*15aaf578SStefano Zampini ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 1924*15aaf578SStefano Zampini ierr = VecSetValue(vec1_V,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 1925*15aaf578SStefano Zampini ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 1926*15aaf578SStefano Zampini ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 1927*15aaf578SStefano Zampini ierr = MatMultTranspose(A_VR,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 1928*15aaf578SStefano Zampini if (n_constraints) { 1929*15aaf578SStefano Zampini ierr = MatMultTransposeAdd(C_CR,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 1930*15aaf578SStefano Zampini } 1931*15aaf578SStefano Zampini } else { 1932*15aaf578SStefano Zampini ierr = MatMultTranspose(C_CR,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 1933*15aaf578SStefano Zampini } 1934*15aaf578SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 1935*15aaf578SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1936*15aaf578SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1937*15aaf578SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1938*15aaf578SStefano Zampini ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1939*15aaf578SStefano Zampini ierr = MatSetValues(pcbddc->coarse_psi_B,n_B,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 1940*15aaf578SStefano Zampini ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1941*15aaf578SStefano Zampini if (i<n_vertices) { 1942*15aaf578SStefano Zampini ierr = MatSetValue(pcbddc->coarse_psi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 1943*15aaf578SStefano Zampini } 1944*15aaf578SStefano Zampini if ( pcbddc->inexact_prec_type || dbg_flag ) { 1945*15aaf578SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1946*15aaf578SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1947*15aaf578SStefano Zampini ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 1948*15aaf578SStefano Zampini ierr = MatSetValues(pcbddc->coarse_psi_D,n_D,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 1949*15aaf578SStefano Zampini ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 1950*15aaf578SStefano Zampini } 1951*15aaf578SStefano Zampini 1952*15aaf578SStefano Zampini if ( dbg_flag ) { 1953*15aaf578SStefano Zampini /* assemble subdomain vector on nodes */ 1954*15aaf578SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 1955*15aaf578SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1956*15aaf578SStefano Zampini ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 1957*15aaf578SStefano Zampini for (j=0;j<n_R;j++) array[idx_R_local[j]] = array2[j]; 1958*15aaf578SStefano Zampini if (i<n_vertices) array[vertices[i]] = one; 1959*15aaf578SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 1960*15aaf578SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1961*15aaf578SStefano Zampini /* assemble subdomain vector of lagrange multipliers */ 1962*15aaf578SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 1963*15aaf578SStefano Zampini for (j=0;j<pcbddc->local_primal_size;j++) { 1964*15aaf578SStefano Zampini array[j]=-coarse_submat_vals[j*pcbddc->local_primal_size+i]; 1965*15aaf578SStefano Zampini } 1966*15aaf578SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 1967*15aaf578SStefano Zampini /* check saddle point solution */ 1968*15aaf578SStefano Zampini ierr = MatMultTranspose(pcbddc->local_mat,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 1969*15aaf578SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 1970*15aaf578SStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[i+pcbddc->local_primal_size]);CHKERRQ(ierr); 1971*15aaf578SStefano Zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 1972*15aaf578SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 1973*15aaf578SStefano Zampini array[i]=array[i]+m_one; /* shift by the identity matrix */ 1974*15aaf578SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 1975*15aaf578SStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[i+pcbddc->local_primal_size]);CHKERRQ(ierr); 1976*15aaf578SStefano Zampini } 1977*15aaf578SStefano Zampini } 1978*15aaf578SStefano Zampini ierr = MatAssemblyBegin(pcbddc->coarse_psi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1979*15aaf578SStefano Zampini ierr = MatAssemblyEnd(pcbddc->coarse_psi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1980*15aaf578SStefano Zampini if ( pcbddc->inexact_prec_type || dbg_flag ) { 1981*15aaf578SStefano Zampini ierr = MatAssemblyBegin(pcbddc->coarse_psi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1982*15aaf578SStefano Zampini ierr = MatAssemblyEnd(pcbddc->coarse_psi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1983*15aaf578SStefano Zampini } 1984*15aaf578SStefano Zampini } 1985*15aaf578SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 19860c7d97c5SJed Brown /* Checking coarse_sub_mat and coarse basis functios */ 1987*15aaf578SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 1988*15aaf578SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 19899d2fce94SStefano Zampini if (dbg_flag) { 19900c7d97c5SJed Brown Mat coarse_sub_mat; 19910c7d97c5SJed Brown Mat TM1,TM2,TM3,TM4; 1992*15aaf578SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 1993*15aaf578SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 1994*15aaf578SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 199519fd82e9SBarry Smith MatType checkmattype=MATSEQAIJ; 19960c7d97c5SJed Brown PetscScalar value; 19970c7d97c5SJed Brown 1998c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 1999c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 2000c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 2001c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 2002c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 2003c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 2004*15aaf578SStefano Zampini if (pcbddc->coarse_psi_B) { 2005*15aaf578SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 2006*15aaf578SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 2007*15aaf578SStefano Zampini } 2008c042a7c3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 20090c7d97c5SJed Brown 20100c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 20110c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Check coarse sub mat and local basis functions\n");CHKERRQ(ierr); 20120c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2013*15aaf578SStefano Zampini if (pcbddc->coarse_psi_B) { 2014*15aaf578SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 2015*15aaf578SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 2016*15aaf578SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 2017*15aaf578SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 2018*15aaf578SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 2019*15aaf578SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 2020*15aaf578SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 2021*15aaf578SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 2022*15aaf578SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 2023*15aaf578SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 2024*15aaf578SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 2025*15aaf578SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 2026*15aaf578SStefano Zampini } else { 202753cdbc3dSStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 202853cdbc3dSStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 202953cdbc3dSStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 2030c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 203153cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 203253cdbc3dSStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 2033c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 203453cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 2035*15aaf578SStefano Zampini } 203653cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 203753cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 203853cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 2039*15aaf578SStefano Zampini ierr = MatConvert(TM1,MATSEQDENSE,MAT_REUSE_MATRIX,&TM1);CHKERRQ(ierr); 2040*15aaf578SStefano Zampini ierr = MatAXPY(TM1,m_one,coarse_sub_mat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 204153cdbc3dSStefano Zampini ierr = MatNorm(TM1,NORM_INFINITY,&value);CHKERRQ(ierr); 20420c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"----------------------------------\n");CHKERRQ(ierr); 20430c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d \n",PetscGlobalRank);CHKERRQ(ierr); 20440c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"matrix error = % 1.14e\n",value);CHKERRQ(ierr); 2045*15aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"coarse functions (phi) errors\n");CHKERRQ(ierr); 2046*15aaf578SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 2047*15aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local %02d-th function error = % 1.14e\n",i,coarsefunctions_errors[i]);CHKERRQ(ierr); 2048*15aaf578SStefano Zampini } 2049*15aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"constraints (phi) errors\n");CHKERRQ(ierr); 2050*15aaf578SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 2051*15aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local %02d-th function error = % 1.14e\n",i,constraints_errors[i]);CHKERRQ(ierr); 2052*15aaf578SStefano Zampini } 2053*15aaf578SStefano Zampini if (pcbddc->coarse_psi_B) { 2054*15aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"coarse functions (psi) errors\n");CHKERRQ(ierr); 2055*15aaf578SStefano Zampini for (i=pcbddc->local_primal_size;i<2*pcbddc->local_primal_size;i++) { 2056*15aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local %02d-th function error = % 1.14e\n",i-pcbddc->local_primal_size,coarsefunctions_errors[i]);CHKERRQ(ierr); 2057*15aaf578SStefano Zampini } 2058*15aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"constraints (psi) errors\n");CHKERRQ(ierr); 2059*15aaf578SStefano Zampini for (i=pcbddc->local_primal_size;i<2*pcbddc->local_primal_size;i++) { 2060*15aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local %02d-th function error = % 1.14e\n",i-pcbddc->local_primal_size,constraints_errors[i]);CHKERRQ(ierr); 2061*15aaf578SStefano Zampini } 2062*15aaf578SStefano Zampini } 20630c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 206453cdbc3dSStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 206553cdbc3dSStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 206653cdbc3dSStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 206753cdbc3dSStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 206853cdbc3dSStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 206953cdbc3dSStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 207053cdbc3dSStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 207153cdbc3dSStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 207253cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 207353cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 2074*15aaf578SStefano Zampini if (pcbddc->coarse_psi_B) { 2075*15aaf578SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 2076*15aaf578SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 2077*15aaf578SStefano Zampini } 2078*15aaf578SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 20790c7d97c5SJed Brown ierr = PetscFree(coarsefunctions_errors);CHKERRQ(ierr); 20800c7d97c5SJed Brown ierr = PetscFree(constraints_errors);CHKERRQ(ierr); 20810c7d97c5SJed Brown } 20820c7d97c5SJed Brown /* free memory */ 20833b03a366Sstefano_zampini if (n_vertices) { 2084*15aaf578SStefano Zampini ierr = PetscFree(vertices);CHKERRQ(ierr); 20850c7d97c5SJed Brown ierr = VecDestroy(&vec1_V);CHKERRQ(ierr); 20860c7d97c5SJed Brown ierr = VecDestroy(&vec2_V);CHKERRQ(ierr); 20870c7d97c5SJed Brown ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 20880c7d97c5SJed Brown ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 20890c7d97c5SJed Brown ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 20900c7d97c5SJed Brown } 2091534831adSStefano Zampini if (n_constraints) { 20920c7d97c5SJed Brown ierr = VecDestroy(&vec1_C);CHKERRQ(ierr); 20930c7d97c5SJed Brown ierr = VecDestroy(&vec2_C);CHKERRQ(ierr); 20940c7d97c5SJed Brown ierr = MatDestroy(&M1);CHKERRQ(ierr); 20950c7d97c5SJed Brown ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 20960c7d97c5SJed Brown } 2097a929c220SStefano Zampini ierr = PetscFree(auxindices);CHKERRQ(ierr); 2098a929c220SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2099a929c220SStefano Zampini /* create coarse matrix and data structures for message passing associated actual choice of coarse problem type */ 2100674ae819SStefano Zampini ierr = PCBDDCSetUpCoarseEnvironment(pc,coarse_submat_vals);CHKERRQ(ierr); 2101a929c220SStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 21020c7d97c5SJed Brown } 21030c7d97c5SJed Brown /* free memory */ 21040c7d97c5SJed Brown ierr = ISDestroy(&is_R_local);CHKERRQ(ierr); 2105674ae819SStefano Zampini 21060c7d97c5SJed Brown PetscFunctionReturn(0); 21070c7d97c5SJed Brown } 21080c7d97c5SJed Brown 21090c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 21100c7d97c5SJed Brown 21117cbb387bSStefano Zampini /* BDDC requires metis 5.0.1 for multilevel */ 21127cbb387bSStefano Zampini #if defined(PETSC_HAVE_METIS) 21137cbb387bSStefano Zampini #include "metis.h" 21147cbb387bSStefano Zampini #define MetisInt idx_t 21157cbb387bSStefano Zampini #define MetisScalar real_t 21167cbb387bSStefano Zampini #endif 21177cbb387bSStefano Zampini 21180c7d97c5SJed Brown #undef __FUNCT__ 2119674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseEnvironment" 2120674ae819SStefano Zampini static PetscErrorCode PCBDDCSetUpCoarseEnvironment(PC pc,PetscScalar* coarse_submat_vals) 21210c7d97c5SJed Brown { 2122674ae819SStefano Zampini 2123674ae819SStefano Zampini 21240c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 21250c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 21260c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 2127ce94432eSBarry Smith MPI_Comm prec_comm; 21280c7d97c5SJed Brown MPI_Comm coarse_comm; 21290c7d97c5SJed Brown 2130674ae819SStefano Zampini MatNullSpace CoarseNullSpace; 2131674ae819SStefano Zampini 21320c7d97c5SJed Brown /* common to all choiches */ 21330c7d97c5SJed Brown PetscScalar *temp_coarse_mat_vals; 21340c7d97c5SJed Brown PetscScalar *ins_coarse_mat_vals; 21350c7d97c5SJed Brown PetscInt *ins_local_primal_indices; 21360c7d97c5SJed Brown PetscMPIInt *localsizes2,*localdispl2; 21370c7d97c5SJed Brown PetscMPIInt size_prec_comm; 21380c7d97c5SJed Brown PetscMPIInt rank_prec_comm; 21390c7d97c5SJed Brown PetscMPIInt active_rank=MPI_PROC_NULL; 21400c7d97c5SJed Brown PetscMPIInt master_proc=0; 21410c7d97c5SJed Brown PetscInt ins_local_primal_size; 21420c7d97c5SJed Brown /* specific to MULTILEVEL_BDDC */ 21430c7d97c5SJed Brown PetscMPIInt *ranks_recv; 21440c7d97c5SJed Brown PetscMPIInt count_recv=0; 21450c7d97c5SJed Brown PetscMPIInt rank_coarse_proc_send_to; 21460c7d97c5SJed Brown PetscMPIInt coarse_color = MPI_UNDEFINED; 21470c7d97c5SJed Brown ISLocalToGlobalMapping coarse_ISLG; 21480c7d97c5SJed Brown /* some other variables */ 21490c7d97c5SJed Brown PetscErrorCode ierr; 215019fd82e9SBarry Smith MatType coarse_mat_type; 215119fd82e9SBarry Smith PCType coarse_pc_type; 215219fd82e9SBarry Smith KSPType coarse_ksp_type; 215353cdbc3dSStefano Zampini PC pc_temp; 21544fad6a16SStefano Zampini PetscInt i,j,k; 21553b03a366Sstefano_zampini PetscInt max_it_coarse_ksp=1; /* don't increase this value */ 2156e269702eSStefano Zampini /* verbose output viewer */ 2157e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 2158e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 2159142dfd88SStefano Zampini 2160ea7e1babSStefano Zampini PetscInt offset,offset2; 2161a929c220SStefano Zampini PetscMPIInt im_active,active_procs; 2162523858cfSStefano Zampini PetscInt *dnz,*onz; 2163142dfd88SStefano Zampini 2164142dfd88SStefano Zampini PetscBool setsym,issym=PETSC_FALSE; 21650c7d97c5SJed Brown 21660c7d97c5SJed Brown PetscFunctionBegin; 21674b2d0b89SJed Brown ierr = PetscObjectGetComm((PetscObject)pc,&prec_comm);CHKERRQ(ierr); 21680c7d97c5SJed Brown ins_local_primal_indices = 0; 21690c7d97c5SJed Brown ins_coarse_mat_vals = 0; 21700c7d97c5SJed Brown localsizes2 = 0; 21710c7d97c5SJed Brown localdispl2 = 0; 21720c7d97c5SJed Brown temp_coarse_mat_vals = 0; 21730c7d97c5SJed Brown coarse_ISLG = 0; 21740c7d97c5SJed Brown 217553cdbc3dSStefano Zampini ierr = MPI_Comm_size(prec_comm,&size_prec_comm);CHKERRQ(ierr); 217653cdbc3dSStefano Zampini ierr = MPI_Comm_rank(prec_comm,&rank_prec_comm);CHKERRQ(ierr); 2177142dfd88SStefano Zampini ierr = MatIsSymmetricKnown(pc->pmat,&setsym,&issym);CHKERRQ(ierr); 2178142dfd88SStefano Zampini 2179beed3852SStefano Zampini /* Assign global numbering to coarse dofs */ 2180beed3852SStefano Zampini { 2181674ae819SStefano Zampini PetscInt *auxlocal_primal,*aux_idx; 2182ef028eecSStefano Zampini PetscMPIInt mpi_local_primal_size; 2183ef028eecSStefano Zampini PetscScalar coarsesum,*array; 2184ef028eecSStefano Zampini 2185ef028eecSStefano Zampini mpi_local_primal_size = (PetscMPIInt)pcbddc->local_primal_size; 2186beed3852SStefano Zampini 2187beed3852SStefano Zampini /* Construct needed data structures for message passing */ 2188ffe5efe1SStefano Zampini j = 0; 2189142dfd88SStefano Zampini if (rank_prec_comm == 0 || pcbddc->coarse_problem_type == REPLICATED_BDDC || pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2190ffe5efe1SStefano Zampini j = size_prec_comm; 2191ffe5efe1SStefano Zampini } 2192ffe5efe1SStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->local_primal_sizes);CHKERRQ(ierr); 2193ffe5efe1SStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 2194beed3852SStefano Zampini /* Gather local_primal_size information for all processes */ 2195142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == REPLICATED_BDDC || pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 21965619798eSStefano Zampini ierr = MPI_Allgather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,prec_comm);CHKERRQ(ierr); 2197ffe5efe1SStefano Zampini } else { 2198ffe5efe1SStefano Zampini ierr = MPI_Gather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 2199ffe5efe1SStefano Zampini } 2200beed3852SStefano Zampini pcbddc->replicated_primal_size = 0; 2201ffe5efe1SStefano Zampini for (i=0; i<j; i++) { 2202beed3852SStefano Zampini pcbddc->local_primal_displacements[i] = pcbddc->replicated_primal_size ; 2203beed3852SStefano Zampini pcbddc->replicated_primal_size += pcbddc->local_primal_sizes[i]; 2204beed3852SStefano Zampini } 2205beed3852SStefano Zampini 2206da1bb401SStefano Zampini /* First let's count coarse dofs. 2207beed3852SStefano Zampini This code fragment assumes that the number of local constraints per connected component 2208beed3852SStefano Zampini is not greater than the number of nodes defined for the connected component 2209beed3852SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 2210ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscInt),&auxlocal_primal);CHKERRQ(ierr); 2211674ae819SStefano Zampini ierr = PCBDDCGetPrimalVerticesLocalIdx(pc,&i,&aux_idx);CHKERRQ(ierr); 2212674ae819SStefano Zampini ierr = PetscMemcpy(auxlocal_primal,aux_idx,i*sizeof(PetscInt));CHKERRQ(ierr); 2213674ae819SStefano Zampini ierr = PetscFree(aux_idx);CHKERRQ(ierr); 2214674ae819SStefano Zampini ierr = PCBDDCGetPrimalConstraintsLocalIdx(pc,&j,&aux_idx);CHKERRQ(ierr); 2215674ae819SStefano Zampini ierr = PetscMemcpy(&auxlocal_primal[i],aux_idx,j*sizeof(PetscInt));CHKERRQ(ierr); 2216674ae819SStefano Zampini ierr = PetscFree(aux_idx);CHKERRQ(ierr); 2217ef028eecSStefano Zampini /* Compute number of coarse dofs */ 2218674ae819SStefano Zampini ierr = PCBDDCSubsetNumbering(prec_comm,matis->mapping,pcbddc->local_primal_size,auxlocal_primal,NULL,&pcbddc->coarse_size,&pcbddc->local_primal_indices);CHKERRQ(ierr); 2219ef028eecSStefano Zampini 2220ef028eecSStefano Zampini if (dbg_flag) { 22212e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 22222e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 22232e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Check coarse indices\n");CHKERRQ(ierr); 22242e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 22252e8d2280SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 22262fa5cd67SKarl Rupp for (i=0;i<pcbddc->local_primal_size;i++) array[auxlocal_primal[i]]=1.0; 2227beed3852SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 22282e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 2229da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2230da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2231da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2232da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2233da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 22342e8d2280SStefano Zampini for (i=0;i<pcis->n;i++) { 22352e8d2280SStefano Zampini if (array[i] == 1.0) { 22362e8d2280SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,1,&i,&j);CHKERRQ(ierr); 22372e8d2280SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d: WRONG COARSE INDEX %d (local %d)\n",PetscGlobalRank,j,i);CHKERRQ(ierr); 22382e8d2280SStefano Zampini } 22392e8d2280SStefano Zampini } 22402e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 22412e8d2280SStefano Zampini for (i=0;i<pcis->n;i++) { 22422fa5cd67SKarl Rupp if (array[i] > 0.0) array[i] = 1.0/array[i]; 22432e8d2280SStefano Zampini } 2244da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 22452e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 2246da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2247da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2248da1bb401SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 22492e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem SHOULD be %lf\n",coarsesum);CHKERRQ(ierr); 22502e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 22512e8d2280SStefano Zampini } 2252142dfd88SStefano Zampini ierr = PetscFree(auxlocal_primal);CHKERRQ(ierr); 22530bdf917eSStefano Zampini } 22540bdf917eSStefano Zampini 22552e8d2280SStefano Zampini if (dbg_flag) { 22567cf533a6SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem is %d\n",pcbddc->coarse_size);CHKERRQ(ierr); 22579d9e44b6SStefano Zampini if (dbg_flag > 1) { 2258674ae819SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 2259674ae819SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2260674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 2261674ae819SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 2262674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_primal_indices[%d]=%d \n",i,pcbddc->local_primal_indices[i]); 2263674ae819SStefano Zampini } 22642e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 22652e8d2280SStefano Zampini } 22669d9e44b6SStefano Zampini } 22672e8d2280SStefano Zampini 2268a929c220SStefano Zampini im_active = 0; 22692fa5cd67SKarl Rupp if (pcis->n) im_active = 1; 2270a929c220SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,prec_comm);CHKERRQ(ierr); 22710bdf917eSStefano Zampini 22720bdf917eSStefano Zampini /* adapt coarse problem type */ 22737cbb387bSStefano Zampini #if defined(PETSC_HAVE_METIS) 22744fad6a16SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 22754fad6a16SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 2276a929c220SStefano Zampini if ( (active_procs/pcbddc->coarsening_ratio) < 2 ) { 22770bdf917eSStefano Zampini if (dbg_flag) { 2278a929c220SStefano 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); 22790bdf917eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 22800bdf917eSStefano Zampini } 22810bdf917eSStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 2282142dfd88SStefano Zampini } 22834fad6a16SStefano Zampini } else { 22844fad6a16SStefano Zampini if (dbg_flag) { 2285a929c220SStefano 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); 22864fad6a16SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 22874fad6a16SStefano Zampini } 22884fad6a16SStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 22894fad6a16SStefano Zampini } 22904fad6a16SStefano Zampini } 22917cbb387bSStefano Zampini #else 22927cbb387bSStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 22937cbb387bSStefano Zampini #endif 2294beed3852SStefano Zampini 22950c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 22960c7d97c5SJed Brown 2297da1bb401SStefano Zampini case(MULTILEVEL_BDDC): /* we define a coarse mesh where subdomains are elements */ 22980c7d97c5SJed Brown { 22997cbb387bSStefano Zampini #if defined(PETSC_HAVE_METIS) 23000c7d97c5SJed Brown /* we need additional variables */ 23010c7d97c5SJed Brown MetisInt n_subdomains,n_parts,objval,ncon,faces_nvtxs; 23020c7d97c5SJed Brown MetisInt *metis_coarse_subdivision; 23030c7d97c5SJed Brown MetisInt options[METIS_NOPTIONS]; 23040c7d97c5SJed Brown PetscMPIInt size_coarse_comm,rank_coarse_comm; 23050c7d97c5SJed Brown PetscMPIInt procs_jumps_coarse_comm; 23060c7d97c5SJed Brown PetscMPIInt *coarse_subdivision; 23070c7d97c5SJed Brown PetscMPIInt *total_count_recv; 23080c7d97c5SJed Brown PetscMPIInt *total_ranks_recv; 23090c7d97c5SJed Brown PetscMPIInt *displacements_recv; 23100c7d97c5SJed Brown PetscMPIInt *my_faces_connectivity; 23110c7d97c5SJed Brown PetscMPIInt *petsc_faces_adjncy; 23120c7d97c5SJed Brown MetisInt *faces_adjncy; 23130c7d97c5SJed Brown MetisInt *faces_xadj; 23140c7d97c5SJed Brown PetscMPIInt *number_of_faces; 23150c7d97c5SJed Brown PetscMPIInt *faces_displacements; 23160c7d97c5SJed Brown PetscInt *array_int; 23170c7d97c5SJed Brown PetscMPIInt my_faces=0; 23180c7d97c5SJed Brown PetscMPIInt total_faces=0; 23193828260eSStefano Zampini PetscInt ranks_stretching_ratio; 23200c7d97c5SJed Brown 23210c7d97c5SJed Brown /* define some quantities */ 23220c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 23230c7d97c5SJed Brown coarse_mat_type = MATIS; 23240c7d97c5SJed Brown coarse_pc_type = PCBDDC; 2325142dfd88SStefano Zampini coarse_ksp_type = KSPRICHARDSON; 23260c7d97c5SJed Brown 23270c7d97c5SJed Brown /* details of coarse decomposition */ 2328a929c220SStefano Zampini n_subdomains = active_procs; 23290c7d97c5SJed Brown n_parts = n_subdomains/pcbddc->coarsening_ratio; 2330a929c220SStefano Zampini ranks_stretching_ratio = size_prec_comm/active_procs; 23313828260eSStefano Zampini procs_jumps_coarse_comm = pcbddc->coarsening_ratio*ranks_stretching_ratio; 23323828260eSStefano Zampini 2333a929c220SStefano Zampini #if 0 2334a929c220SStefano Zampini PetscMPIInt *old_ranks; 2335a929c220SStefano Zampini PetscInt *new_ranks,*jj,*ii; 2336a929c220SStefano Zampini MatPartitioning mat_part; 2337a929c220SStefano Zampini IS coarse_new_decomposition,is_numbering; 2338a929c220SStefano Zampini PetscViewer viewer_test; 2339a929c220SStefano Zampini MPI_Comm test_coarse_comm; 2340a929c220SStefano Zampini PetscMPIInt test_coarse_color; 2341a929c220SStefano Zampini Mat mat_adj; 2342a929c220SStefano Zampini /* Create new communicator for coarse problem splitting the old one */ 2343a929c220SStefano Zampini /* procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 2344a929c220SStefano Zampini key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator */ 2345a929c220SStefano Zampini test_coarse_color = ( im_active ? 0 : MPI_UNDEFINED ); 2346a929c220SStefano Zampini test_coarse_comm = MPI_COMM_NULL; 2347a929c220SStefano Zampini ierr = MPI_Comm_split(prec_comm,test_coarse_color,rank_prec_comm,&test_coarse_comm);CHKERRQ(ierr); 2348a929c220SStefano Zampini if (im_active) { 2349a929c220SStefano Zampini ierr = PetscMalloc(n_subdomains*sizeof(PetscMPIInt),&old_ranks); 2350a929c220SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscInt),&new_ranks); 2351a929c220SStefano Zampini ierr = MPI_Comm_rank(test_coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 2352a929c220SStefano Zampini ierr = MPI_Comm_size(test_coarse_comm,&j);CHKERRQ(ierr); 2353a929c220SStefano Zampini ierr = MPI_Allgather(&rank_prec_comm,1,MPIU_INT,old_ranks,1,MPIU_INT,test_coarse_comm);CHKERRQ(ierr); 2354674ae819SStefano Zampini for (i=0; i<size_prec_comm; i++) new_ranks[i] = -1; 2355674ae819SStefano Zampini for (i=0; i<n_subdomains; i++) new_ranks[old_ranks[i]] = i; 2356a929c220SStefano Zampini ierr = PetscViewerASCIIOpen(test_coarse_comm,"test_mat_part.out",&viewer_test);CHKERRQ(ierr); 2357a929c220SStefano Zampini k = pcis->n_neigh-1; 2358a929c220SStefano Zampini ierr = PetscMalloc(2*sizeof(PetscInt),&ii); 2359a929c220SStefano Zampini ii[0]=0; 2360a929c220SStefano Zampini ii[1]=k; 2361a929c220SStefano Zampini ierr = PetscMalloc(k*sizeof(PetscInt),&jj); 2362674ae819SStefano Zampini for (i=0; i<k; i++) jj[i]=new_ranks[pcis->neigh[i+1]]; 2363a929c220SStefano Zampini ierr = PetscSortInt(k,jj);CHKERRQ(ierr); 23640298fd71SBarry Smith ierr = MatCreateMPIAdj(test_coarse_comm,1,n_subdomains,ii,jj,NULL,&mat_adj);CHKERRQ(ierr); 2365a929c220SStefano Zampini ierr = MatView(mat_adj,viewer_test);CHKERRQ(ierr); 2366a929c220SStefano Zampini ierr = MatPartitioningCreate(test_coarse_comm,&mat_part);CHKERRQ(ierr); 2367a929c220SStefano Zampini ierr = MatPartitioningSetAdjacency(mat_part,mat_adj);CHKERRQ(ierr); 2368a929c220SStefano Zampini ierr = MatPartitioningSetFromOptions(mat_part);CHKERRQ(ierr); 2369a929c220SStefano Zampini printf("Setting Nparts %d\n",n_parts); 2370a929c220SStefano Zampini ierr = MatPartitioningSetNParts(mat_part,n_parts);CHKERRQ(ierr); 2371a929c220SStefano Zampini ierr = MatPartitioningView(mat_part,viewer_test);CHKERRQ(ierr); 2372a929c220SStefano Zampini ierr = MatPartitioningApply(mat_part,&coarse_new_decomposition);CHKERRQ(ierr); 2373a929c220SStefano Zampini ierr = ISView(coarse_new_decomposition,viewer_test);CHKERRQ(ierr); 2374a929c220SStefano Zampini ierr = ISPartitioningToNumbering(coarse_new_decomposition,&is_numbering);CHKERRQ(ierr); 2375a929c220SStefano Zampini ierr = ISView(is_numbering,viewer_test);CHKERRQ(ierr); 2376a929c220SStefano Zampini ierr = PetscViewerDestroy(&viewer_test);CHKERRQ(ierr); 2377a929c220SStefano Zampini ierr = ISDestroy(&coarse_new_decomposition);CHKERRQ(ierr); 2378a929c220SStefano Zampini ierr = ISDestroy(&is_numbering);CHKERRQ(ierr); 2379a929c220SStefano Zampini ierr = MatPartitioningDestroy(&mat_part);CHKERRQ(ierr); 2380a929c220SStefano Zampini ierr = PetscFree(old_ranks);CHKERRQ(ierr); 2381a929c220SStefano Zampini ierr = PetscFree(new_ranks);CHKERRQ(ierr); 2382a929c220SStefano Zampini ierr = MPI_Comm_free(&test_coarse_comm);CHKERRQ(ierr); 2383a929c220SStefano Zampini } 2384a929c220SStefano Zampini #endif 2385a929c220SStefano Zampini 23864fad6a16SStefano Zampini /* build CSR graph of subdomains' connectivity */ 23870c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&array_int);CHKERRQ(ierr); 23883828260eSStefano Zampini ierr = PetscMemzero(array_int,pcis->n*sizeof(PetscInt));CHKERRQ(ierr); 23890c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++){/* i=1 so I don't count myself -> faces nodes counts to 1 */ 23900c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++){ 23910c7d97c5SJed Brown array_int[ pcis->shared[i][j] ]+=1; 23920c7d97c5SJed Brown } 23930c7d97c5SJed Brown } 23940c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++){ 23950c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++){ 23967cf533a6SStefano Zampini if (array_int[ pcis->shared[i][j] ] > 0 ){ 23970c7d97c5SJed Brown my_faces++; 23980c7d97c5SJed Brown break; 23990c7d97c5SJed Brown } 24000c7d97c5SJed Brown } 24010c7d97c5SJed Brown } 24020c7d97c5SJed Brown 240353cdbc3dSStefano Zampini ierr = MPI_Reduce(&my_faces,&total_faces,1,MPIU_INT,MPI_SUM,master_proc,prec_comm);CHKERRQ(ierr); 24040c7d97c5SJed Brown ierr = PetscMalloc (my_faces*sizeof(PetscInt),&my_faces_connectivity);CHKERRQ(ierr); 24050c7d97c5SJed Brown my_faces=0; 24060c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++){ 24070c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++){ 24087cf533a6SStefano Zampini if (array_int[ pcis->shared[i][j] ] > 0 ){ 24090c7d97c5SJed Brown my_faces_connectivity[my_faces]=pcis->neigh[i]; 24100c7d97c5SJed Brown my_faces++; 24110c7d97c5SJed Brown break; 24120c7d97c5SJed Brown } 24130c7d97c5SJed Brown } 24140c7d97c5SJed Brown } 24150c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 24160c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(PetscMPIInt),&petsc_faces_adjncy);CHKERRQ(ierr); 24170c7d97c5SJed Brown ierr = PetscMalloc (size_prec_comm*sizeof(PetscMPIInt),&number_of_faces);CHKERRQ(ierr); 24180c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(MetisInt),&faces_adjncy);CHKERRQ(ierr); 24190c7d97c5SJed Brown ierr = PetscMalloc ((n_subdomains+1)*sizeof(MetisInt),&faces_xadj);CHKERRQ(ierr); 24200c7d97c5SJed Brown ierr = PetscMalloc ((size_prec_comm+1)*sizeof(PetscMPIInt),&faces_displacements);CHKERRQ(ierr); 24210c7d97c5SJed Brown } 242253cdbc3dSStefano Zampini ierr = MPI_Gather(&my_faces,1,MPIU_INT,&number_of_faces[0],1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 24230c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 24240c7d97c5SJed Brown faces_xadj[0]=0; 24250c7d97c5SJed Brown faces_displacements[0]=0; 24260c7d97c5SJed Brown j=0; 24270c7d97c5SJed Brown for (i=1;i<size_prec_comm+1;i++) { 24280c7d97c5SJed Brown faces_displacements[i]=faces_displacements[i-1]+number_of_faces[i-1]; 24290c7d97c5SJed Brown if (number_of_faces[i-1]) { 24300c7d97c5SJed Brown j++; 24310c7d97c5SJed Brown faces_xadj[j]=faces_xadj[j-1]+number_of_faces[i-1]; 24320c7d97c5SJed Brown } 24330c7d97c5SJed Brown } 24340c7d97c5SJed Brown } 243553cdbc3dSStefano 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); 24360c7d97c5SJed Brown ierr = PetscFree(my_faces_connectivity);CHKERRQ(ierr); 24370c7d97c5SJed Brown ierr = PetscFree(array_int);CHKERRQ(ierr); 24380c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 24393828260eSStefano Zampini for (i=0;i<total_faces;i++) faces_adjncy[i]=(MetisInt)(petsc_faces_adjncy[i]/ranks_stretching_ratio); /* cast to MetisInt */ 24400c7d97c5SJed Brown ierr = PetscFree(faces_displacements);CHKERRQ(ierr); 24410c7d97c5SJed Brown ierr = PetscFree(number_of_faces);CHKERRQ(ierr); 24420c7d97c5SJed Brown ierr = PetscFree(petsc_faces_adjncy);CHKERRQ(ierr); 24430c7d97c5SJed Brown } 24440c7d97c5SJed Brown 24450c7d97c5SJed Brown if ( rank_prec_comm == master_proc ) { 2446674ae819SStefano Zampini 24473828260eSStefano Zampini PetscInt heuristic_for_metis=3; 2448674ae819SStefano Zampini 24490c7d97c5SJed Brown ncon=1; 24500c7d97c5SJed Brown faces_nvtxs=n_subdomains; 24510c7d97c5SJed Brown /* partition graoh induced by face connectivity */ 24520c7d97c5SJed Brown ierr = PetscMalloc (n_subdomains*sizeof(MetisInt),&metis_coarse_subdivision);CHKERRQ(ierr); 24530c7d97c5SJed Brown ierr = METIS_SetDefaultOptions(options); 24540c7d97c5SJed Brown /* we need a contiguous partition of the coarse mesh */ 24550c7d97c5SJed Brown options[METIS_OPTION_CONTIG]=1; 24560c7d97c5SJed Brown options[METIS_OPTION_NITER]=30; 24574fad6a16SStefano Zampini if (pcbddc->coarsening_ratio > 1) { 24583828260eSStefano Zampini if (n_subdomains>n_parts*heuristic_for_metis) { 24593828260eSStefano Zampini options[METIS_OPTION_IPTYPE]=METIS_IPTYPE_EDGE; 24603828260eSStefano Zampini options[METIS_OPTION_OBJTYPE]=METIS_OBJTYPE_CUT; 24610c7d97c5SJed Brown ierr = METIS_PartGraphKway(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 2462674ae819SStefano 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); 24633828260eSStefano Zampini } else { 24643828260eSStefano Zampini ierr = METIS_PartGraphRecursive(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 2465674ae819SStefano 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); 24663828260eSStefano Zampini } 24674fad6a16SStefano Zampini } else { 24682fa5cd67SKarl Rupp for (i=0;i<n_subdomains;i++) metis_coarse_subdivision[i]=i; 24694fad6a16SStefano Zampini } 24700c7d97c5SJed Brown ierr = PetscFree(faces_xadj);CHKERRQ(ierr); 24710c7d97c5SJed Brown ierr = PetscFree(faces_adjncy);CHKERRQ(ierr); 24720bdf917eSStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&coarse_subdivision);CHKERRQ(ierr); 24732fa5cd67SKarl Rupp 24740c7d97c5SJed Brown /* copy/cast values avoiding possible type conflicts between PETSc, MPI and METIS */ 24752fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) coarse_subdivision[i]=MPI_PROC_NULL; 24762fa5cd67SKarl Rupp for (i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=(PetscInt)(metis_coarse_subdivision[i]); 24770c7d97c5SJed Brown ierr = PetscFree(metis_coarse_subdivision);CHKERRQ(ierr); 24780c7d97c5SJed Brown } 24790c7d97c5SJed Brown 24800c7d97c5SJed Brown /* Create new communicator for coarse problem splitting the old one */ 24810c7d97c5SJed Brown if ( !(rank_prec_comm%procs_jumps_coarse_comm) && rank_prec_comm < procs_jumps_coarse_comm*n_parts ){ 2482da1bb401SStefano Zampini coarse_color=0; /* for communicator splitting */ 2483da1bb401SStefano Zampini active_rank=rank_prec_comm; /* for insertion of matrix values */ 24840c7d97c5SJed Brown } 2485da1bb401SStefano Zampini /* procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 2486da1bb401SStefano Zampini key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator */ 248753cdbc3dSStefano Zampini ierr = MPI_Comm_split(prec_comm,coarse_color,rank_prec_comm,&coarse_comm);CHKERRQ(ierr); 24880c7d97c5SJed Brown 24890c7d97c5SJed Brown if ( coarse_color == 0 ) { 249053cdbc3dSStefano Zampini ierr = MPI_Comm_size(coarse_comm,&size_coarse_comm);CHKERRQ(ierr); 249153cdbc3dSStefano Zampini ierr = MPI_Comm_rank(coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 24920c7d97c5SJed Brown } else { 24930c7d97c5SJed Brown rank_coarse_comm = MPI_PROC_NULL; 24940c7d97c5SJed Brown } 24950c7d97c5SJed Brown 24967cf533a6SStefano Zampini /* master proc take care of arranging and distributing coarse information */ 24970c7d97c5SJed Brown if (rank_coarse_comm == master_proc) { 24980c7d97c5SJed Brown ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&displacements_recv);CHKERRQ(ierr); 24990bdf917eSStefano Zampini ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&total_count_recv);CHKERRQ(ierr); 25000bdf917eSStefano Zampini ierr = PetscMalloc (n_subdomains*sizeof(PetscMPIInt),&total_ranks_recv);CHKERRQ(ierr); 25010c7d97c5SJed Brown /* some initializations */ 25020c7d97c5SJed Brown displacements_recv[0]=0; 25030bdf917eSStefano Zampini ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 25040c7d97c5SJed Brown /* count from how many processes the j-th process of the coarse decomposition will receive data */ 25050bdf917eSStefano Zampini for (j=0;j<size_coarse_comm;j++) { 25060bdf917eSStefano Zampini for (i=0;i<size_prec_comm;i++) { 25072fa5cd67SKarl Rupp if (coarse_subdivision[i]==j) total_count_recv[j]++; 25080bdf917eSStefano Zampini } 25090bdf917eSStefano Zampini } 25100c7d97c5SJed Brown /* displacements needed for scatterv of total_ranks_recv */ 25112fa5cd67SKarl Rupp for (i=1; i<size_coarse_comm; i++) displacements_recv[i]=displacements_recv[i-1]+total_count_recv[i-1]; 25122fa5cd67SKarl Rupp 25130c7d97c5SJed Brown /* Now fill properly total_ranks_recv -> each coarse process will receive the ranks (in prec_comm communicator) of its friend (sending) processes */ 25140c7d97c5SJed Brown ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 25150c7d97c5SJed Brown for (j=0;j<size_coarse_comm;j++) { 25163828260eSStefano Zampini for (i=0;i<size_prec_comm;i++) { 25170c7d97c5SJed Brown if (coarse_subdivision[i]==j) { 25180c7d97c5SJed Brown total_ranks_recv[displacements_recv[j]+total_count_recv[j]]=i; 25193828260eSStefano Zampini total_count_recv[j]+=1; 25200c7d97c5SJed Brown } 25210c7d97c5SJed Brown } 25220c7d97c5SJed Brown } 2523da1bb401SStefano Zampini /*for (j=0;j<size_coarse_comm;j++) { 25243828260eSStefano Zampini printf("process %d in new rank will receive from %d processes (original ranks follows)\n",j,total_count_recv[j]); 25253828260eSStefano Zampini for (i=0;i<total_count_recv[j];i++) { 25263828260eSStefano Zampini printf("%d ",total_ranks_recv[displacements_recv[j]+i]); 25273828260eSStefano Zampini } 25283828260eSStefano Zampini printf("\n"); 2529da1bb401SStefano Zampini }*/ 25300c7d97c5SJed Brown 25310c7d97c5SJed Brown /* identify new decomposition in terms of ranks in the old communicator */ 25320bdf917eSStefano Zampini for (i=0;i<n_subdomains;i++) { 25330bdf917eSStefano Zampini coarse_subdivision[ranks_stretching_ratio*i]=coarse_subdivision[ranks_stretching_ratio*i]*procs_jumps_coarse_comm; 25340bdf917eSStefano Zampini } 2535da1bb401SStefano Zampini /*printf("coarse_subdivision in old end new ranks\n"); 2536674ae819SStefano Zampini for (i=0;i<size_prec_comm;i++) 25373828260eSStefano Zampini if (coarse_subdivision[i]!=MPI_PROC_NULL) { 25383828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]/procs_jumps_coarse_comm); 25393828260eSStefano Zampini } else { 25403828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]); 25413828260eSStefano Zampini } 2542da1bb401SStefano Zampini printf("\n");*/ 25430c7d97c5SJed Brown } 25440c7d97c5SJed Brown 25450c7d97c5SJed Brown /* Scatter new decomposition for send details */ 254653cdbc3dSStefano Zampini ierr = MPI_Scatter(&coarse_subdivision[0],1,MPIU_INT,&rank_coarse_proc_send_to,1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 25470c7d97c5SJed Brown /* Scatter receiving details to members of coarse decomposition */ 25480c7d97c5SJed Brown if ( coarse_color == 0) { 254953cdbc3dSStefano Zampini ierr = MPI_Scatter(&total_count_recv[0],1,MPIU_INT,&count_recv,1,MPIU_INT,master_proc,coarse_comm);CHKERRQ(ierr); 25500c7d97c5SJed Brown ierr = PetscMalloc (count_recv*sizeof(PetscMPIInt),&ranks_recv);CHKERRQ(ierr); 255153cdbc3dSStefano 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); 25520c7d97c5SJed Brown } 25530c7d97c5SJed Brown 2554da1bb401SStefano Zampini /*printf("I will send my matrix data to proc %d\n",rank_coarse_proc_send_to); 2555da1bb401SStefano Zampini if (coarse_color == 0) { 2556da1bb401SStefano Zampini printf("I will receive some matrix data from %d processes (ranks follows)\n",count_recv); 2557da1bb401SStefano Zampini for (i=0;i<count_recv;i++) 2558da1bb401SStefano Zampini printf("%d ",ranks_recv[i]); 2559da1bb401SStefano Zampini printf("\n"); 2560da1bb401SStefano Zampini }*/ 25610c7d97c5SJed Brown 25620c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 25630bdf917eSStefano Zampini ierr = PetscFree(coarse_subdivision);CHKERRQ(ierr); 2564da1bb401SStefano Zampini ierr = PetscFree(total_count_recv);CHKERRQ(ierr); 25650bdf917eSStefano Zampini ierr = PetscFree(total_ranks_recv);CHKERRQ(ierr); 25660c7d97c5SJed Brown ierr = PetscFree(displacements_recv);CHKERRQ(ierr); 25670c7d97c5SJed Brown } 25687cbb387bSStefano Zampini #endif 25690c7d97c5SJed Brown break; 25700c7d97c5SJed Brown } 25710c7d97c5SJed Brown 25720c7d97c5SJed Brown case(REPLICATED_BDDC): 25730c7d97c5SJed Brown 25740c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 25750c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 25760c7d97c5SJed Brown coarse_pc_type = PCLU; 257753cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 25780c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 25790c7d97c5SJed Brown active_rank = rank_prec_comm; 25800c7d97c5SJed Brown break; 25810c7d97c5SJed Brown 25820c7d97c5SJed Brown case(PARALLEL_BDDC): 25830c7d97c5SJed Brown 25840c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 2585674ae819SStefano Zampini coarse_mat_type = MATAIJ; 25860c7d97c5SJed Brown coarse_pc_type = PCREDUNDANT; 258753cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 25880c7d97c5SJed Brown coarse_comm = prec_comm; 25890c7d97c5SJed Brown active_rank = rank_prec_comm; 25900c7d97c5SJed Brown break; 25910c7d97c5SJed Brown 25920c7d97c5SJed Brown case(SEQUENTIAL_BDDC): 25930c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 2594674ae819SStefano Zampini coarse_mat_type = MATAIJ; 25950c7d97c5SJed Brown coarse_pc_type = PCLU; 259653cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 25970c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 25980c7d97c5SJed Brown active_rank = master_proc; 25990c7d97c5SJed Brown break; 26000c7d97c5SJed Brown } 26010c7d97c5SJed Brown 26020c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 26030c7d97c5SJed Brown 26040c7d97c5SJed Brown case(SCATTERS_BDDC): 26050c7d97c5SJed Brown { 26060c7d97c5SJed Brown if (pcbddc->coarse_problem_type==MULTILEVEL_BDDC) { 26070c7d97c5SJed Brown 26082e8d2280SStefano Zampini IS coarse_IS; 26092e8d2280SStefano Zampini 2610523858cfSStefano Zampini if(pcbddc->coarsening_ratio == 1) { 2611523858cfSStefano Zampini ins_local_primal_size = pcbddc->local_primal_size; 2612523858cfSStefano Zampini ins_local_primal_indices = pcbddc->local_primal_indices; 2613523858cfSStefano Zampini if (coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 2614523858cfSStefano Zampini /* nonzeros */ 2615523858cfSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&dnz);CHKERRQ(ierr); 2616523858cfSStefano Zampini ierr = PetscMemzero(dnz,ins_local_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 2617523858cfSStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 2618523858cfSStefano Zampini dnz[i] = ins_local_primal_size; 2619523858cfSStefano Zampini } 2620523858cfSStefano Zampini } else { 26210c7d97c5SJed Brown PetscMPIInt send_size; 2622ef028eecSStefano Zampini PetscMPIInt *send_buffer; 26230c7d97c5SJed Brown PetscInt *aux_ins_indices; 26240c7d97c5SJed Brown PetscInt ii,jj; 26250c7d97c5SJed Brown MPI_Request *requests; 2626ef028eecSStefano Zampini 2627523858cfSStefano Zampini ierr = PetscMalloc(count_recv*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 2628523858cfSStefano Zampini /* reusing pcbddc->local_primal_displacements and pcbddc->replicated_primal_size */ 2629523858cfSStefano Zampini ierr = PetscFree(pcbddc->local_primal_displacements);CHKERRQ(ierr); 2630523858cfSStefano Zampini ierr = PetscMalloc((count_recv+1)*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 2631523858cfSStefano Zampini pcbddc->replicated_primal_size = count_recv; 2632523858cfSStefano Zampini j = 0; 2633523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 2634523858cfSStefano Zampini pcbddc->local_primal_displacements[i] = j; 2635523858cfSStefano Zampini j += pcbddc->local_primal_sizes[ranks_recv[i]]; 2636523858cfSStefano Zampini } 2637523858cfSStefano Zampini pcbddc->local_primal_displacements[count_recv] = j; 2638523858cfSStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 26390c7d97c5SJed Brown /* allocate auxiliary space */ 2640523858cfSStefano Zampini ierr = PetscMalloc(count_recv*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 26410c7d97c5SJed Brown ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscInt),&aux_ins_indices);CHKERRQ(ierr); 26420c7d97c5SJed Brown ierr = PetscMemzero(aux_ins_indices,pcbddc->coarse_size*sizeof(PetscInt));CHKERRQ(ierr); 26430c7d97c5SJed Brown /* allocate stuffs for message massing */ 26440c7d97c5SJed Brown ierr = PetscMalloc((count_recv+1)*sizeof(MPI_Request),&requests);CHKERRQ(ierr); 2645523858cfSStefano Zampini for (i=0;i<count_recv+1;i++) { requests[i]=MPI_REQUEST_NULL; } 2646523858cfSStefano Zampini /* send indices to be inserted */ 2647523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 2648523858cfSStefano Zampini send_size = pcbddc->local_primal_sizes[ranks_recv[i]]; 2649523858cfSStefano 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); 2650523858cfSStefano Zampini } 2651523858cfSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 2652523858cfSStefano Zampini send_size = pcbddc->local_primal_size; 2653ef028eecSStefano Zampini ierr = PetscMalloc(send_size*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 2654ef028eecSStefano Zampini for (i=0;i<send_size;i++) { 2655ef028eecSStefano Zampini send_buffer[i]=(PetscMPIInt)pcbddc->local_primal_indices[i]; 2656ef028eecSStefano Zampini } 2657ef028eecSStefano Zampini ierr = MPI_Isend(send_buffer,send_size,MPIU_INT,rank_coarse_proc_send_to,999,prec_comm,&requests[count_recv]);CHKERRQ(ierr); 2658523858cfSStefano Zampini } 2659523858cfSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2660ef028eecSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 2661ef028eecSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 2662ef028eecSStefano Zampini } 26630c7d97c5SJed Brown j = 0; 26640c7d97c5SJed Brown for (i=0;i<count_recv;i++) { 26652e8d2280SStefano Zampini ii = pcbddc->local_primal_displacements[i+1]-pcbddc->local_primal_displacements[i]; 26662e8d2280SStefano Zampini localsizes2[i] = ii*ii; 26670c7d97c5SJed Brown localdispl2[i] = j; 26680c7d97c5SJed Brown j += localsizes2[i]; 2669523858cfSStefano Zampini jj = pcbddc->local_primal_displacements[i]; 26704fad6a16SStefano Zampini /* it counts the coarse subdomains sharing the coarse node */ 26712e8d2280SStefano Zampini for (k=0;k<ii;k++) { 26724fad6a16SStefano Zampini aux_ins_indices[pcbddc->replicated_local_primal_indices[jj+k]] += 1; 26730c7d97c5SJed Brown } 26744fad6a16SStefano Zampini } 2675523858cfSStefano Zampini /* temp_coarse_mat_vals used to store matrix values to be received */ 26760c7d97c5SJed Brown ierr = PetscMalloc(j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 26770c7d97c5SJed Brown /* evaluate how many values I will insert in coarse mat */ 26780c7d97c5SJed Brown ins_local_primal_size = 0; 2679ea7e1babSStefano Zampini for (i=0;i<pcbddc->coarse_size;i++) { 2680ea7e1babSStefano Zampini if (aux_ins_indices[i]) { 26810c7d97c5SJed Brown ins_local_primal_size++; 2682ea7e1babSStefano Zampini } 2683ea7e1babSStefano Zampini } 26840c7d97c5SJed Brown /* evaluate indices I will insert in coarse mat */ 26850c7d97c5SJed Brown ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 26860c7d97c5SJed Brown j = 0; 2687ea7e1babSStefano Zampini for(i=0;i<pcbddc->coarse_size;i++) { 2688ea7e1babSStefano Zampini if(aux_ins_indices[i]) { 26892e8d2280SStefano Zampini ins_local_primal_indices[j] = i; 26902e8d2280SStefano Zampini j++; 2691ea7e1babSStefano Zampini } 2692ea7e1babSStefano Zampini } 2693523858cfSStefano Zampini /* processes partecipating in coarse problem receive matrix data from their friends */ 2694523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 2695523858cfSStefano Zampini ierr = MPI_Irecv(&temp_coarse_mat_vals[localdispl2[i]],localsizes2[i],MPIU_SCALAR,ranks_recv[i],666,prec_comm,&requests[i]);CHKERRQ(ierr); 2696523858cfSStefano Zampini } 2697523858cfSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL ) { 2698523858cfSStefano Zampini send_size = pcbddc->local_primal_size*pcbddc->local_primal_size; 2699523858cfSStefano 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); 2700523858cfSStefano Zampini } 2701523858cfSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2702523858cfSStefano Zampini /* nonzeros */ 2703523858cfSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&dnz);CHKERRQ(ierr); 2704523858cfSStefano Zampini ierr = PetscMemzero(dnz,ins_local_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 27050c7d97c5SJed Brown /* use aux_ins_indices to realize a global to local mapping */ 27060c7d97c5SJed Brown j=0; 27070c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++){ 27080c7d97c5SJed Brown if(aux_ins_indices[i]==0){ 27090c7d97c5SJed Brown aux_ins_indices[i]=-1; 27100c7d97c5SJed Brown } else { 27110c7d97c5SJed Brown aux_ins_indices[i]=j; 27120c7d97c5SJed Brown j++; 27130c7d97c5SJed Brown } 27140c7d97c5SJed Brown } 27154fad6a16SStefano Zampini for (i=0;i<count_recv;i++) { 2716523858cfSStefano Zampini j = pcbddc->local_primal_sizes[ranks_recv[i]]; 2717523858cfSStefano Zampini for (k=0;k<j;k++) { 2718523858cfSStefano Zampini dnz[aux_ins_indices[pcbddc->replicated_local_primal_indices[pcbddc->local_primal_displacements[i]+k]]] += j; 27190c7d97c5SJed Brown } 27200c7d97c5SJed Brown } 2721523858cfSStefano Zampini /* check */ 2722523858cfSStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 2723523858cfSStefano Zampini if (dnz[i] > ins_local_primal_size) { 2724523858cfSStefano Zampini dnz[i] = ins_local_primal_size; 27250c7d97c5SJed Brown } 27260c7d97c5SJed Brown } 27270c7d97c5SJed Brown ierr = PetscFree(requests);CHKERRQ(ierr); 27280c7d97c5SJed Brown ierr = PetscFree(aux_ins_indices);CHKERRQ(ierr); 27290c7d97c5SJed Brown if (coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 27304fad6a16SStefano Zampini } 27310c7d97c5SJed Brown /* create local to global mapping needed by coarse MATIS */ 2732142dfd88SStefano Zampini if (coarse_comm != MPI_COMM_NULL ) {ierr = MPI_Comm_free(&coarse_comm);CHKERRQ(ierr);} 27330c7d97c5SJed Brown coarse_comm = prec_comm; 27340c7d97c5SJed Brown active_rank = rank_prec_comm; 27350c7d97c5SJed Brown ierr = ISCreateGeneral(coarse_comm,ins_local_primal_size,ins_local_primal_indices,PETSC_COPY_VALUES,&coarse_IS);CHKERRQ(ierr); 27360c7d97c5SJed Brown ierr = ISLocalToGlobalMappingCreateIS(coarse_IS,&coarse_ISLG);CHKERRQ(ierr); 27370c7d97c5SJed Brown ierr = ISDestroy(&coarse_IS);CHKERRQ(ierr); 27382e8d2280SStefano Zampini } else if (pcbddc->coarse_problem_type==PARALLEL_BDDC) { 27390c7d97c5SJed Brown /* arrays for values insertion */ 27400c7d97c5SJed Brown ins_local_primal_size = pcbddc->local_primal_size; 27412e8d2280SStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 27420c7d97c5SJed Brown ierr = PetscMalloc(ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 27430c7d97c5SJed Brown for (j=0;j<ins_local_primal_size;j++){ 27440c7d97c5SJed Brown ins_local_primal_indices[j]=pcbddc->local_primal_indices[j]; 27454fad6a16SStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 27464fad6a16SStefano Zampini ins_coarse_mat_vals[j*ins_local_primal_size+i]=coarse_submat_vals[j*ins_local_primal_size+i]; 27474fad6a16SStefano Zampini } 27480c7d97c5SJed Brown } 27490c7d97c5SJed Brown } 27500c7d97c5SJed Brown break; 2751674ae819SStefano Zampini 27520c7d97c5SJed Brown } 27530c7d97c5SJed Brown 27540c7d97c5SJed Brown case(GATHERS_BDDC): 27550c7d97c5SJed Brown { 2756674ae819SStefano Zampini 27570c7d97c5SJed Brown PetscMPIInt mysize,mysize2; 2758ef028eecSStefano Zampini PetscMPIInt *send_buffer; 27590c7d97c5SJed Brown 27600c7d97c5SJed Brown if (rank_prec_comm==active_rank) { 27610c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 27620bdf917eSStefano Zampini ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscScalar),&pcbddc->replicated_local_primal_values);CHKERRQ(ierr); 27630c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 27640c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 27650c7d97c5SJed Brown /* arrays for values insertion */ 27662fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) localsizes2[i]=pcbddc->local_primal_sizes[i]*pcbddc->local_primal_sizes[i]; 27670c7d97c5SJed Brown localdispl2[0]=0; 27682fa5cd67SKarl Rupp for (i=1;i<size_prec_comm;i++) localdispl2[i]=localsizes2[i-1]+localdispl2[i-1]; 27690c7d97c5SJed Brown j=0; 27702fa5cd67SKarl Rupp for (i=0;i<size_prec_comm;i++) j+=localsizes2[i]; 27710c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 27720c7d97c5SJed Brown } 27730c7d97c5SJed Brown 27740c7d97c5SJed Brown mysize=pcbddc->local_primal_size; 27750c7d97c5SJed Brown mysize2=pcbddc->local_primal_size*pcbddc->local_primal_size; 2776ef028eecSStefano Zampini ierr = PetscMalloc(mysize*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 27772fa5cd67SKarl Rupp for (i=0; i<mysize; i++) send_buffer[i]=(PetscMPIInt)pcbddc->local_primal_indices[i]; 27782fa5cd67SKarl Rupp 27790c7d97c5SJed Brown if (pcbddc->coarse_problem_type == SEQUENTIAL_BDDC){ 2780ef028eecSStefano 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); 278153cdbc3dSStefano 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); 27820c7d97c5SJed Brown } else { 2783ef028eecSStefano 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); 278453cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,prec_comm);CHKERRQ(ierr); 27850c7d97c5SJed Brown } 2786ef028eecSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 27870c7d97c5SJed Brown break; 2788da1bb401SStefano Zampini }/* switch on coarse problem and communications associated with finished */ 27890c7d97c5SJed Brown } 27900c7d97c5SJed Brown 27910c7d97c5SJed Brown /* Now create and fill up coarse matrix */ 27920c7d97c5SJed Brown if ( rank_prec_comm == active_rank ) { 2793142dfd88SStefano Zampini 2794142dfd88SStefano Zampini Mat matis_coarse_local_mat; 2795142dfd88SStefano Zampini 27960c7d97c5SJed Brown if (pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 27970c7d97c5SJed Brown ierr = MatCreate(coarse_comm,&pcbddc->coarse_mat);CHKERRQ(ierr); 27980c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_mat,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size);CHKERRQ(ierr); 27990c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_mat,coarse_mat_type);CHKERRQ(ierr); 2800674ae819SStefano Zampini ierr = MatSetOptionsPrefix(pcbddc->coarse_mat,"coarse_");CHKERRQ(ierr); 2801674ae819SStefano Zampini ierr = MatSetFromOptions(pcbddc->coarse_mat);CHKERRQ(ierr); 28023b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 2803da1bb401SStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 28043b03a366Sstefano_zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 28050c7d97c5SJed Brown } else { 28064fad6a16SStefano Zampini ierr = MatCreateIS(coarse_comm,1,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_ISLG,&pcbddc->coarse_mat);CHKERRQ(ierr); 28073b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 28080c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 2809674ae819SStefano Zampini ierr = MatSetOptionsPrefix(pcbddc->coarse_mat,"coarse_");CHKERRQ(ierr); 2810674ae819SStefano Zampini ierr = MatSetFromOptions(pcbddc->coarse_mat);CHKERRQ(ierr); 28113b03a366Sstefano_zampini ierr = MatSetUp(matis_coarse_local_mat);CHKERRQ(ierr); 2812da1bb401SStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 2813a0ba757dSStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 28140c7d97c5SJed Brown } 2815142dfd88SStefano Zampini /* preallocation */ 2816142dfd88SStefano Zampini if (pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 2817ef028eecSStefano Zampini 2818674ae819SStefano Zampini PetscInt lrows,lcols,bs; 2819ef028eecSStefano Zampini 2820142dfd88SStefano Zampini ierr = MatGetLocalSize(pcbddc->coarse_mat,&lrows,&lcols);CHKERRQ(ierr); 2821142dfd88SStefano Zampini ierr = MatPreallocateInitialize(coarse_comm,lrows,lcols,dnz,onz);CHKERRQ(ierr); 2822674ae819SStefano Zampini ierr = MatGetBlockSize(pcbddc->coarse_mat,&bs);CHKERRQ(ierr); 2823ef028eecSStefano Zampini 2824142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == PARALLEL_BDDC) { 2825ef028eecSStefano Zampini 2826ef028eecSStefano Zampini Vec vec_dnz,vec_onz; 2827ef028eecSStefano Zampini PetscScalar *my_dnz,*my_onz,*array; 2828ef028eecSStefano Zampini PetscInt *mat_ranges,*row_ownership; 2829ef028eecSStefano Zampini PetscInt coarse_index_row,coarse_index_col,owner; 2830ef028eecSStefano Zampini 2831ef028eecSStefano Zampini ierr = VecCreate(prec_comm,&vec_dnz);CHKERRQ(ierr); 2832674ae819SStefano Zampini ierr = VecSetBlockSize(vec_dnz,bs);CHKERRQ(ierr); 2833ef028eecSStefano Zampini ierr = VecSetSizes(vec_dnz,PETSC_DECIDE,pcbddc->coarse_size);CHKERRQ(ierr); 2834ef028eecSStefano Zampini ierr = VecSetType(vec_dnz,VECMPI);CHKERRQ(ierr); 2835ef028eecSStefano Zampini ierr = VecDuplicate(vec_dnz,&vec_onz);CHKERRQ(ierr); 2836ef028eecSStefano Zampini 2837ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscScalar),&my_dnz);CHKERRQ(ierr); 2838ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscScalar),&my_onz);CHKERRQ(ierr); 2839ef028eecSStefano Zampini ierr = PetscMemzero(my_dnz,pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 2840ef028eecSStefano Zampini ierr = PetscMemzero(my_onz,pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 2841ef028eecSStefano Zampini 2842ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscInt),&row_ownership);CHKERRQ(ierr); 2843ef028eecSStefano Zampini ierr = MatGetOwnershipRanges(pcbddc->coarse_mat,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 2844142dfd88SStefano Zampini for (i=0;i<size_prec_comm;i++) { 2845ef028eecSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 2846ef028eecSStefano Zampini row_ownership[j]=i; 2847142dfd88SStefano Zampini } 2848142dfd88SStefano Zampini } 2849ef028eecSStefano Zampini 2850ef028eecSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 2851ef028eecSStefano Zampini coarse_index_row = pcbddc->local_primal_indices[i]; 2852ef028eecSStefano Zampini owner = row_ownership[coarse_index_row]; 2853ef028eecSStefano Zampini for (j=i;j<pcbddc->local_primal_size;j++) { 2854ef028eecSStefano Zampini owner = row_ownership[coarse_index_row]; 2855ef028eecSStefano Zampini coarse_index_col = pcbddc->local_primal_indices[j]; 2856ef028eecSStefano Zampini if (coarse_index_col > mat_ranges[owner]-1 && coarse_index_col < mat_ranges[owner+1] ) { 2857ef028eecSStefano Zampini my_dnz[i] += 1.0; 2858142dfd88SStefano Zampini } else { 2859ef028eecSStefano Zampini my_onz[i] += 1.0; 2860142dfd88SStefano Zampini } 2861ef028eecSStefano Zampini if (i != j) { 2862ef028eecSStefano Zampini owner = row_ownership[coarse_index_col]; 2863ef028eecSStefano Zampini if (coarse_index_row > mat_ranges[owner]-1 && coarse_index_row < mat_ranges[owner+1] ) { 2864ef028eecSStefano Zampini my_dnz[j] += 1.0; 2865142dfd88SStefano Zampini } else { 2866ef028eecSStefano Zampini my_onz[j] += 1.0; 2867142dfd88SStefano Zampini } 2868142dfd88SStefano Zampini } 2869142dfd88SStefano Zampini } 2870142dfd88SStefano Zampini } 2871ef028eecSStefano Zampini ierr = VecSet(vec_dnz,0.0);CHKERRQ(ierr); 2872ef028eecSStefano Zampini ierr = VecSet(vec_onz,0.0);CHKERRQ(ierr); 2873a929c220SStefano Zampini if (pcbddc->local_primal_size) { 2874ef028eecSStefano Zampini ierr = VecSetValues(vec_dnz,pcbddc->local_primal_size,pcbddc->local_primal_indices,my_dnz,ADD_VALUES);CHKERRQ(ierr); 2875ef028eecSStefano Zampini ierr = VecSetValues(vec_onz,pcbddc->local_primal_size,pcbddc->local_primal_indices,my_onz,ADD_VALUES);CHKERRQ(ierr); 2876a929c220SStefano Zampini } 2877ef028eecSStefano Zampini ierr = VecAssemblyBegin(vec_dnz);CHKERRQ(ierr); 2878ef028eecSStefano Zampini ierr = VecAssemblyBegin(vec_onz);CHKERRQ(ierr); 2879ef028eecSStefano Zampini ierr = VecAssemblyEnd(vec_dnz);CHKERRQ(ierr); 2880ef028eecSStefano Zampini ierr = VecAssemblyEnd(vec_onz);CHKERRQ(ierr); 2881ef028eecSStefano Zampini j = mat_ranges[rank_prec_comm+1]-mat_ranges[rank_prec_comm]; 2882ef028eecSStefano Zampini ierr = VecGetArray(vec_dnz,&array);CHKERRQ(ierr); 28832fa5cd67SKarl Rupp for (i=0; i<j; i++) dnz[i] = (PetscInt)array[i]; 28842fa5cd67SKarl Rupp 2885ef028eecSStefano Zampini ierr = VecRestoreArray(vec_dnz,&array);CHKERRQ(ierr); 2886ef028eecSStefano Zampini ierr = VecGetArray(vec_onz,&array);CHKERRQ(ierr); 28872fa5cd67SKarl Rupp for (i=0;i<j;i++) onz[i] = (PetscInt)array[i]; 28882fa5cd67SKarl Rupp 2889ef028eecSStefano Zampini ierr = VecRestoreArray(vec_onz,&array);CHKERRQ(ierr); 2890ef028eecSStefano Zampini ierr = PetscFree(my_dnz);CHKERRQ(ierr); 2891ef028eecSStefano Zampini ierr = PetscFree(my_onz);CHKERRQ(ierr); 2892ef028eecSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 2893ef028eecSStefano Zampini ierr = VecDestroy(&vec_dnz);CHKERRQ(ierr); 2894ef028eecSStefano Zampini ierr = VecDestroy(&vec_onz);CHKERRQ(ierr); 2895142dfd88SStefano Zampini } else { 2896142dfd88SStefano Zampini for (k=0;k<size_prec_comm;k++){ 2897142dfd88SStefano Zampini offset=pcbddc->local_primal_displacements[k]; 2898142dfd88SStefano Zampini offset2=localdispl2[k]; 2899142dfd88SStefano Zampini ins_local_primal_size = pcbddc->local_primal_sizes[k]; 2900ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2901ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2902ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2903ef028eecSStefano Zampini } 2904142dfd88SStefano Zampini for (j=0;j<ins_local_primal_size;j++) { 2905142dfd88SStefano Zampini ierr = MatPreallocateSet(ins_local_primal_indices[j],ins_local_primal_size,ins_local_primal_indices,dnz,onz);CHKERRQ(ierr); 2906142dfd88SStefano Zampini } 2907ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2908142dfd88SStefano Zampini } 2909142dfd88SStefano Zampini } 29102fa5cd67SKarl Rupp 2911142dfd88SStefano Zampini /* check */ 2912142dfd88SStefano Zampini for (i=0;i<lrows;i++) { 29132fa5cd67SKarl Rupp if (dnz[i]>lcols) dnz[i]=lcols; 29142fa5cd67SKarl Rupp if (onz[i]>pcbddc->coarse_size-lcols) onz[i]=pcbddc->coarse_size-lcols; 2915142dfd88SStefano Zampini } 2916d9a4edebSJed Brown ierr = MatSeqAIJSetPreallocation(pcbddc->coarse_mat,0,dnz);CHKERRQ(ierr); 2917d9a4edebSJed Brown ierr = MatMPIAIJSetPreallocation(pcbddc->coarse_mat,0,dnz,0,onz);CHKERRQ(ierr); 2918142dfd88SStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 2919142dfd88SStefano Zampini } else { 2920523858cfSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis_coarse_local_mat,0,dnz);CHKERRQ(ierr); 2921523858cfSStefano Zampini ierr = PetscFree(dnz);CHKERRQ(ierr); 2922142dfd88SStefano Zampini } 2923142dfd88SStefano Zampini /* insert values */ 2924523858cfSStefano Zampini if (pcbddc->coarse_problem_type == PARALLEL_BDDC) { 29250c7d97c5SJed 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); 2926523858cfSStefano Zampini } else if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2927523858cfSStefano Zampini if (pcbddc->coarsening_ratio == 1) { 2928523858cfSStefano Zampini ins_coarse_mat_vals = coarse_submat_vals; 2929523858cfSStefano 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); 2930523858cfSStefano Zampini } else { 2931523858cfSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2932523858cfSStefano Zampini for (k=0;k<pcbddc->replicated_primal_size;k++) { 2933523858cfSStefano Zampini offset = pcbddc->local_primal_displacements[k]; 2934523858cfSStefano Zampini offset2 = localdispl2[k]; 2935523858cfSStefano Zampini ins_local_primal_size = pcbddc->local_primal_displacements[k+1]-pcbddc->local_primal_displacements[k]; 2936ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2937ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2938ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2939ef028eecSStefano Zampini } 2940523858cfSStefano Zampini ins_coarse_mat_vals = &temp_coarse_mat_vals[offset2]; 2941523858cfSStefano 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); 2942ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2943523858cfSStefano Zampini } 2944523858cfSStefano Zampini } 2945523858cfSStefano Zampini ins_local_primal_indices = 0; 2946523858cfSStefano Zampini ins_coarse_mat_vals = 0; 2947ea7e1babSStefano Zampini } else { 2948ea7e1babSStefano Zampini for (k=0;k<size_prec_comm;k++){ 2949ea7e1babSStefano Zampini offset=pcbddc->local_primal_displacements[k]; 2950ea7e1babSStefano Zampini offset2=localdispl2[k]; 2951ea7e1babSStefano Zampini ins_local_primal_size = pcbddc->local_primal_sizes[k]; 2952ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 2953ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++){ 2954ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 2955ef028eecSStefano Zampini } 2956ea7e1babSStefano Zampini ins_coarse_mat_vals = &temp_coarse_mat_vals[offset2]; 2957ea7e1babSStefano 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); 2958ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 2959ea7e1babSStefano Zampini } 2960ea7e1babSStefano Zampini ins_local_primal_indices = 0; 2961ea7e1babSStefano Zampini ins_coarse_mat_vals = 0; 2962ea7e1babSStefano Zampini } 29630c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 29640c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2965142dfd88SStefano Zampini /* symmetry of coarse matrix */ 2966142dfd88SStefano Zampini if (issym) { 2967142dfd88SStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 2968142dfd88SStefano Zampini } 29690c7d97c5SJed Brown ierr = MatGetVecs(pcbddc->coarse_mat,&pcbddc->coarse_vec,&pcbddc->coarse_rhs);CHKERRQ(ierr); 29700bdf917eSStefano Zampini } 29710bdf917eSStefano Zampini 29720bdf917eSStefano Zampini /* create loc to glob scatters if needed */ 29730bdf917eSStefano Zampini if (pcbddc->coarse_communications_type == SCATTERS_BDDC) { 29740bdf917eSStefano Zampini IS local_IS,global_IS; 29750bdf917eSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&local_IS);CHKERRQ(ierr); 29760bdf917eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_indices,PETSC_COPY_VALUES,&global_IS);CHKERRQ(ierr); 29770bdf917eSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,local_IS,pcbddc->coarse_vec,global_IS,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 29780bdf917eSStefano Zampini ierr = ISDestroy(&local_IS);CHKERRQ(ierr); 29790bdf917eSStefano Zampini ierr = ISDestroy(&global_IS);CHKERRQ(ierr); 29800bdf917eSStefano Zampini } 29810bdf917eSStefano Zampini 2982a929c220SStefano Zampini /* free memory no longer needed */ 2983a929c220SStefano Zampini if (coarse_ISLG) { ierr = ISLocalToGlobalMappingDestroy(&coarse_ISLG);CHKERRQ(ierr); } 2984a929c220SStefano Zampini if (ins_local_primal_indices) { ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); } 2985a929c220SStefano Zampini if (ins_coarse_mat_vals) { ierr = PetscFree(ins_coarse_mat_vals);CHKERRQ(ierr); } 2986a929c220SStefano Zampini if (localsizes2) { ierr = PetscFree(localsizes2);CHKERRQ(ierr); } 2987a929c220SStefano Zampini if (localdispl2) { ierr = PetscFree(localdispl2);CHKERRQ(ierr); } 2988a929c220SStefano Zampini if (temp_coarse_mat_vals) { ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr); } 2989a929c220SStefano Zampini 2990674ae819SStefano Zampini /* Compute coarse null space */ 2991674ae819SStefano Zampini CoarseNullSpace = 0; 29920bdf917eSStefano Zampini if (pcbddc->NullSpace) { 2993674ae819SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,&CoarseNullSpace);CHKERRQ(ierr); 29940bdf917eSStefano Zampini } 29950bdf917eSStefano Zampini 29960bdf917eSStefano Zampini /* KSP for coarse problem */ 29970bdf917eSStefano Zampini if (rank_prec_comm == active_rank) { 29982e8d2280SStefano Zampini PetscBool isbddc=PETSC_FALSE; 29990bdf917eSStefano Zampini 300053cdbc3dSStefano Zampini ierr = KSPCreate(coarse_comm,&pcbddc->coarse_ksp);CHKERRQ(ierr); 300153cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 300253cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 30033b03a366Sstefano_zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,max_it_coarse_ksp);CHKERRQ(ierr); 300453cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 300553cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 300653cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 30070c7d97c5SJed Brown /* Allow user's customization */ 3008da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,"coarse_");CHKERRQ(ierr); 30090c7d97c5SJed Brown /* Set Up PC for coarse problem BDDC */ 301053cdbc3dSStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 30114fad6a16SStefano Zampini i = pcbddc->current_level+1; 30124fad6a16SStefano Zampini ierr = PCBDDCSetLevel(pc_temp,i);CHKERRQ(ierr); 30134fad6a16SStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 30144fad6a16SStefano Zampini ierr = PCBDDCSetMaxLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 301553cdbc3dSStefano Zampini ierr = PCBDDCSetCoarseProblemType(pc_temp,MULTILEVEL_BDDC);CHKERRQ(ierr); 3016674ae819SStefano Zampini if (CoarseNullSpace) { 3017674ae819SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 3018674ae819SStefano Zampini } 30194fad6a16SStefano Zampini if (dbg_flag) { 30204fad6a16SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------Level %d: Setting up level %d---------------\n",pcbddc->current_level,i);CHKERRQ(ierr); 30214fad6a16SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 302253cdbc3dSStefano Zampini } 3023674ae819SStefano Zampini } else { 3024674ae819SStefano Zampini if (CoarseNullSpace) { 3025674ae819SStefano Zampini ierr = KSPSetNullSpace(pcbddc->coarse_ksp,CoarseNullSpace);CHKERRQ(ierr); 3026674ae819SStefano Zampini } 30274fad6a16SStefano Zampini } 30284fad6a16SStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 302953cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 3030142dfd88SStefano Zampini 30310298fd71SBarry Smith ierr = KSPGetTolerances(pcbddc->coarse_ksp,NULL,NULL,NULL,&j);CHKERRQ(ierr); 30322e8d2280SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 30332e8d2280SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 30342e8d2280SStefano Zampini if (j == 1) { 30352e8d2280SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 30362e8d2280SStefano Zampini if (isbddc) { 30372e8d2280SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc_temp,PETSC_FALSE);CHKERRQ(ierr); 30385619798eSStefano Zampini } 30395619798eSStefano Zampini } 30400c7d97c5SJed Brown } 3041a929c220SStefano Zampini /* Check coarse problem if requested */ 3042142dfd88SStefano Zampini if ( dbg_flag && rank_prec_comm == active_rank ) { 3043142dfd88SStefano Zampini KSP check_ksp; 3044142dfd88SStefano Zampini PC check_pc; 3045142dfd88SStefano Zampini Vec check_vec; 3046142dfd88SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min,lambda_max; 304719fd82e9SBarry Smith KSPType check_ksp_type; 30480c7d97c5SJed Brown 3049142dfd88SStefano Zampini /* Create ksp object suitable for extreme eigenvalues' estimation */ 3050142dfd88SStefano Zampini ierr = KSPCreate(coarse_comm,&check_ksp);CHKERRQ(ierr); 3051142dfd88SStefano Zampini ierr = KSPSetOperators(check_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 30520bdf917eSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 3053142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 30542fa5cd67SKarl Rupp if (issym) check_ksp_type = KSPCG; 30552fa5cd67SKarl Rupp else check_ksp_type = KSPGMRES; 3056142dfd88SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,PETSC_TRUE);CHKERRQ(ierr); 3057142dfd88SStefano Zampini } else { 3058142dfd88SStefano Zampini check_ksp_type = KSPPREONLY; 3059142dfd88SStefano Zampini } 3060142dfd88SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 3061142dfd88SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 3062142dfd88SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 3063142dfd88SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 3064142dfd88SStefano Zampini /* create random vec */ 3065142dfd88SStefano Zampini ierr = VecDuplicate(pcbddc->coarse_vec,&check_vec);CHKERRQ(ierr); 30660298fd71SBarry Smith ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 3067674ae819SStefano Zampini if (CoarseNullSpace) { 3068674ae819SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec,NULL);CHKERRQ(ierr); 3069674ae819SStefano Zampini } 3070142dfd88SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,check_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 3071142dfd88SStefano Zampini /* solve coarse problem */ 3072142dfd88SStefano Zampini ierr = KSPSolve(check_ksp,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 3073674ae819SStefano Zampini if (CoarseNullSpace) { 3074674ae819SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 3075674ae819SStefano Zampini } 3076142dfd88SStefano Zampini /* check coarse problem residual error */ 3077142dfd88SStefano Zampini ierr = VecAXPY(check_vec,-1.0,pcbddc->coarse_vec);CHKERRQ(ierr); 3078142dfd88SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 3079142dfd88SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,check_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 3080142dfd88SStefano Zampini ierr = VecNorm(pcbddc->coarse_rhs,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 3081142dfd88SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 3082142dfd88SStefano Zampini /* get eigenvalue estimation if inexact */ 3083142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 3084142dfd88SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); 3085142dfd88SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&k);CHKERRQ(ierr); 3086142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues estimated with %d iterations of %s.\n",k,check_ksp_type);CHKERRQ(ierr); 3087e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues: % 1.14e %1.14e\n",lambda_min,lambda_max);CHKERRQ(ierr); 30883b03a366Sstefano_zampini } 3089142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem exact infty_error : %1.14e\n",infty_error);CHKERRQ(ierr); 3090142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem residual infty_error: %1.14e\n",abs_infty_error);CHKERRQ(ierr); 3091142dfd88SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 309253cdbc3dSStefano Zampini } 3093674ae819SStefano Zampini if (dbg_flag) { 3094da1bb401SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 3095da1bb401SStefano Zampini } 3096674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 3097a0ba757dSStefano Zampini 30980c7d97c5SJed Brown PetscFunctionReturn(0); 30990c7d97c5SJed Brown } 31000c7d97c5SJed Brown 3101