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 7a0ba757dSStefano Zampini - remove metis dependency -> use MatPartitioning for multilevel -> Assemble serial adjacency in ManageLocalBoundaries? 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 2207475bc1SBarry Smith #include "bddc.h" /*I "petscpc.h" I*/ 233b03a366Sstefano_zampini #include <petscblaslapack.h> 240c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 250c7d97c5SJed Brown #undef __FUNCT__ 260c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC" 270c7d97c5SJed Brown PetscErrorCode PCSetFromOptions_BDDC(PC pc) 280c7d97c5SJed Brown { 290c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 300c7d97c5SJed Brown PetscErrorCode ierr; 310c7d97c5SJed Brown 320c7d97c5SJed Brown PetscFunctionBegin; 330c7d97c5SJed Brown ierr = PetscOptionsHead("BDDC options");CHKERRQ(ierr); 340c7d97c5SJed Brown /* Verbose debugging of main data structures */ 35e269702eSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_check_all" ,"Verbose (debugging) output for PCBDDC" ,"none",pcbddc->dbg_flag ,&pcbddc->dbg_flag ,PETSC_NULL);CHKERRQ(ierr); 360c7d97c5SJed Brown /* Some customization for default primal space */ 37da1bb401SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_vertices_only" ,"Use only vertices in coarse space (i.e. discard constraints)","none",pcbddc->vertices_flag ,&pcbddc->vertices_flag ,PETSC_NULL);CHKERRQ(ierr); 38da1bb401SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_constraints_only","Use only constraints in coarse space (i.e. discard vertices)","none",pcbddc->constraints_flag,&pcbddc->constraints_flag,PETSC_NULL);CHKERRQ(ierr); 39da1bb401SStefano Zampini 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 ,PETSC_NULL);CHKERRQ(ierr); 40da1bb401SStefano Zampini 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 ,PETSC_NULL);CHKERRQ(ierr); 410c7d97c5SJed Brown /* Coarse solver context */ 426c667b0aSStefano 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 */ 430c7d97c5SJed Brown 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,PETSC_NULL);CHKERRQ(ierr); 440c7d97c5SJed Brown /* Two different application of BDDC to the whole set of dofs, internal and interface */ 4529622bf0SStefano Zampini 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,PETSC_NULL);CHKERRQ(ierr); 46534831adSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_change_of_basis","Use change of basis approach for primal space","none",pcbddc->usechangeofbasis,&pcbddc->usechangeofbasis,PETSC_NULL);CHKERRQ(ierr); 47534831adSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_change_on_faces","Use change of basis approach for face constraints","none",pcbddc->usechangeonfaces,&pcbddc->usechangeonfaces,PETSC_NULL);CHKERRQ(ierr); 48534831adSStefano Zampini pcbddc->usechangeonfaces = pcbddc->usechangeonfaces && pcbddc->usechangeofbasis; 490c7d97c5SJed Brown ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,PETSC_NULL);CHKERRQ(ierr); 504fad6a16SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_max_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,PETSC_NULL);CHKERRQ(ierr); 510c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 520c7d97c5SJed Brown PetscFunctionReturn(0); 530c7d97c5SJed Brown } 540c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 550c7d97c5SJed Brown EXTERN_C_BEGIN 560c7d97c5SJed Brown #undef __FUNCT__ 570c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType_BDDC" 5853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetCoarseProblemType_BDDC(PC pc, CoarseProblemType CPT) 590c7d97c5SJed Brown { 600c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 610c7d97c5SJed Brown 620c7d97c5SJed Brown PetscFunctionBegin; 630c7d97c5SJed Brown pcbddc->coarse_problem_type = CPT; 640c7d97c5SJed Brown PetscFunctionReturn(0); 650c7d97c5SJed Brown } 660c7d97c5SJed Brown EXTERN_C_END 670c7d97c5SJed Brown #undef __FUNCT__ 680c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType" 6953cdbc3dSStefano Zampini /*@ 709c0446d6SStefano Zampini PCBDDCSetCoarseProblemType - Set coarse problem type in PCBDDC. 7153cdbc3dSStefano Zampini 729c0446d6SStefano Zampini Not collective 7353cdbc3dSStefano Zampini 7453cdbc3dSStefano Zampini Input Parameters: 7553cdbc3dSStefano Zampini + pc - the preconditioning context 7653cdbc3dSStefano Zampini - CoarseProblemType - pick a better name and explain what this is 7753cdbc3dSStefano Zampini 7853cdbc3dSStefano Zampini Level: intermediate 7953cdbc3dSStefano Zampini 8053cdbc3dSStefano Zampini Notes: 81da1bb401SStefano Zampini Not collective but all procs must call with same arguments. 8253cdbc3dSStefano Zampini 8353cdbc3dSStefano Zampini .seealso: PCBDDC 8453cdbc3dSStefano Zampini @*/ 850c7d97c5SJed Brown PetscErrorCode PCBDDCSetCoarseProblemType(PC pc, CoarseProblemType CPT) 860c7d97c5SJed Brown { 870c7d97c5SJed Brown PetscErrorCode ierr; 880c7d97c5SJed Brown 890c7d97c5SJed Brown PetscFunctionBegin; 900c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 910c7d97c5SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetCoarseProblemType_C",(PC,CoarseProblemType),(pc,CPT));CHKERRQ(ierr); 920c7d97c5SJed Brown PetscFunctionReturn(0); 930c7d97c5SJed Brown } 940c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 950c7d97c5SJed Brown EXTERN_C_BEGIN 960c7d97c5SJed Brown #undef __FUNCT__ 974fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio_BDDC" 984fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 994fad6a16SStefano Zampini { 1004fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1014fad6a16SStefano Zampini 1024fad6a16SStefano Zampini PetscFunctionBegin; 1034fad6a16SStefano Zampini pcbddc->coarsening_ratio=k; 1044fad6a16SStefano Zampini PetscFunctionReturn(0); 1054fad6a16SStefano Zampini } 1064fad6a16SStefano Zampini EXTERN_C_END 1074fad6a16SStefano Zampini #undef __FUNCT__ 1084fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio" 1094fad6a16SStefano Zampini /*@ 1104fad6a16SStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel coarsening 1114fad6a16SStefano Zampini 1124fad6a16SStefano Zampini Logically collective on PC 1134fad6a16SStefano Zampini 1144fad6a16SStefano Zampini Input Parameters: 1154fad6a16SStefano Zampini + pc - the preconditioning context 1164fad6a16SStefano Zampini - k - coarsening ratio 1174fad6a16SStefano Zampini 1184fad6a16SStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level. 1194fad6a16SStefano Zampini 1204fad6a16SStefano Zampini Level: intermediate 1214fad6a16SStefano Zampini 1224fad6a16SStefano Zampini Notes: 1234fad6a16SStefano Zampini 1244fad6a16SStefano Zampini .seealso: PCBDDC 1254fad6a16SStefano Zampini @*/ 1264fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 1274fad6a16SStefano Zampini { 1284fad6a16SStefano Zampini PetscErrorCode ierr; 1294fad6a16SStefano Zampini 1304fad6a16SStefano Zampini PetscFunctionBegin; 1314fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1324fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 1334fad6a16SStefano Zampini PetscFunctionReturn(0); 1344fad6a16SStefano Zampini } 1354fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 1364fad6a16SStefano Zampini EXTERN_C_BEGIN 1374fad6a16SStefano Zampini #undef __FUNCT__ 1384fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetMaxLevels_BDDC" 1394fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetMaxLevels_BDDC(PC pc,PetscInt max_levels) 1404fad6a16SStefano Zampini { 1414fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1424fad6a16SStefano Zampini 1434fad6a16SStefano Zampini PetscFunctionBegin; 1444fad6a16SStefano Zampini pcbddc->max_levels=max_levels; 1454fad6a16SStefano Zampini PetscFunctionReturn(0); 1464fad6a16SStefano Zampini } 1474fad6a16SStefano Zampini EXTERN_C_END 1484fad6a16SStefano Zampini #undef __FUNCT__ 1494fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetMaxLevels" 1504fad6a16SStefano Zampini /*@ 1514fad6a16SStefano Zampini PCBDDCSetMaxLevels - Sets the maximum number of levels within the multilevel approach. 1524fad6a16SStefano Zampini 1534fad6a16SStefano Zampini Logically collective on PC 1544fad6a16SStefano Zampini 1554fad6a16SStefano Zampini Input Parameters: 1564fad6a16SStefano Zampini + pc - the preconditioning context 1574fad6a16SStefano Zampini - max_levels - the maximum number of levels 1584fad6a16SStefano Zampini 1594fad6a16SStefano Zampini Default value is 1, i.e. coarse problem will be solved inexactly with one application 1604fad6a16SStefano Zampini of PCBDDC preconditioner if the multilevel approach is requested. 1614fad6a16SStefano Zampini 1624fad6a16SStefano Zampini Level: intermediate 1634fad6a16SStefano Zampini 1644fad6a16SStefano Zampini Notes: 1654fad6a16SStefano Zampini 1664fad6a16SStefano Zampini .seealso: PCBDDC 1674fad6a16SStefano Zampini @*/ 1684fad6a16SStefano Zampini PetscErrorCode PCBDDCSetMaxLevels(PC pc,PetscInt max_levels) 1694fad6a16SStefano Zampini { 1704fad6a16SStefano Zampini PetscErrorCode ierr; 1714fad6a16SStefano Zampini 1724fad6a16SStefano Zampini PetscFunctionBegin; 1734fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1744fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetMaxLevels_C",(PC,PetscInt),(pc,max_levels));CHKERRQ(ierr); 1754fad6a16SStefano Zampini PetscFunctionReturn(0); 1764fad6a16SStefano Zampini } 1774fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 1784fad6a16SStefano Zampini EXTERN_C_BEGIN 1794fad6a16SStefano Zampini #undef __FUNCT__ 1800bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace_BDDC" 1810bdf917eSStefano Zampini static PetscErrorCode PCBDDCSetNullSpace_BDDC(PC pc,MatNullSpace NullSpace) 1820bdf917eSStefano Zampini { 1830bdf917eSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1840bdf917eSStefano Zampini PetscErrorCode ierr; 1850bdf917eSStefano Zampini 1860bdf917eSStefano Zampini PetscFunctionBegin; 1870bdf917eSStefano Zampini ierr = PetscObjectReference((PetscObject)NullSpace);CHKERRQ(ierr); 1880bdf917eSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 1890bdf917eSStefano Zampini pcbddc->NullSpace=NullSpace; 1900bdf917eSStefano Zampini PetscFunctionReturn(0); 1910bdf917eSStefano Zampini } 1920bdf917eSStefano Zampini EXTERN_C_END 1930bdf917eSStefano Zampini #undef __FUNCT__ 1940bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace" 1950bdf917eSStefano Zampini /*@ 1960bdf917eSStefano Zampini PCBDDCSetNullSpace - Set NullSpace of global operator of BDDC preconditioned mat. 1970bdf917eSStefano Zampini 1980bdf917eSStefano Zampini Logically collective on PC and MatNullSpace 1990bdf917eSStefano Zampini 2000bdf917eSStefano Zampini Input Parameters: 2010bdf917eSStefano Zampini + pc - the preconditioning context 2020bdf917eSStefano Zampini - NullSpace - Null space of the linear operator to be preconditioned. 2030bdf917eSStefano Zampini 2040bdf917eSStefano Zampini Level: intermediate 2050bdf917eSStefano Zampini 2060bdf917eSStefano Zampini Notes: 2070bdf917eSStefano Zampini 2080bdf917eSStefano Zampini .seealso: PCBDDC 2090bdf917eSStefano Zampini @*/ 2100bdf917eSStefano Zampini PetscErrorCode PCBDDCSetNullSpace(PC pc,MatNullSpace NullSpace) 2110bdf917eSStefano Zampini { 2120bdf917eSStefano Zampini PetscErrorCode ierr; 2130bdf917eSStefano Zampini 2140bdf917eSStefano Zampini PetscFunctionBegin; 2150bdf917eSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2160bdf917eSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNullSpace_C",(PC,MatNullSpace),(pc,NullSpace));CHKERRQ(ierr); 2170bdf917eSStefano Zampini PetscFunctionReturn(0); 2180bdf917eSStefano Zampini } 2190bdf917eSStefano Zampini /* -------------------------------------------------------------------------- */ 2200bdf917eSStefano Zampini EXTERN_C_BEGIN 2210bdf917eSStefano Zampini #undef __FUNCT__ 2223b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC" 2233b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 2243b03a366Sstefano_zampini { 2253b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2263b03a366Sstefano_zampini PetscErrorCode ierr; 2273b03a366Sstefano_zampini 2283b03a366Sstefano_zampini PetscFunctionBegin; 2293b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 23036e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 23136e030ebSStefano Zampini pcbddc->DirichletBoundaries=DirichletBoundaries; 2323b03a366Sstefano_zampini PetscFunctionReturn(0); 2333b03a366Sstefano_zampini } 2343b03a366Sstefano_zampini EXTERN_C_END 2353b03a366Sstefano_zampini #undef __FUNCT__ 2363b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries" 2373b03a366Sstefano_zampini /*@ 238da1bb401SStefano Zampini PCBDDCSetDirichletBoundaries - Set index set defining subdomain part (in local ordering) 239da1bb401SStefano Zampini of Dirichlet boundaries for the global problem. 2403b03a366Sstefano_zampini 2413b03a366Sstefano_zampini Not collective 2423b03a366Sstefano_zampini 2433b03a366Sstefano_zampini Input Parameters: 2443b03a366Sstefano_zampini + pc - the preconditioning context 2453b03a366Sstefano_zampini - DirichletBoundaries - sequential index set defining the subdomain part of Dirichlet boundaries (can be PETSC_NULL) 2463b03a366Sstefano_zampini 2473b03a366Sstefano_zampini Level: intermediate 2483b03a366Sstefano_zampini 2493b03a366Sstefano_zampini Notes: 2503b03a366Sstefano_zampini 2513b03a366Sstefano_zampini .seealso: PCBDDC 2523b03a366Sstefano_zampini @*/ 2533b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 2543b03a366Sstefano_zampini { 2553b03a366Sstefano_zampini PetscErrorCode ierr; 2563b03a366Sstefano_zampini 2573b03a366Sstefano_zampini PetscFunctionBegin; 2583b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2593b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 2603b03a366Sstefano_zampini PetscFunctionReturn(0); 2613b03a366Sstefano_zampini } 2623b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 2633b03a366Sstefano_zampini EXTERN_C_BEGIN 2643b03a366Sstefano_zampini #undef __FUNCT__ 2650c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 26653cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 2670c7d97c5SJed Brown { 2680c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 26953cdbc3dSStefano Zampini PetscErrorCode ierr; 2700c7d97c5SJed Brown 2710c7d97c5SJed Brown PetscFunctionBegin; 27253cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 27336e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 27436e030ebSStefano Zampini pcbddc->NeumannBoundaries=NeumannBoundaries; 2750c7d97c5SJed Brown PetscFunctionReturn(0); 2760c7d97c5SJed Brown } 2770c7d97c5SJed Brown EXTERN_C_END 2780c7d97c5SJed Brown #undef __FUNCT__ 2790c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 28057527edcSJed Brown /*@ 281da1bb401SStefano Zampini PCBDDCSetNeumannBoundaries - Set index set defining subdomain part (in local ordering) 282da1bb401SStefano Zampini of Neumann boundaries for the global problem. 28357527edcSJed Brown 2849c0446d6SStefano Zampini Not collective 28557527edcSJed Brown 28657527edcSJed Brown Input Parameters: 28757527edcSJed Brown + pc - the preconditioning context 2889c0446d6SStefano Zampini - NeumannBoundaries - sequential index set defining the subdomain part of Neumann boundaries (can be PETSC_NULL) 28957527edcSJed Brown 29057527edcSJed Brown Level: intermediate 29157527edcSJed Brown 29257527edcSJed Brown Notes: 29357527edcSJed Brown 29457527edcSJed Brown .seealso: PCBDDC 29557527edcSJed Brown @*/ 29653cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 2970c7d97c5SJed Brown { 2980c7d97c5SJed Brown PetscErrorCode ierr; 2990c7d97c5SJed Brown 3000c7d97c5SJed Brown PetscFunctionBegin; 3010c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 30253cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 30353cdbc3dSStefano Zampini PetscFunctionReturn(0); 30453cdbc3dSStefano Zampini } 30553cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 30653cdbc3dSStefano Zampini EXTERN_C_BEGIN 30753cdbc3dSStefano Zampini #undef __FUNCT__ 308da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC" 309da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 310da1bb401SStefano Zampini { 311da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 312da1bb401SStefano Zampini 313da1bb401SStefano Zampini PetscFunctionBegin; 314da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 315da1bb401SStefano Zampini PetscFunctionReturn(0); 316da1bb401SStefano Zampini } 317da1bb401SStefano Zampini EXTERN_C_END 318da1bb401SStefano Zampini #undef __FUNCT__ 319da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries" 320da1bb401SStefano Zampini /*@ 321da1bb401SStefano Zampini PCBDDCGetDirichletBoundaries - Get index set defining subdomain part (in local ordering) 322da1bb401SStefano Zampini of Dirichlet boundaries for the global problem. 323da1bb401SStefano Zampini 324da1bb401SStefano Zampini Not collective 325da1bb401SStefano Zampini 326da1bb401SStefano Zampini Input Parameters: 327da1bb401SStefano Zampini + pc - the preconditioning context 328da1bb401SStefano Zampini 329da1bb401SStefano Zampini Output Parameters: 330da1bb401SStefano Zampini + DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 331da1bb401SStefano Zampini 332da1bb401SStefano Zampini Level: intermediate 333da1bb401SStefano Zampini 334da1bb401SStefano Zampini Notes: 335da1bb401SStefano Zampini 336da1bb401SStefano Zampini .seealso: PCBDDC 337da1bb401SStefano Zampini @*/ 338da1bb401SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 339da1bb401SStefano Zampini { 340da1bb401SStefano Zampini PetscErrorCode ierr; 341da1bb401SStefano Zampini 342da1bb401SStefano Zampini PetscFunctionBegin; 343da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 344da1bb401SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 345da1bb401SStefano Zampini PetscFunctionReturn(0); 346da1bb401SStefano Zampini } 347da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 348da1bb401SStefano Zampini EXTERN_C_BEGIN 349da1bb401SStefano Zampini #undef __FUNCT__ 35053cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 35153cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 35253cdbc3dSStefano Zampini { 35353cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 35453cdbc3dSStefano Zampini 35553cdbc3dSStefano Zampini PetscFunctionBegin; 35653cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 35753cdbc3dSStefano Zampini PetscFunctionReturn(0); 35853cdbc3dSStefano Zampini } 35953cdbc3dSStefano Zampini EXTERN_C_END 36053cdbc3dSStefano Zampini #undef __FUNCT__ 36153cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 36253cdbc3dSStefano Zampini /*@ 363da1bb401SStefano Zampini PCBDDCGetNeumannBoundaries - Get index set defining subdomain part (in local ordering) 364da1bb401SStefano Zampini of Neumann boundaries for the global problem. 36553cdbc3dSStefano Zampini 3669c0446d6SStefano Zampini Not collective 36753cdbc3dSStefano Zampini 36853cdbc3dSStefano Zampini Input Parameters: 36953cdbc3dSStefano Zampini + pc - the preconditioning context 37053cdbc3dSStefano Zampini 37153cdbc3dSStefano Zampini Output Parameters: 37253cdbc3dSStefano Zampini + NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 37353cdbc3dSStefano Zampini 37453cdbc3dSStefano Zampini Level: intermediate 37553cdbc3dSStefano Zampini 37653cdbc3dSStefano Zampini Notes: 37753cdbc3dSStefano Zampini 37853cdbc3dSStefano Zampini .seealso: PCBDDC 37953cdbc3dSStefano Zampini @*/ 38053cdbc3dSStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 38153cdbc3dSStefano Zampini { 38253cdbc3dSStefano Zampini PetscErrorCode ierr; 38353cdbc3dSStefano Zampini 38453cdbc3dSStefano Zampini PetscFunctionBegin; 38553cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 38653cdbc3dSStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 3870c7d97c5SJed Brown PetscFunctionReturn(0); 3880c7d97c5SJed Brown } 38936e030ebSStefano Zampini /* -------------------------------------------------------------------------- */ 39036e030ebSStefano Zampini EXTERN_C_BEGIN 39136e030ebSStefano Zampini #undef __FUNCT__ 392da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC" 3931a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 39436e030ebSStefano Zampini { 39536e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 396da1bb401SStefano Zampini PCBDDCGraph mat_graph=pcbddc->mat_graph; 397da1bb401SStefano Zampini PetscErrorCode ierr; 39836e030ebSStefano Zampini 39936e030ebSStefano Zampini PetscFunctionBegin; 400da1bb401SStefano Zampini mat_graph->nvtxs=nvtxs; 401da1bb401SStefano Zampini ierr = PetscFree(mat_graph->xadj);CHKERRQ(ierr); 402da1bb401SStefano Zampini ierr = PetscFree(mat_graph->adjncy);CHKERRQ(ierr); 403da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 404da1bb401SStefano Zampini ierr = PetscMalloc((mat_graph->nvtxs+1)*sizeof(PetscInt),&mat_graph->xadj);CHKERRQ(ierr); 405da1bb401SStefano Zampini ierr = PetscMalloc(xadj[mat_graph->nvtxs]*sizeof(PetscInt),&mat_graph->adjncy);CHKERRQ(ierr); 406da1bb401SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(mat_graph->nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 407da1bb401SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[mat_graph->nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 408da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 4091a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 4101a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 411acee19a7SJed Brown } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d\n",copymode); 41236e030ebSStefano Zampini PetscFunctionReturn(0); 41336e030ebSStefano Zampini } 41436e030ebSStefano Zampini EXTERN_C_END 41536e030ebSStefano Zampini #undef __FUNCT__ 416da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph" 41736e030ebSStefano Zampini /*@ 418da1bb401SStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set CSR graph of local matrix for use of PCBDDC. 41936e030ebSStefano Zampini 42036e030ebSStefano Zampini Not collective 42136e030ebSStefano Zampini 42236e030ebSStefano Zampini Input Parameters: 42336e030ebSStefano Zampini + pc - the preconditioning context 424da1bb401SStefano Zampini - nvtxs - number of local vertices of the graph 425da1bb401SStefano Zampini - xadj, adjncy - the CSR graph 426da1bb401SStefano Zampini - copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER. In the former case the user must free the array passed in; 427da1bb401SStefano Zampini in the latter case, memory must be obtained with PetscMalloc. 42836e030ebSStefano Zampini 42936e030ebSStefano Zampini Level: intermediate 43036e030ebSStefano Zampini 43136e030ebSStefano Zampini Notes: 43236e030ebSStefano Zampini 43336e030ebSStefano Zampini .seealso: PCBDDC 43436e030ebSStefano Zampini @*/ 4351a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 43636e030ebSStefano Zampini { 437da1bb401SStefano Zampini PetscInt nrows,ncols; 438da1bb401SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 43936e030ebSStefano Zampini PetscErrorCode ierr; 44036e030ebSStefano Zampini 44136e030ebSStefano Zampini PetscFunctionBegin; 44236e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 443da1bb401SStefano Zampini ierr = MatGetSize(matis->A,&nrows,&ncols);CHKERRQ(ierr); 444f23aa3ddSBarry Smith if (nvtxs != nrows) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local adjacency size %d passed in %s differs from local problem size %d!\n",nvtxs,nrows); 445f23aa3ddSBarry Smith else { 4461a83f524SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 447da1bb401SStefano Zampini } 44836e030ebSStefano Zampini PetscFunctionReturn(0); 44936e030ebSStefano Zampini } 4509c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 4519c0446d6SStefano Zampini EXTERN_C_BEGIN 4529c0446d6SStefano Zampini #undef __FUNCT__ 4539c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 4549c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 4559c0446d6SStefano Zampini { 4569c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4579c0446d6SStefano Zampini PetscInt i; 4589c0446d6SStefano Zampini PetscErrorCode ierr; 4599c0446d6SStefano Zampini 4609c0446d6SStefano Zampini PetscFunctionBegin; 461da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 4629c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 4639c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 4649c0446d6SStefano Zampini } 465d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 466da1bb401SStefano Zampini /* allocate space then set */ 4679c0446d6SStefano Zampini ierr = PetscMalloc(n_is*sizeof(IS),&pcbddc->ISForDofs);CHKERRQ(ierr); 4689c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 469da1bb401SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 470da1bb401SStefano Zampini pcbddc->ISForDofs[i]=ISForDofs[i]; 4719c0446d6SStefano Zampini } 4729c0446d6SStefano Zampini pcbddc->n_ISForDofs=n_is; 4739c0446d6SStefano Zampini PetscFunctionReturn(0); 4749c0446d6SStefano Zampini } 4759c0446d6SStefano Zampini EXTERN_C_END 4769c0446d6SStefano Zampini #undef __FUNCT__ 4779c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 4789c0446d6SStefano Zampini /*@ 479da1bb401SStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of local mat. 4809c0446d6SStefano Zampini 4819c0446d6SStefano Zampini Not collective 4829c0446d6SStefano Zampini 4839c0446d6SStefano Zampini Input Parameters: 4849c0446d6SStefano Zampini + pc - the preconditioning context 485da1bb401SStefano Zampini - n - number of index sets defining the fields 486da1bb401SStefano Zampini - IS[] - array of IS describing the fields 4879c0446d6SStefano Zampini 4889c0446d6SStefano Zampini Level: intermediate 4899c0446d6SStefano Zampini 4909c0446d6SStefano Zampini Notes: 4919c0446d6SStefano Zampini 4929c0446d6SStefano Zampini .seealso: PCBDDC 4939c0446d6SStefano Zampini @*/ 4949c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 4959c0446d6SStefano Zampini { 4969c0446d6SStefano Zampini PetscErrorCode ierr; 4979c0446d6SStefano Zampini 4989c0446d6SStefano Zampini PetscFunctionBegin; 4999c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5009c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 5019c0446d6SStefano Zampini PetscFunctionReturn(0); 5029c0446d6SStefano Zampini } 503da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 504534831adSStefano Zampini #undef __FUNCT__ 505534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC" 506534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 507534831adSStefano Zampini /* 508534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 509534831adSStefano Zampini guess if a transformation of basis approach has been selected. 5109c0446d6SStefano Zampini 511534831adSStefano Zampini Input Parameter: 512534831adSStefano Zampini + pc - the preconditioner contex 513534831adSStefano Zampini 514534831adSStefano Zampini Application Interface Routine: PCPreSolve() 515534831adSStefano Zampini 516534831adSStefano Zampini Notes: 517534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 518534831adSStefano Zampini the user, but instead is called by KSPSolve(). 519534831adSStefano Zampini */ 520534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 521534831adSStefano Zampini { 522534831adSStefano Zampini PetscErrorCode ierr; 523534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 524534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 525534831adSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 526534831adSStefano Zampini Mat temp_mat; 5273972b0daSStefano Zampini IS dirIS; 5283972b0daSStefano Zampini PetscInt dirsize,i,*is_indices; 5293972b0daSStefano Zampini PetscScalar *array_x,*array_diagonal; 5303972b0daSStefano Zampini Vec used_vec; 5313972b0daSStefano Zampini PetscBool guess_nonzero; 532534831adSStefano Zampini 533534831adSStefano Zampini PetscFunctionBegin; 5343972b0daSStefano Zampini if (x) { 5353972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 5363972b0daSStefano Zampini used_vec = x; 5373972b0daSStefano Zampini } else { 5383972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 5393972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 5403972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 5413972b0daSStefano Zampini } 5423972b0daSStefano Zampini /* hack into ksp data structure PCPreSolve comes earlier in src/ksp/ksp/interface/itfunc.c */ 5433972b0daSStefano Zampini if (ksp) { 5443972b0daSStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&guess_nonzero);CHKERRQ(ierr); 5453972b0daSStefano Zampini if (!guess_nonzero) { 5463972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 5473972b0daSStefano Zampini } 5483972b0daSStefano Zampini } 5493972b0daSStefano Zampini /* store the original rhs */ 5503972b0daSStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 5513972b0daSStefano Zampini 5523972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 5533972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 5543972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 5553972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5563972b0daSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5573972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5583972b0daSStefano Zampini ierr = VecScatterEnd (matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5593972b0daSStefano Zampini ierr = PCBDDCGetDirichletBoundaries(pc,&dirIS);CHKERRQ(ierr); 5603972b0daSStefano Zampini if (dirIS) { 5613972b0daSStefano Zampini ierr = ISGetSize(dirIS,&dirsize);CHKERRQ(ierr); 5623972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 5633972b0daSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 5643972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5653972b0daSStefano Zampini for (i=0;i<dirsize;i++) { 5663972b0daSStefano Zampini array_x[is_indices[i]]=array_diagonal[is_indices[i]]; 5673972b0daSStefano Zampini } 5683972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5693972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 5703972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 5713972b0daSStefano Zampini } 5723972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5733972b0daSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 574b76ba322SStefano Zampini 5753972b0daSStefano Zampini /* remove the computed solution from the rhs */ 5763972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 5773972b0daSStefano Zampini ierr = MatMultAdd(pc->pmat,used_vec,rhs,rhs);CHKERRQ(ierr); 5783972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 579b76ba322SStefano Zampini 580b76ba322SStefano Zampini /* store partially computed solution and set initial guess */ 5813972b0daSStefano Zampini if (x) { 5823972b0daSStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 5833972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 584b76ba322SStefano Zampini if (pcbddc->use_exact_dirichlet) { 585b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 586b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 587b76ba322SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 588b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 589b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 590b76ba322SStefano Zampini if (ksp) { 591b76ba322SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 592b76ba322SStefano Zampini } 593b76ba322SStefano Zampini } 5943972b0daSStefano Zampini } 595b76ba322SStefano Zampini 596b76ba322SStefano Zampini /* rhs change of basis */ 597b76ba322SStefano Zampini if (pcbddc->usechangeofbasis) { 598b76ba322SStefano Zampini /* swap pointers for local matrices */ 599b76ba322SStefano Zampini temp_mat = matis->A; 600b76ba322SStefano Zampini matis->A = pcbddc->local_mat; 601b76ba322SStefano Zampini pcbddc->local_mat = temp_mat; 602b76ba322SStefano Zampini /* Get local rhs and apply transformation of basis */ 603b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 604b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 605b76ba322SStefano Zampini /* from original basis to modified basis */ 606b76ba322SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 607b76ba322SStefano Zampini /* put back modified values into the global vec using INSERT_VALUES copy mode */ 608b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 609b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6100bdf917eSStefano Zampini if (ksp && pcbddc->NullSpace) { 6110bdf917eSStefano Zampini ierr = MatNullSpaceRemove(pcbddc->NullSpace,used_vec,PETSC_NULL);CHKERRQ(ierr); 6120bdf917eSStefano Zampini ierr = MatNullSpaceRemove(pcbddc->NullSpace,rhs,PETSC_NULL);CHKERRQ(ierr); 613b76ba322SStefano Zampini } 6140bdf917eSStefano Zampini } 6150bdf917eSStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 616534831adSStefano Zampini PetscFunctionReturn(0); 617534831adSStefano Zampini } 618534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 619534831adSStefano Zampini #undef __FUNCT__ 620534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC" 621534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 622534831adSStefano Zampini /* 623534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 624534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 625534831adSStefano Zampini 626534831adSStefano Zampini Input Parameter: 627534831adSStefano Zampini + pc - the preconditioner contex 628534831adSStefano Zampini 629534831adSStefano Zampini Application Interface Routine: PCPostSolve() 630534831adSStefano Zampini 631534831adSStefano Zampini Notes: 632534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 633534831adSStefano Zampini the user, but instead is called by KSPSolve(). 634534831adSStefano Zampini */ 635534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 636534831adSStefano Zampini { 637534831adSStefano Zampini PetscErrorCode ierr; 638534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 639534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 640534831adSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 641534831adSStefano Zampini Mat temp_mat; 642534831adSStefano Zampini 643534831adSStefano Zampini PetscFunctionBegin; 644534831adSStefano Zampini if (pcbddc->usechangeofbasis) { 645534831adSStefano Zampini /* swap pointers for local matrices */ 646534831adSStefano Zampini temp_mat = matis->A; 647534831adSStefano Zampini matis->A = pcbddc->local_mat; 648534831adSStefano Zampini pcbddc->local_mat = temp_mat; 649534831adSStefano Zampini /* restore rhs to its original state */ 6503425bc38SStefano Zampini if (rhs) { 6513425bc38SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,rhs);CHKERRQ(ierr); 6523425bc38SStefano Zampini } 653534831adSStefano Zampini /* Get Local boundary and apply transformation of basis to solution vector */ 654534831adSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 655534831adSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 656534831adSStefano Zampini /* from modified basis to original basis */ 657534831adSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 658534831adSStefano Zampini /* put back modified values into the global vec using INSERT_VALUES copy mode */ 659534831adSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 660534831adSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 661534831adSStefano Zampini } 6623972b0daSStefano Zampini /* add solution removed in presolve */ 6633425bc38SStefano Zampini if (x) { 6643425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 6653425bc38SStefano Zampini } 666534831adSStefano Zampini PetscFunctionReturn(0); 667534831adSStefano Zampini } 668534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 66953cdbc3dSStefano Zampini #undef __FUNCT__ 67053cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 6710c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 6720c7d97c5SJed Brown /* 6730c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 6740c7d97c5SJed Brown by setting data structures and options. 6750c7d97c5SJed Brown 6760c7d97c5SJed Brown Input Parameter: 67753cdbc3dSStefano Zampini + pc - the preconditioner context 6780c7d97c5SJed Brown 6790c7d97c5SJed Brown Application Interface Routine: PCSetUp() 6800c7d97c5SJed Brown 6810c7d97c5SJed Brown Notes: 6820c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 6830c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 6840c7d97c5SJed Brown */ 68553cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 6860c7d97c5SJed Brown { 6870c7d97c5SJed Brown PetscErrorCode ierr; 6880c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 6890c7d97c5SJed Brown 6900c7d97c5SJed Brown PetscFunctionBegin; 6910c7d97c5SJed Brown if (!pc->setupcalled) { 6923b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 6939c0446d6SStefano Zampini So, we set to pcnone the Neumann problem of pcis in order to avoid unneeded computation 6940c7d97c5SJed Brown Also, we decide to directly build the (same) Dirichlet problem */ 6950c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localN_pc_type","none");CHKERRQ(ierr); 6960c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localD_pc_type","none");CHKERRQ(ierr); 6970c7d97c5SJed Brown /* Set up all the "iterative substructuring" common block */ 6980bdf917eSStefano Zampini 6990c7d97c5SJed Brown ierr = PCISSetUp(pc);CHKERRQ(ierr); 7003b03a366Sstefano_zampini /* Get stdout for dbg */ 701e269702eSStefano Zampini if (pcbddc->dbg_flag) { 702e269702eSStefano Zampini ierr = PetscViewerASCIIGetStdout(((PetscObject)pc)->comm,&pcbddc->dbg_viewer);CHKERRQ(ierr); 703e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 704e269702eSStefano Zampini } 7053b03a366Sstefano_zampini /* Analyze local interface */ 7060c7d97c5SJed Brown ierr = PCBDDCManageLocalBoundaries(pc);CHKERRQ(ierr); 7073b03a366Sstefano_zampini /* Set up local constraint matrix */ 7083b03a366Sstefano_zampini ierr = PCBDDCCreateConstraintMatrix(pc);CHKERRQ(ierr); 7090c7d97c5SJed Brown /* Create coarse and local stuffs used for evaluating action of preconditioner */ 7100c7d97c5SJed Brown ierr = PCBDDCCoarseSetUp(pc);CHKERRQ(ierr); 7110c7d97c5SJed Brown } 7120c7d97c5SJed Brown PetscFunctionReturn(0); 7130c7d97c5SJed Brown } 7140c7d97c5SJed Brown 7150c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 7160c7d97c5SJed Brown /* 7170c7d97c5SJed Brown PCApply_BDDC - Applies the BDDC preconditioner to a vector. 7180c7d97c5SJed Brown 7190c7d97c5SJed Brown Input Parameters: 7200c7d97c5SJed Brown . pc - the preconditioner context 7210c7d97c5SJed Brown . r - input vector (global) 7220c7d97c5SJed Brown 7230c7d97c5SJed Brown Output Parameter: 7240c7d97c5SJed Brown . z - output vector (global) 7250c7d97c5SJed Brown 7260c7d97c5SJed Brown Application Interface Routine: PCApply() 7270c7d97c5SJed Brown */ 7280c7d97c5SJed Brown #undef __FUNCT__ 7290c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 73053cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 7310c7d97c5SJed Brown { 7320c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 7330c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 7340c7d97c5SJed Brown PetscErrorCode ierr; 7353b03a366Sstefano_zampini const PetscScalar one = 1.0; 7363b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 7372617d88aSStefano Zampini const PetscScalar zero = 0.0; 7380c7d97c5SJed Brown 7390c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 7400c7d97c5SJed Brown NN interface preconditioner changed to BDDC 74129622bf0SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->inexact_prec_type = PETSC_TRUE) */ 7420c7d97c5SJed Brown 7430c7d97c5SJed Brown PetscFunctionBegin; 744b76ba322SStefano Zampini if (!pcbddc->use_exact_dirichlet) { 7450c7d97c5SJed Brown /* First Dirichlet solve */ 7460c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7470c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 74853cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 7490c7d97c5SJed Brown /* 7500c7d97c5SJed Brown Assembling right hand side for BDDC operator 7510c7d97c5SJed Brown - vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE) 7520c7d97c5SJed Brown - the interface part of the global vector z 7530c7d97c5SJed Brown */ 7540c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 7550c7d97c5SJed Brown ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 75629622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 7570c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 7580c7d97c5SJed Brown ierr = VecCopy(r,z);CHKERRQ(ierr); 7590c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7600c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7612617d88aSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7622617d88aSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 763b76ba322SStefano Zampini } else { 764b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,r,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 765b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,r,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7660bdf917eSStefano Zampini ierr = VecSet(pcis->vec1_D,zero);CHKERRQ(ierr); 767b76ba322SStefano Zampini ierr = VecSet(pcis->vec2_D,zero);CHKERRQ(ierr); 768b76ba322SStefano Zampini } 769b76ba322SStefano Zampini 770b76ba322SStefano Zampini /* Apply partition of unity */ 7712617d88aSStefano Zampini ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 7722617d88aSStefano Zampini 7732617d88aSStefano Zampini /* Apply interface preconditioner 7742617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 7752617d88aSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc);CHKERRQ(ierr); 7762617d88aSStefano Zampini 7772617d88aSStefano Zampini /* Apply partition of unity and sum boundary values */ 7782617d88aSStefano Zampini ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 7792617d88aSStefano Zampini ierr = VecSet(z,zero);CHKERRQ(ierr); 7802617d88aSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7812617d88aSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7820c7d97c5SJed Brown 7833b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 7840c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7850c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7860c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 78729622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 78853cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr); 7890c7d97c5SJed Brown ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr); 79029622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); } 7910c7d97c5SJed Brown ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr); 7920c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7930c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7940c7d97c5SJed Brown PetscFunctionReturn(0); 7950c7d97c5SJed Brown 7960c7d97c5SJed Brown } 797da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 798da1bb401SStefano Zampini #undef __FUNCT__ 799da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC" 800da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 801da1bb401SStefano Zampini { 802da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 8030bdf917eSStefano Zampini PetscInt i; 804da1bb401SStefano Zampini PetscErrorCode ierr; 805da1bb401SStefano Zampini 806da1bb401SStefano Zampini PetscFunctionBegin; 807da1bb401SStefano Zampini /* free data created by PCIS */ 808da1bb401SStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 809da1bb401SStefano Zampini /* free BDDC data */ 8100bdf917eSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->CoarseNullSpace);CHKERRQ(ierr); 8110bdf917eSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 8123972b0daSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 813534831adSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 814534831adSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 815534831adSStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 816da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 817da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_rhs);CHKERRQ(ierr); 818da1bb401SStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 819da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_mat);CHKERRQ(ierr); 820da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 821da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 822da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 823da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 824da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 825da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 826da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 827da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 828da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->vec4_D);CHKERRQ(ierr); 829da1bb401SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 830da1bb401SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 831da1bb401SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 832da1bb401SStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 833da1bb401SStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 834da1bb401SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 835da1bb401SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 836da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 837da1bb401SStefano Zampini ierr = PetscFree(pcbddc->local_primal_indices);CHKERRQ(ierr); 838da1bb401SStefano Zampini ierr = PetscFree(pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 8390bdf917eSStefano Zampini ierr = PetscFree(pcbddc->replicated_local_primal_values);CHKERRQ(ierr); 840da1bb401SStefano Zampini ierr = PetscFree(pcbddc->local_primal_displacements);CHKERRQ(ierr); 841da1bb401SStefano Zampini ierr = PetscFree(pcbddc->local_primal_sizes);CHKERRQ(ierr); 842da1bb401SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); } 843da1bb401SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 844da1bb401SStefano Zampini for (i=0;i<pcbddc->n_ISForFaces;i++) { ierr = ISDestroy(&pcbddc->ISForFaces[i]);CHKERRQ(ierr); } 845da1bb401SStefano Zampini ierr = PetscFree(pcbddc->ISForFaces);CHKERRQ(ierr); 846da1bb401SStefano Zampini for (i=0;i<pcbddc->n_ISForEdges;i++) { ierr = ISDestroy(&pcbddc->ISForEdges[i]);CHKERRQ(ierr); } 847da1bb401SStefano Zampini ierr = PetscFree(pcbddc->ISForEdges);CHKERRQ(ierr); 848da1bb401SStefano Zampini ierr = ISDestroy(&pcbddc->ISForVertices);CHKERRQ(ierr); 8493972b0daSStefano Zampini /* Free graph structure */ 850da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->xadj);CHKERRQ(ierr); 851da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->adjncy);CHKERRQ(ierr); 852142dfd88SStefano Zampini if (pcbddc->mat_graph->nvtxs) { 853da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->neighbours_set[0]);CHKERRQ(ierr); 854142dfd88SStefano Zampini } 855da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->neighbours_set);CHKERRQ(ierr); 8563972b0daSStefano Zampini ierr = PetscFree4(pcbddc->mat_graph->where,pcbddc->mat_graph->count,pcbddc->mat_graph->cptr,pcbddc->mat_graph->queue);CHKERRQ(ierr); 8573972b0daSStefano Zampini ierr = PetscFree2(pcbddc->mat_graph->which_dof,pcbddc->mat_graph->touched);CHKERRQ(ierr); 8583972b0daSStefano Zampini ierr = PetscFree(pcbddc->mat_graph->where_ncmps);CHKERRQ(ierr); 859da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr); 8603425bc38SStefano Zampini /* remove functions */ 8614fad6a16SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetCoarseningRatio_C","",PETSC_NULL);CHKERRQ(ierr); 8624fad6a16SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetMaxLevels_C","",PETSC_NULL);CHKERRQ(ierr); 8630bdf917eSStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetNullSpace_C","",PETSC_NULL);CHKERRQ(ierr); 8643425bc38SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C","",PETSC_NULL);CHKERRQ(ierr); 8653425bc38SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C","",PETSC_NULL);CHKERRQ(ierr); 8663425bc38SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C","",PETSC_NULL);CHKERRQ(ierr); 8673425bc38SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C","",PETSC_NULL);CHKERRQ(ierr); 8683425bc38SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetCoarseProblemType_C","",PETSC_NULL);CHKERRQ(ierr); 8693425bc38SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetDofsSplitting_C","",PETSC_NULL);CHKERRQ(ierr); 8703425bc38SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C","",PETSC_NULL);CHKERRQ(ierr); 8713425bc38SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCPreSolve_C","",PETSC_NULL);CHKERRQ(ierr); 8723425bc38SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCPostSolve_C","",PETSC_NULL);CHKERRQ(ierr); 8733425bc38SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C","",PETSC_NULL);CHKERRQ(ierr); 8743425bc38SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C","",PETSC_NULL);CHKERRQ(ierr); 8753425bc38SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C","",PETSC_NULL);CHKERRQ(ierr); 876da1bb401SStefano Zampini /* Free the private data structure that was hanging off the PC */ 877da1bb401SStefano Zampini ierr = PetscFree(pcbddc);CHKERRQ(ierr); 878da1bb401SStefano Zampini PetscFunctionReturn(0); 879da1bb401SStefano Zampini } 8803425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 8813425bc38SStefano Zampini EXTERN_C_BEGIN 8823425bc38SStefano Zampini #undef __FUNCT__ 8833425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC" 8843425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 8853425bc38SStefano Zampini { 8863425bc38SStefano Zampini FETIDPMat_ctx *mat_ctx; 8873425bc38SStefano Zampini PC_IS* pcis; 8883425bc38SStefano Zampini PC_BDDC* pcbddc; 8893425bc38SStefano Zampini PetscErrorCode ierr; 8900c7d97c5SJed Brown 8913425bc38SStefano Zampini PetscFunctionBegin; 8923425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 8933425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 8943425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 8953425bc38SStefano Zampini 8963425bc38SStefano Zampini /* change of basis for physical rhs if needed 8973425bc38SStefano Zampini It also changes the rhs in case of dirichlet boundaries */ 8983425bc38SStefano Zampini (*mat_ctx->pc->ops->presolve)(mat_ctx->pc,PETSC_NULL,standard_rhs,PETSC_NULL); 8993425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 9003425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9013425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9023425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9033425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9043425bc38SStefano Zampini /* scale rhs since it should be unassembled */ 9053425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 90629622bf0SStefano Zampini if (!pcbddc->inexact_prec_type) { 9073425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 9083425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 9093425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 9103425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 9113425bc38SStefano Zampini ierr = VecSet(standard_rhs,0.0);CHKERRQ(ierr); 9123425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9133425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9143425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9153425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9163425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 9173425bc38SStefano Zampini } 9183425bc38SStefano Zampini /* BDDC rhs */ 9193425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 92029622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { 9213425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 9223425bc38SStefano Zampini } 9233425bc38SStefano Zampini /* apply BDDC */ 9243425bc38SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr); 9253425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 9263425bc38SStefano Zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 9273425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 9283425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9293425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9303425bc38SStefano Zampini /* restore original rhs */ 9313425bc38SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,standard_rhs);CHKERRQ(ierr); 9323425bc38SStefano Zampini PetscFunctionReturn(0); 9333425bc38SStefano Zampini } 9343425bc38SStefano Zampini EXTERN_C_END 9353425bc38SStefano Zampini #undef __FUNCT__ 9363425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS" 9373425bc38SStefano Zampini /*@ 9383425bc38SStefano Zampini PCBDDCMatFETIDPGetRHS - Get rhs for FETIDP linear system. 9393425bc38SStefano Zampini 9403425bc38SStefano Zampini Collective 9413425bc38SStefano Zampini 9423425bc38SStefano Zampini Input Parameters: 9433425bc38SStefano Zampini + fetidp_mat - the FETIDP mat obtained by a call to PCBDDCCreateFETIDPOperators 9443425bc38SStefano Zampini + standard_rhs - the rhs of your linear system 9453425bc38SStefano Zampini 9463425bc38SStefano Zampini Output Parameters: 9473425bc38SStefano Zampini + fetidp_flux_rhs - the rhs of the FETIDP linear system 9483425bc38SStefano Zampini 9493425bc38SStefano Zampini Level: developer 9503425bc38SStefano Zampini 9513425bc38SStefano Zampini Notes: 9523425bc38SStefano Zampini 9533425bc38SStefano Zampini .seealso: PCBDDC 9543425bc38SStefano Zampini @*/ 9553425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 9563425bc38SStefano Zampini { 9573425bc38SStefano Zampini FETIDPMat_ctx *mat_ctx; 9583425bc38SStefano Zampini PetscErrorCode ierr; 9593425bc38SStefano Zampini 9603425bc38SStefano Zampini PetscFunctionBegin; 9613425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 9623425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 9633425bc38SStefano Zampini PetscFunctionReturn(0); 9643425bc38SStefano Zampini } 9653425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 9663425bc38SStefano Zampini EXTERN_C_BEGIN 9673425bc38SStefano Zampini #undef __FUNCT__ 9683425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC" 9693425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 9703425bc38SStefano Zampini { 9713425bc38SStefano Zampini FETIDPMat_ctx *mat_ctx; 9723425bc38SStefano Zampini PC_IS* pcis; 9733425bc38SStefano Zampini PC_BDDC* pcbddc; 9743425bc38SStefano Zampini PetscErrorCode ierr; 9753425bc38SStefano Zampini 9763425bc38SStefano Zampini PetscFunctionBegin; 9773425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 9783425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 9793425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 9803425bc38SStefano Zampini 9813425bc38SStefano Zampini /* apply B_delta^T */ 9823425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9833425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9843425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 9853425bc38SStefano Zampini /* compute rhs for BDDC application */ 9863425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 98729622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { 9883425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 9893425bc38SStefano Zampini } 9903425bc38SStefano Zampini /* apply BDDC */ 9913425bc38SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr); 9923425bc38SStefano Zampini /* put values into standard global vector */ 9933425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9943425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 99529622bf0SStefano Zampini if (!pcbddc->inexact_prec_type) { 9963425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 9973425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 9983425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_D,-1.0,pcis->vec1_D);CHKERRQ(ierr); 9993425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 10003425bc38SStefano Zampini } 10013425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10023425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10033425bc38SStefano Zampini /* final change of basis if needed 10043425bc38SStefano Zampini Is also sums the dirichlet part removed during RHS assembling */ 10053425bc38SStefano Zampini (*mat_ctx->pc->ops->postsolve)(mat_ctx->pc,PETSC_NULL,PETSC_NULL,standard_sol); 10063425bc38SStefano Zampini PetscFunctionReturn(0); 10073425bc38SStefano Zampini 10083425bc38SStefano Zampini } 10093425bc38SStefano Zampini EXTERN_C_END 10103425bc38SStefano Zampini #undef __FUNCT__ 10113425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution" 10123425bc38SStefano Zampini /*@ 10133425bc38SStefano Zampini PCBDDCMatFETIDPGetSolution - Get Solution for FETIDP linear system. 10143425bc38SStefano Zampini 10153425bc38SStefano Zampini Collective 10163425bc38SStefano Zampini 10173425bc38SStefano Zampini Input Parameters: 10183425bc38SStefano Zampini + fetidp_mat - the FETIDP mat obtained by a call to PCBDDCCreateFETIDPOperators 10193425bc38SStefano Zampini + fetidp_flux_sol - the solution of the FETIDP linear system 10203425bc38SStefano Zampini 10213425bc38SStefano Zampini Output Parameters: 10223425bc38SStefano Zampini + standard_sol - the solution on the global domain 10233425bc38SStefano Zampini 10243425bc38SStefano Zampini Level: developer 10253425bc38SStefano Zampini 10263425bc38SStefano Zampini Notes: 10273425bc38SStefano Zampini 10283425bc38SStefano Zampini .seealso: PCBDDC 10293425bc38SStefano Zampini @*/ 10303425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 10313425bc38SStefano Zampini { 10323425bc38SStefano Zampini FETIDPMat_ctx *mat_ctx; 10333425bc38SStefano Zampini PetscErrorCode ierr; 10343425bc38SStefano Zampini 10353425bc38SStefano Zampini PetscFunctionBegin; 10363425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 10373425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 10383425bc38SStefano Zampini PetscFunctionReturn(0); 10393425bc38SStefano Zampini } 10403425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 10413425bc38SStefano Zampini EXTERN_C_BEGIN 1042f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec); 1043f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat); 1044f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec); 1045f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC); 10463425bc38SStefano Zampini #undef __FUNCT__ 10473425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC" 10483425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 10493425bc38SStefano Zampini { 10503425bc38SStefano Zampini FETIDPMat_ctx *fetidpmat_ctx; 10513425bc38SStefano Zampini Mat newmat; 10523425bc38SStefano Zampini FETIDPPC_ctx *fetidppc_ctx; 10533425bc38SStefano Zampini PC newpc; 10543425bc38SStefano Zampini MPI_Comm comm = ((PetscObject)pc)->comm; 10553425bc38SStefano Zampini PetscErrorCode ierr; 10563425bc38SStefano Zampini 10573425bc38SStefano Zampini PetscFunctionBegin; 10583425bc38SStefano Zampini /* FETIDP linear matrix */ 10593425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc, &fetidpmat_ctx);CHKERRQ(ierr); 10603425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 10613425bc38SStefano Zampini ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 10623425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 10633425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 10643425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 10653425bc38SStefano Zampini /* FETIDP preconditioner */ 10663425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc, &fetidppc_ctx);CHKERRQ(ierr); 10673425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 10683425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 10693425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 10703425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 10713425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 10723425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 10733425bc38SStefano Zampini ierr = PCSetOperators(newpc,newmat,newmat,SAME_PRECONDITIONER);CHKERRQ(ierr); 10743425bc38SStefano Zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 10753425bc38SStefano Zampini /* return pointers for objects created */ 10763425bc38SStefano Zampini *fetidp_mat=newmat; 10773425bc38SStefano Zampini *fetidp_pc=newpc; 10783425bc38SStefano Zampini PetscFunctionReturn(0); 10793425bc38SStefano Zampini } 10803425bc38SStefano Zampini EXTERN_C_END 10813425bc38SStefano Zampini #undef __FUNCT__ 10823425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators" 10833425bc38SStefano Zampini /*@ 10843425bc38SStefano Zampini PCBDDCCreateFETIDPOperators - Create operators for FETIDP. 10853425bc38SStefano Zampini 10863425bc38SStefano Zampini Collective 10873425bc38SStefano Zampini 10883425bc38SStefano Zampini Input Parameters: 10893425bc38SStefano Zampini + pc - the BDDC preconditioning context (setup must be already called) 10903425bc38SStefano Zampini 10913425bc38SStefano Zampini Level: developer 10923425bc38SStefano Zampini 10933425bc38SStefano Zampini Notes: 10943425bc38SStefano Zampini 10953425bc38SStefano Zampini .seealso: PCBDDC 10963425bc38SStefano Zampini @*/ 10973425bc38SStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 10983425bc38SStefano Zampini { 10993425bc38SStefano Zampini PetscErrorCode ierr; 11003425bc38SStefano Zampini 11013425bc38SStefano Zampini PetscFunctionBegin; 11023425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 11033425bc38SStefano Zampini if (pc->setupcalled) { 11043425bc38SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,Mat*,PC*),(pc,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 1105f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n"); 11063425bc38SStefano Zampini PetscFunctionReturn(0); 11073425bc38SStefano Zampini } 11080c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1109da1bb401SStefano Zampini /*MC 1110da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 11110c7d97c5SJed Brown 1112da1bb401SStefano Zampini Options Database Keys: 1113da1bb401SStefano Zampini . -pcbddc ??? - 1114da1bb401SStefano Zampini 1115da1bb401SStefano Zampini Level: intermediate 1116da1bb401SStefano Zampini 1117da1bb401SStefano Zampini Notes: The matrix used with this preconditioner must be of type MATIS 1118da1bb401SStefano Zampini 1119da1bb401SStefano Zampini Unlike more 'conventional' interface preconditioners, this iterates over ALL the 1120da1bb401SStefano Zampini degrees of freedom, NOT just those on the interface (this allows the use of approximate solvers 1121da1bb401SStefano Zampini on the subdomains). 1122da1bb401SStefano Zampini 1123da1bb401SStefano Zampini Options for the coarse grid preconditioner can be set with - 1124da1bb401SStefano Zampini Options for the Dirichlet subproblem can be set with - 1125da1bb401SStefano Zampini Options for the Neumann subproblem can be set with - 1126da1bb401SStefano Zampini 1127da1bb401SStefano Zampini Contributed by Stefano Zampini 1128da1bb401SStefano Zampini 1129da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 1130da1bb401SStefano Zampini M*/ 1131da1bb401SStefano Zampini EXTERN_C_BEGIN 1132da1bb401SStefano Zampini #undef __FUNCT__ 1133da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC" 1134da1bb401SStefano Zampini PetscErrorCode PCCreate_BDDC(PC pc) 1135da1bb401SStefano Zampini { 1136da1bb401SStefano Zampini PetscErrorCode ierr; 1137da1bb401SStefano Zampini PC_BDDC *pcbddc; 1138da1bb401SStefano Zampini PCBDDCGraph mat_graph; 1139da1bb401SStefano Zampini 1140da1bb401SStefano Zampini PetscFunctionBegin; 1141da1bb401SStefano Zampini /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 1142da1bb401SStefano Zampini ierr = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr); 1143da1bb401SStefano Zampini pc->data = (void*)pcbddc; 1144da1bb401SStefano Zampini 1145da1bb401SStefano Zampini /* create PCIS data structure */ 1146da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 1147da1bb401SStefano Zampini 1148da1bb401SStefano Zampini /* BDDC specific */ 11490bdf917eSStefano Zampini pcbddc->CoarseNullSpace = 0; 11500bdf917eSStefano Zampini pcbddc->NullSpace = 0; 11513972b0daSStefano Zampini pcbddc->temp_solution = 0; 1152534831adSStefano Zampini pcbddc->original_rhs = 0; 1153534831adSStefano Zampini pcbddc->local_mat = 0; 1154534831adSStefano Zampini pcbddc->ChangeOfBasisMatrix = 0; 1155534831adSStefano Zampini pcbddc->usechangeofbasis = PETSC_TRUE; 1156534831adSStefano Zampini pcbddc->usechangeonfaces = PETSC_FALSE; 1157da1bb401SStefano Zampini pcbddc->coarse_vec = 0; 1158da1bb401SStefano Zampini pcbddc->coarse_rhs = 0; 1159da1bb401SStefano Zampini pcbddc->coarse_ksp = 0; 1160da1bb401SStefano Zampini pcbddc->coarse_phi_B = 0; 1161da1bb401SStefano Zampini pcbddc->coarse_phi_D = 0; 1162da1bb401SStefano Zampini pcbddc->vec1_P = 0; 1163da1bb401SStefano Zampini pcbddc->vec1_R = 0; 1164da1bb401SStefano Zampini pcbddc->vec2_R = 0; 1165da1bb401SStefano Zampini pcbddc->local_auxmat1 = 0; 1166da1bb401SStefano Zampini pcbddc->local_auxmat2 = 0; 1167da1bb401SStefano Zampini pcbddc->R_to_B = 0; 1168da1bb401SStefano Zampini pcbddc->R_to_D = 0; 1169da1bb401SStefano Zampini pcbddc->ksp_D = 0; 1170da1bb401SStefano Zampini pcbddc->ksp_R = 0; 1171da1bb401SStefano Zampini pcbddc->local_primal_indices = 0; 117229622bf0SStefano Zampini pcbddc->inexact_prec_type = PETSC_FALSE; 1173da1bb401SStefano Zampini pcbddc->NeumannBoundaries = 0; 1174da1bb401SStefano Zampini pcbddc->ISForDofs = 0; 1175da1bb401SStefano Zampini pcbddc->ISForVertices = 0; 1176da1bb401SStefano Zampini pcbddc->n_ISForFaces = 0; 1177da1bb401SStefano Zampini pcbddc->n_ISForEdges = 0; 1178da1bb401SStefano Zampini pcbddc->ConstraintMatrix = 0; 1179da1bb401SStefano Zampini pcbddc->use_nnsp_true = PETSC_FALSE; 1180da1bb401SStefano Zampini pcbddc->local_primal_sizes = 0; 1181da1bb401SStefano Zampini pcbddc->local_primal_displacements = 0; 1182da1bb401SStefano Zampini pcbddc->replicated_local_primal_indices = 0; 1183da1bb401SStefano Zampini pcbddc->replicated_local_primal_values = 0; 1184da1bb401SStefano Zampini pcbddc->coarse_loc_to_glob = 0; 1185da1bb401SStefano Zampini pcbddc->dbg_flag = PETSC_FALSE; 1186da1bb401SStefano Zampini pcbddc->coarsening_ratio = 8; 1187b76ba322SStefano Zampini pcbddc->use_exact_dirichlet = PETSC_TRUE; 11884fad6a16SStefano Zampini pcbddc->current_level = 0; 11894fad6a16SStefano Zampini pcbddc->max_levels = 1; 1190da1bb401SStefano Zampini 1191da1bb401SStefano Zampini /* allocate and initialize needed graph structure */ 1192da1bb401SStefano Zampini ierr = PetscMalloc(sizeof(*mat_graph),&pcbddc->mat_graph);CHKERRQ(ierr); 1193da1bb401SStefano Zampini pcbddc->mat_graph->xadj = 0; 1194da1bb401SStefano Zampini pcbddc->mat_graph->adjncy = 0; 1195da1bb401SStefano Zampini 1196da1bb401SStefano Zampini /* function pointers */ 1197da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 1198da1bb401SStefano Zampini pc->ops->applytranspose = 0; 1199da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 1200da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 1201da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 1202da1bb401SStefano Zampini pc->ops->view = 0; 1203da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 1204da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 1205da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 1206534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 1207534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 1208da1bb401SStefano Zampini 1209da1bb401SStefano Zampini /* composing function */ 12104fad6a16SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetCoarseningRatio_C","PCBDDCSetCoarseningRatio_BDDC", 12114fad6a16SStefano Zampini PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 12124fad6a16SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetMaxLevels_C","PCBDDCSetMaxLevels_BDDC", 12134fad6a16SStefano Zampini PCBDDCSetMaxLevels_BDDC);CHKERRQ(ierr); 12140bdf917eSStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetNullSpace_C","PCBDDCSetNullSpace_BDDC", 12150bdf917eSStefano Zampini PCBDDCSetNullSpace_BDDC);CHKERRQ(ierr); 1216da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C","PCBDDCSetDirichletBoundaries_BDDC", 1217da1bb401SStefano Zampini PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 1218da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C","PCBDDCSetNeumannBoundaries_BDDC", 1219da1bb401SStefano Zampini PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 1220da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C","PCBDDCGetDirichletBoundaries_BDDC", 1221da1bb401SStefano Zampini PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 1222da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C","PCBDDCGetNeumannBoundaries_BDDC", 1223da1bb401SStefano Zampini PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 1224da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetCoarseProblemType_C","PCBDDCSetCoarseProblemType_BDDC", 1225da1bb401SStefano Zampini PCBDDCSetCoarseProblemType_BDDC);CHKERRQ(ierr); 1226da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetDofsSplitting_C","PCBDDCSetDofsSplitting_BDDC", 1227da1bb401SStefano Zampini PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 1228da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C","PCBDDCSetLocalAdjacencyGraph_BDDC", 1229da1bb401SStefano Zampini PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 1230534831adSStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCPreSolve_C","PCPreSolve_BDDC", 1231534831adSStefano Zampini PCPreSolve_BDDC);CHKERRQ(ierr); 1232534831adSStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCPostSolve_C","PCPostSolve_BDDC", 1233534831adSStefano Zampini PCPostSolve_BDDC);CHKERRQ(ierr); 12343425bc38SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C","PCBDDCCreateFETIDPOperators_BDDC", 12353425bc38SStefano Zampini PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 12363425bc38SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C","PCBDDCMatFETIDPGetRHS_BDDC", 12373425bc38SStefano Zampini PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 12383425bc38SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C","PCBDDCMatFETIDPGetSolution_BDDC", 12393425bc38SStefano Zampini PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 1240da1bb401SStefano Zampini PetscFunctionReturn(0); 1241da1bb401SStefano Zampini } 1242da1bb401SStefano Zampini EXTERN_C_END 12433425bc38SStefano Zampini 1244da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 1245da1bb401SStefano Zampini /* All static functions from now on */ 1246da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 12474fad6a16SStefano Zampini #undef __FUNCT__ 124829622bf0SStefano Zampini #define __FUNCT__ "PCBDDCApplyNullSpaceCorrectionPC" 124929622bf0SStefano Zampini static PetscErrorCode PCBDDCApplyNullSpaceCorrectionPC(PC pc,Vec x,Vec y) 125029622bf0SStefano Zampini { 125129622bf0SStefano Zampini NullSpaceCorrection_ctx *pc_ctx; 125229622bf0SStefano Zampini PetscErrorCode ierr; 125329622bf0SStefano Zampini 125429622bf0SStefano Zampini PetscFunctionBegin; 125529622bf0SStefano Zampini ierr = PCShellGetContext(pc,(void**)&pc_ctx);CHKERRQ(ierr); 125629622bf0SStefano Zampini /* E */ 125729622bf0SStefano Zampini ierr = MatMultTranspose(pc_ctx->Lbasis_mat,x,pc_ctx->work_small_2);CHKERRQ(ierr); 125829622bf0SStefano Zampini ierr = MatMultAdd(pc_ctx->Kbasis_mat,pc_ctx->work_small_2,x,pc_ctx->work_full_1);CHKERRQ(ierr); 125929622bf0SStefano Zampini /* P^-1 */ 126029622bf0SStefano Zampini ierr = PCApply(pc_ctx->local_pc,pc_ctx->work_full_1,pc_ctx->work_full_2);CHKERRQ(ierr); 126129622bf0SStefano Zampini /* E^T */ 126229622bf0SStefano Zampini ierr = MatMultTranspose(pc_ctx->Kbasis_mat,pc_ctx->work_full_2,pc_ctx->work_small_1);CHKERRQ(ierr); 126329622bf0SStefano Zampini ierr = VecScale(pc_ctx->work_small_1,-1.0);CHKERRQ(ierr); 126429622bf0SStefano Zampini ierr = MatMultAdd(pc_ctx->Lbasis_mat,pc_ctx->work_small_1,pc_ctx->work_full_2,pc_ctx->work_full_1);CHKERRQ(ierr); 126529622bf0SStefano Zampini /* Sum contributions */ 126629622bf0SStefano Zampini ierr = MatMultAdd(pc_ctx->basis_mat,pc_ctx->work_small_2,pc_ctx->work_full_1,y);CHKERRQ(ierr); 126729622bf0SStefano Zampini PetscFunctionReturn(0); 126829622bf0SStefano Zampini } 126929622bf0SStefano Zampini 127029622bf0SStefano Zampini #undef __FUNCT__ 127129622bf0SStefano Zampini #define __FUNCT__ "PCBDDCDestroyNullSpaceCorrectionPC" 127229622bf0SStefano Zampini static PetscErrorCode PCBDDCDestroyNullSpaceCorrectionPC(PC pc) 127329622bf0SStefano Zampini { 127429622bf0SStefano Zampini NullSpaceCorrection_ctx *pc_ctx; 127529622bf0SStefano Zampini PetscErrorCode ierr; 127629622bf0SStefano Zampini 127729622bf0SStefano Zampini PetscFunctionBegin; 127829622bf0SStefano Zampini ierr = PCShellGetContext(pc,(void**)&pc_ctx);CHKERRQ(ierr); 127929622bf0SStefano Zampini ierr = VecDestroy(&pc_ctx->work_small_1);CHKERRQ(ierr); 128029622bf0SStefano Zampini ierr = VecDestroy(&pc_ctx->work_small_2);CHKERRQ(ierr); 128129622bf0SStefano Zampini ierr = VecDestroy(&pc_ctx->work_full_1);CHKERRQ(ierr); 128229622bf0SStefano Zampini ierr = VecDestroy(&pc_ctx->work_full_2);CHKERRQ(ierr); 128329622bf0SStefano Zampini ierr = MatDestroy(&pc_ctx->basis_mat);CHKERRQ(ierr); 128429622bf0SStefano Zampini ierr = MatDestroy(&pc_ctx->Lbasis_mat);CHKERRQ(ierr); 128529622bf0SStefano Zampini ierr = MatDestroy(&pc_ctx->Kbasis_mat);CHKERRQ(ierr); 128629622bf0SStefano Zampini ierr = PCDestroy(&pc_ctx->local_pc);CHKERRQ(ierr); 128729622bf0SStefano Zampini ierr = PetscFree(pc_ctx);CHKERRQ(ierr); 128829622bf0SStefano Zampini PetscFunctionReturn(0); 128929622bf0SStefano Zampini } 129029622bf0SStefano Zampini 129129622bf0SStefano Zampini #undef __FUNCT__ 129229622bf0SStefano Zampini #define __FUNCT__ "PCBDDCAdaptLocalProblem" 129329622bf0SStefano Zampini static PetscErrorCode PCBDDCAdaptLocalProblem(PC pc,IS local_dofs) 129429622bf0SStefano Zampini { 1295f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCApplyNullSpaceCorrectionPC(PC,Vec,Vec); 1296f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyNullSpaceCorrectionPC(PC); 129729622bf0SStefano Zampini 129829622bf0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 129929622bf0SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 130029622bf0SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 130129622bf0SStefano Zampini KSP *local_ksp; 130229622bf0SStefano Zampini PC newpc; 130329622bf0SStefano Zampini NullSpaceCorrection_ctx *shell_ctx; 130429622bf0SStefano Zampini Mat local_mat,local_pmat,small_mat,inv_small_mat; 130529622bf0SStefano Zampini MatStructure local_mat_struct; 130629622bf0SStefano Zampini Vec work1,work2,work3; 130729622bf0SStefano Zampini const Vec *nullvecs; 130829622bf0SStefano Zampini VecScatter scatter_ctx; 130929622bf0SStefano Zampini IS is_aux; 131029622bf0SStefano Zampini MatFactorInfo matinfo; 131129622bf0SStefano Zampini PetscScalar *basis_mat,*Kbasis_mat,*array,*array_mat; 131229622bf0SStefano Zampini PetscScalar one = 1.0,zero = 0.0, m_one = -1.0; 131329622bf0SStefano Zampini PetscInt basis_dofs,basis_size,nnsp_size,i,k,n_I,n_R; 131429622bf0SStefano Zampini PetscBool nnsp_has_cnst; 131529622bf0SStefano Zampini PetscErrorCode ierr; 131629622bf0SStefano Zampini 131729622bf0SStefano Zampini PetscFunctionBegin; 131829622bf0SStefano Zampini /* Infer the local solver */ 131929622bf0SStefano Zampini ierr = ISGetSize(local_dofs,&basis_dofs);CHKERRQ(ierr); 132029622bf0SStefano Zampini ierr = VecGetSize(pcis->vec1_D,&n_I);CHKERRQ(ierr); 132129622bf0SStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&n_R);CHKERRQ(ierr); 132229622bf0SStefano Zampini if (basis_dofs == n_I) { 132329622bf0SStefano Zampini /* Dirichlet solver */ 132429622bf0SStefano Zampini local_ksp = &pcbddc->ksp_D; 132529622bf0SStefano Zampini } else if (basis_dofs == n_R) { 132629622bf0SStefano Zampini /* Neumann solver */ 132729622bf0SStefano Zampini local_ksp = &pcbddc->ksp_R; 1328f23aa3ddSBarry Smith } else SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in %s: unknown local IS size %d. n_I=%d, n_R=%d)\n",basis_dofs,n_I,n_R); 132929622bf0SStefano Zampini ierr = KSPGetOperators(*local_ksp,&local_mat,&local_pmat,&local_mat_struct);CHKERRQ(ierr); 133029622bf0SStefano Zampini 133129622bf0SStefano Zampini /* Get null space vecs */ 133229622bf0SStefano Zampini ierr = MatNullSpaceGetVecs(pcbddc->NullSpace,&nnsp_has_cnst,&nnsp_size,&nullvecs);CHKERRQ(ierr); 133329622bf0SStefano Zampini basis_size = nnsp_size; 133429622bf0SStefano Zampini if (nnsp_has_cnst) { 133529622bf0SStefano Zampini basis_size++; 133629622bf0SStefano Zampini } 133729622bf0SStefano Zampini 133829622bf0SStefano Zampini /* Create shell ctx */ 133929622bf0SStefano Zampini ierr = PetscMalloc(sizeof(*shell_ctx),&shell_ctx);CHKERRQ(ierr); 134029622bf0SStefano Zampini 134129622bf0SStefano Zampini /* Create work vectors in shell context */ 134229622bf0SStefano Zampini ierr = VecCreate(PETSC_COMM_SELF,&shell_ctx->work_small_1);CHKERRQ(ierr); 134329622bf0SStefano Zampini ierr = VecSetSizes(shell_ctx->work_small_1,basis_size,basis_size);CHKERRQ(ierr); 134429622bf0SStefano Zampini ierr = VecSetType(shell_ctx->work_small_1,VECSEQ);CHKERRQ(ierr); 134529622bf0SStefano Zampini ierr = VecDuplicate(shell_ctx->work_small_1,&shell_ctx->work_small_2);CHKERRQ(ierr); 134629622bf0SStefano Zampini ierr = VecCreate(PETSC_COMM_SELF,&shell_ctx->work_full_1);CHKERRQ(ierr); 134729622bf0SStefano Zampini ierr = VecSetSizes(shell_ctx->work_full_1,basis_dofs,basis_dofs);CHKERRQ(ierr); 134829622bf0SStefano Zampini ierr = VecSetType(shell_ctx->work_full_1,VECSEQ);CHKERRQ(ierr); 134929622bf0SStefano Zampini ierr = VecDuplicate(shell_ctx->work_full_1,&shell_ctx->work_full_2);CHKERRQ(ierr); 135029622bf0SStefano Zampini 135129622bf0SStefano Zampini /* Allocate workspace */ 135229622bf0SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,basis_dofs,basis_size,PETSC_NULL,&shell_ctx->basis_mat);CHKERRQ(ierr); 135329622bf0SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,basis_dofs,basis_size,PETSC_NULL,&shell_ctx->Kbasis_mat);CHKERRQ(ierr); 135429622bf0SStefano Zampini ierr = MatDenseGetArray(shell_ctx->basis_mat,&basis_mat);CHKERRQ(ierr); 135529622bf0SStefano Zampini ierr = MatDenseGetArray(shell_ctx->Kbasis_mat,&Kbasis_mat);CHKERRQ(ierr); 135629622bf0SStefano Zampini 135729622bf0SStefano Zampini /* Restrict local null space on selected dofs (Dirichlet or Neumann) 135829622bf0SStefano Zampini and compute matrices N and K*N */ 135929622bf0SStefano Zampini ierr = VecDuplicate(shell_ctx->work_full_1,&work1);CHKERRQ(ierr); 136029622bf0SStefano Zampini ierr = VecDuplicate(shell_ctx->work_full_1,&work2);CHKERRQ(ierr); 136129622bf0SStefano Zampini ierr = VecScatterCreate(pcis->vec1_N,local_dofs,work1,(IS)0,&scatter_ctx);CHKERRQ(ierr); 136229622bf0SStefano Zampini k=0; 136329622bf0SStefano Zampini for (;k<nnsp_size;k++) { 136429622bf0SStefano Zampini ierr = VecScatterBegin(matis->ctx,nullvecs[k],pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 136529622bf0SStefano Zampini ierr = VecScatterEnd(matis->ctx,nullvecs[k],pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 136629622bf0SStefano Zampini ierr = VecPlaceArray(work1,(const PetscScalar*)&basis_mat[k*basis_dofs]);CHKERRQ(ierr); 136729622bf0SStefano Zampini ierr = VecScatterBegin(scatter_ctx,pcis->vec1_N,work1,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 136829622bf0SStefano Zampini ierr = VecScatterEnd(scatter_ctx,pcis->vec1_N,work1,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 136929622bf0SStefano Zampini ierr = VecPlaceArray(work2,(const PetscScalar*)&Kbasis_mat[k*basis_dofs]);CHKERRQ(ierr); 137029622bf0SStefano Zampini ierr = MatMult(local_mat,work1,work2);CHKERRQ(ierr); 137129622bf0SStefano Zampini ierr = VecResetArray(work1);CHKERRQ(ierr); 137229622bf0SStefano Zampini ierr = VecResetArray(work2);CHKERRQ(ierr); 137329622bf0SStefano Zampini } 137429622bf0SStefano Zampini if (nnsp_has_cnst) { 137529622bf0SStefano Zampini ierr = VecPlaceArray(work1,(const PetscScalar*)&basis_mat[k*basis_dofs]);CHKERRQ(ierr); 137629622bf0SStefano Zampini ierr = VecSet(work1,one);CHKERRQ(ierr); 137729622bf0SStefano Zampini ierr = VecPlaceArray(work2,(const PetscScalar*)&Kbasis_mat[k*basis_dofs]);CHKERRQ(ierr); 137829622bf0SStefano Zampini ierr = MatMult(local_mat,work1,work2);CHKERRQ(ierr); 137929622bf0SStefano Zampini ierr = VecResetArray(work1);CHKERRQ(ierr); 138029622bf0SStefano Zampini ierr = VecResetArray(work2);CHKERRQ(ierr); 138129622bf0SStefano Zampini } 138229622bf0SStefano Zampini ierr = VecDestroy(&work1);CHKERRQ(ierr); 138329622bf0SStefano Zampini ierr = VecDestroy(&work2);CHKERRQ(ierr); 138429622bf0SStefano Zampini ierr = VecScatterDestroy(&scatter_ctx);CHKERRQ(ierr); 138529622bf0SStefano Zampini ierr = MatDenseRestoreArray(shell_ctx->basis_mat,&basis_mat);CHKERRQ(ierr); 138629622bf0SStefano Zampini ierr = MatDenseRestoreArray(shell_ctx->Kbasis_mat,&Kbasis_mat);CHKERRQ(ierr); 138729622bf0SStefano Zampini 138829622bf0SStefano Zampini /* Assemble another Mat object in shell context */ 138929622bf0SStefano Zampini ierr = MatTransposeMatMult(shell_ctx->basis_mat,shell_ctx->Kbasis_mat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&small_mat);CHKERRQ(ierr); 139029622bf0SStefano Zampini ierr = MatFactorInfoInitialize(&matinfo);CHKERRQ(ierr); 139129622bf0SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,basis_size,0,1,&is_aux);CHKERRQ(ierr); 139229622bf0SStefano Zampini ierr = MatLUFactor(small_mat,is_aux,is_aux,&matinfo);CHKERRQ(ierr); 139329622bf0SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 139429622bf0SStefano Zampini ierr = PetscMalloc(basis_size*basis_size*sizeof(PetscScalar),&array_mat);CHKERRQ(ierr); 139529622bf0SStefano Zampini for (k=0;k<basis_size;k++) { 139629622bf0SStefano Zampini ierr = VecSet(shell_ctx->work_small_1,zero);CHKERRQ(ierr); 139729622bf0SStefano Zampini ierr = VecSetValue(shell_ctx->work_small_1,k,one,INSERT_VALUES);CHKERRQ(ierr); 139829622bf0SStefano Zampini ierr = VecAssemblyBegin(shell_ctx->work_small_1);CHKERRQ(ierr); 139929622bf0SStefano Zampini ierr = VecAssemblyEnd(shell_ctx->work_small_1);CHKERRQ(ierr); 140029622bf0SStefano Zampini ierr = MatSolve(small_mat,shell_ctx->work_small_1,shell_ctx->work_small_2);CHKERRQ(ierr); 140129622bf0SStefano Zampini ierr = VecGetArray(shell_ctx->work_small_2,&array);CHKERRQ(ierr); 140229622bf0SStefano Zampini for (i=0;i<basis_size;i++) { 140329622bf0SStefano Zampini array_mat[i*basis_size+k]=array[i]; 140429622bf0SStefano Zampini } 140529622bf0SStefano Zampini ierr = VecRestoreArray(shell_ctx->work_small_2,&array);CHKERRQ(ierr); 140629622bf0SStefano Zampini } 140729622bf0SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,basis_size,basis_size,array_mat,&inv_small_mat);CHKERRQ(ierr); 140829622bf0SStefano Zampini ierr = MatMatMult(shell_ctx->basis_mat,inv_small_mat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&shell_ctx->Lbasis_mat);CHKERRQ(ierr); 140929622bf0SStefano Zampini ierr = PetscFree(array_mat);CHKERRQ(ierr); 141029622bf0SStefano Zampini ierr = MatDestroy(&inv_small_mat);CHKERRQ(ierr); 141129622bf0SStefano Zampini ierr = MatDestroy(&small_mat);CHKERRQ(ierr); 141229622bf0SStefano Zampini ierr = MatScale(shell_ctx->Kbasis_mat,m_one);CHKERRQ(ierr); 141329622bf0SStefano Zampini 141429622bf0SStefano Zampini /* Rebuild local PC */ 141529622bf0SStefano Zampini ierr = KSPGetPC(*local_ksp,&shell_ctx->local_pc);CHKERRQ(ierr); 141629622bf0SStefano Zampini ierr = PetscObjectReference((PetscObject)shell_ctx->local_pc);CHKERRQ(ierr); 141729622bf0SStefano Zampini ierr = PCCreate(PETSC_COMM_SELF,&newpc);CHKERRQ(ierr); 141829622bf0SStefano Zampini ierr = PCSetOperators(newpc,local_mat,local_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 141929622bf0SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 142029622bf0SStefano Zampini ierr = PCShellSetContext(newpc,shell_ctx);CHKERRQ(ierr); 142129622bf0SStefano Zampini ierr = PCShellSetApply(newpc,PCBDDCApplyNullSpaceCorrectionPC);CHKERRQ(ierr); 142229622bf0SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyNullSpaceCorrectionPC);CHKERRQ(ierr); 142329622bf0SStefano Zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 142429622bf0SStefano Zampini ierr = KSPSetPC(*local_ksp,newpc);CHKERRQ(ierr); 142529622bf0SStefano Zampini ierr = PCDestroy(&newpc);CHKERRQ(ierr); 142629622bf0SStefano Zampini ierr = KSPSetUp(*local_ksp);CHKERRQ(ierr); 142729622bf0SStefano Zampini 142829622bf0SStefano Zampini /* test */ 142929622bf0SStefano Zampini if (pcbddc->dbg_flag) { 143029622bf0SStefano Zampini PetscReal test_err; 143129622bf0SStefano Zampini KSP check_ksp; 143229622bf0SStefano Zampini PC check_pc; 143329622bf0SStefano Zampini PetscReal lambda_min,lambda_max; 143429622bf0SStefano Zampini Mat test_mat; 143529622bf0SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 143629622bf0SStefano Zampini PetscBool setsym,issym=PETSC_FALSE; 143729622bf0SStefano Zampini 143829622bf0SStefano Zampini ierr = KSPGetPC(*local_ksp,&check_pc);CHKERRQ(ierr); 143929622bf0SStefano Zampini ierr = VecDuplicate(shell_ctx->work_full_1,&work1);CHKERRQ(ierr); 144029622bf0SStefano Zampini ierr = VecDuplicate(shell_ctx->work_full_1,&work2);CHKERRQ(ierr); 144129622bf0SStefano Zampini ierr = VecDuplicate(shell_ctx->work_full_1,&work3);CHKERRQ(ierr); 144229622bf0SStefano Zampini ierr = VecSetRandom(shell_ctx->work_small_1,PETSC_NULL);CHKERRQ(ierr); 144329622bf0SStefano Zampini ierr = MatMult(shell_ctx->basis_mat,shell_ctx->work_small_1,work1);CHKERRQ(ierr); 144429622bf0SStefano Zampini ierr = VecCopy(work1,work2);CHKERRQ(ierr); 144529622bf0SStefano Zampini ierr = MatMult(local_mat,work1,work3);CHKERRQ(ierr); 144629622bf0SStefano Zampini ierr = PCApply(check_pc,work3,work1);CHKERRQ(ierr); 144729622bf0SStefano Zampini ierr = VecAXPY(work1,m_one,work2);CHKERRQ(ierr); 144829622bf0SStefano Zampini ierr = VecNorm(work1,NORM_INFINITY,&test_err);CHKERRQ(ierr); 144929622bf0SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d error for nullspace correction for ",PetscGlobalRank); 145029622bf0SStefano Zampini if (basis_dofs == n_I) { 145129622bf0SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Dirichlet "); 145229622bf0SStefano Zampini } else { 145329622bf0SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Neumann "); 145429622bf0SStefano Zampini } 145529622bf0SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"solver is :%1.14e\n",test_err); 145629622bf0SStefano Zampini 145729622bf0SStefano Zampini ierr = MatTransposeMatMult(shell_ctx->Lbasis_mat,shell_ctx->Kbasis_mat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&test_mat);CHKERRQ(ierr); 145829622bf0SStefano Zampini ierr = MatShift(test_mat,one);CHKERRQ(ierr); 145929622bf0SStefano Zampini ierr = MatNorm(test_mat,NORM_INFINITY,&test_err);CHKERRQ(ierr); 146029622bf0SStefano Zampini ierr = MatDestroy(&test_mat);CHKERRQ(ierr); 146129622bf0SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d error for nullspace matrices is :%1.14e\n",PetscGlobalRank,test_err); 146229622bf0SStefano Zampini 146329622bf0SStefano Zampini /* Create ksp object suitable for extreme eigenvalues' estimation */ 146429622bf0SStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&check_ksp);CHKERRQ(ierr); 146529622bf0SStefano Zampini ierr = KSPSetOperators(check_ksp,local_mat,local_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 146629622bf0SStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-8,1.e-8,PETSC_DEFAULT,basis_dofs);CHKERRQ(ierr); 146729622bf0SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,PETSC_TRUE);CHKERRQ(ierr); 146829622bf0SStefano Zampini ierr = MatIsSymmetricKnown(pc->pmat,&setsym,&issym);CHKERRQ(ierr); 146929622bf0SStefano Zampini if (issym) { 147029622bf0SStefano Zampini ierr = KSPSetType(check_ksp,KSPCG);CHKERRQ(ierr); 147129622bf0SStefano Zampini } 147229622bf0SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 147329622bf0SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 147429622bf0SStefano Zampini ierr = VecSetRandom(work1,PETSC_NULL);CHKERRQ(ierr); 147529622bf0SStefano Zampini ierr = MatMult(local_mat,work1,work2);CHKERRQ(ierr); 147629622bf0SStefano Zampini ierr = KSPSolve(check_ksp,work2,work2);CHKERRQ(ierr); 147729622bf0SStefano Zampini ierr = VecAXPY(work2,m_one,work1);CHKERRQ(ierr); 147829622bf0SStefano Zampini ierr = VecNorm(work2,NORM_INFINITY,&test_err);CHKERRQ(ierr); 147929622bf0SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); 148029622bf0SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&k);CHKERRQ(ierr); 148129622bf0SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d error for adapted KSP %1.14e (it %d, eigs %1.6e %1.6e)\n",PetscGlobalRank,test_err,k,lambda_min,lambda_max); 148229622bf0SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 148329622bf0SStefano Zampini ierr = VecDestroy(&work1);CHKERRQ(ierr); 148429622bf0SStefano Zampini ierr = VecDestroy(&work2);CHKERRQ(ierr); 148529622bf0SStefano Zampini ierr = VecDestroy(&work3);CHKERRQ(ierr); 148629622bf0SStefano Zampini } 148729622bf0SStefano Zampini PetscFunctionReturn(0); 148829622bf0SStefano Zampini } 148929622bf0SStefano Zampini 149029622bf0SStefano Zampini #undef __FUNCT__ 14912e8d2280SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet" 14922e8d2280SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool use) 14932e8d2280SStefano Zampini { 14942e8d2280SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 14952e8d2280SStefano Zampini 14962e8d2280SStefano Zampini PetscFunctionBegin; 14972e8d2280SStefano Zampini pcbddc->use_exact_dirichlet=use; 14982e8d2280SStefano Zampini PetscFunctionReturn(0); 14992e8d2280SStefano Zampini } 15002e8d2280SStefano Zampini 15012e8d2280SStefano Zampini #undef __FUNCT__ 15024fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel" 15034fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 15044fad6a16SStefano Zampini { 15054fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15064fad6a16SStefano Zampini 15074fad6a16SStefano Zampini PetscFunctionBegin; 15084fad6a16SStefano Zampini pcbddc->current_level=level; 15094fad6a16SStefano Zampini PetscFunctionReturn(0); 15104fad6a16SStefano Zampini } 15113425bc38SStefano Zampini 15123425bc38SStefano Zampini #undef __FUNCT__ 15130bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCAdaptNullSpace" 15140bdf917eSStefano Zampini static PetscErrorCode PCBDDCAdaptNullSpace(PC pc) 15150bdf917eSStefano Zampini { 15160bdf917eSStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 15170bdf917eSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 15180bdf917eSStefano Zampini KSP inv_change; 15190bdf917eSStefano Zampini PC pc_change; 15200bdf917eSStefano Zampini const Vec *nsp_vecs; 15210bdf917eSStefano Zampini Vec *new_nsp_vecs; 15220bdf917eSStefano Zampini PetscInt i,nsp_size,new_nsp_size,start_new; 15230bdf917eSStefano Zampini PetscBool nsp_has_cnst; 15240bdf917eSStefano Zampini MatNullSpace new_nsp; 15250bdf917eSStefano Zampini PetscErrorCode ierr; 15260bdf917eSStefano Zampini 15270bdf917eSStefano Zampini PetscFunctionBegin; 15280bdf917eSStefano Zampini ierr = MatNullSpaceGetVecs(pcbddc->NullSpace,&nsp_has_cnst,&nsp_size,&nsp_vecs);CHKERRQ(ierr); 15290bdf917eSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&inv_change);CHKERRQ(ierr); 15300bdf917eSStefano Zampini ierr = KSPSetOperators(inv_change,pcbddc->ChangeOfBasisMatrix,pcbddc->ChangeOfBasisMatrix,SAME_PRECONDITIONER);CHKERRQ(ierr); 15310bdf917eSStefano Zampini ierr = KSPSetType(inv_change,KSPPREONLY);CHKERRQ(ierr); 15320bdf917eSStefano Zampini ierr = KSPGetPC(inv_change,&pc_change);CHKERRQ(ierr); 15330bdf917eSStefano Zampini ierr = PCSetType(pc_change,PCLU);CHKERRQ(ierr); 15340bdf917eSStefano Zampini ierr = KSPSetUp(inv_change);CHKERRQ(ierr); 15350bdf917eSStefano Zampini new_nsp_size = nsp_size; 15360bdf917eSStefano Zampini if (nsp_has_cnst) { new_nsp_size++; } 15370bdf917eSStefano Zampini ierr = PetscMalloc(new_nsp_size*sizeof(Vec),&new_nsp_vecs);CHKERRQ(ierr); 15380bdf917eSStefano Zampini for (i=0;i<new_nsp_size;i++) { ierr = VecDuplicate(pcis->vec1_global,&new_nsp_vecs[i]);CHKERRQ(ierr); } 15390bdf917eSStefano Zampini start_new = 0; 15400bdf917eSStefano Zampini if (nsp_has_cnst) { 15410bdf917eSStefano Zampini start_new = 1; 15420bdf917eSStefano Zampini ierr = VecSet(new_nsp_vecs[0],1.0);CHKERRQ(ierr); 15430bdf917eSStefano Zampini ierr = VecSet(pcis->vec1_B,1.0);CHKERRQ(ierr); 15440bdf917eSStefano Zampini ierr = KSPSolve(inv_change,pcis->vec1_B,pcis->vec1_B); 15450bdf917eSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,new_nsp_vecs[0],INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15460bdf917eSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,new_nsp_vecs[0],INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15470bdf917eSStefano Zampini } 15480bdf917eSStefano Zampini for (i=0;i<nsp_size;i++) { 15490bdf917eSStefano Zampini ierr = VecCopy(nsp_vecs[i],new_nsp_vecs[i+start_new]);CHKERRQ(ierr); 15500bdf917eSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,nsp_vecs[i],pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15510bdf917eSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,nsp_vecs[i],pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15520bdf917eSStefano Zampini ierr = KSPSolve(inv_change,pcis->vec1_B,pcis->vec1_B); 15530bdf917eSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,new_nsp_vecs[i+start_new],INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15540bdf917eSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,new_nsp_vecs[i+start_new],INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15550bdf917eSStefano Zampini } 15560bdf917eSStefano Zampini ierr = VecNormalize(new_nsp_vecs[0],PETSC_NULL);CHKERRQ(ierr); 15570bdf917eSStefano Zampini /* TODO : Orthonormalize vecs when new_nsp_size > 0! */ 15580bdf917eSStefano Zampini 15590bdf917eSStefano Zampini ierr = KSPDestroy(&inv_change);CHKERRQ(ierr); 15600bdf917eSStefano Zampini ierr = MatNullSpaceCreate(((PetscObject)pc)->comm,PETSC_FALSE,new_nsp_size,new_nsp_vecs,&new_nsp);CHKERRQ(ierr); 15610bdf917eSStefano Zampini ierr = PCBDDCSetNullSpace(pc,new_nsp);CHKERRQ(ierr); 15620bdf917eSStefano Zampini ierr = MatNullSpaceDestroy(&new_nsp);CHKERRQ(ierr); 15630bdf917eSStefano Zampini /* 15640bdf917eSStefano Zampini ierr = MatNullSpaceTest(pcbddc->NullSpace,pc->pmat,&nsp_t);CHKERRQ(ierr); 15650bdf917eSStefano Zampini printf("New Null Space, mat changed: %d\n",nsp_t); 15660bdf917eSStefano Zampini temp_mat = matis->A; 15670bdf917eSStefano Zampini matis->A = pcbddc->local_mat; 15680bdf917eSStefano Zampini pcbddc->local_mat = temp_mat; 15690bdf917eSStefano Zampini ierr = MatNullSpaceTest(pcbddc->NullSpace,pc->pmat,&nsp_t);CHKERRQ(ierr); 15700bdf917eSStefano Zampini printf("New Null Space, mat original: %d\n",nsp_t);*/ 15710bdf917eSStefano Zampini 15720bdf917eSStefano Zampini for (i=0;i<new_nsp_size;i++) { ierr = VecDestroy(&new_nsp_vecs[i]);CHKERRQ(ierr); } 15730bdf917eSStefano Zampini ierr = PetscFree(new_nsp_vecs);CHKERRQ(ierr); 15740bdf917eSStefano Zampini PetscFunctionReturn(0); 15750bdf917eSStefano Zampini } 15760bdf917eSStefano Zampini 15770bdf917eSStefano Zampini #undef __FUNCT__ 15783425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPMatContext" 15793425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPMatContext(PC pc, FETIDPMat_ctx **fetidpmat_ctx) 15803425bc38SStefano Zampini { 15813425bc38SStefano Zampini FETIDPMat_ctx *newctx; 15823425bc38SStefano Zampini PetscErrorCode ierr; 15833425bc38SStefano Zampini 15843425bc38SStefano Zampini PetscFunctionBegin; 15853425bc38SStefano Zampini ierr = PetscMalloc(sizeof(*newctx),&newctx);CHKERRQ(ierr); 15863425bc38SStefano Zampini newctx->lambda_local = 0; 15873425bc38SStefano Zampini newctx->temp_solution_B = 0; 15883425bc38SStefano Zampini newctx->temp_solution_D = 0; 15893425bc38SStefano Zampini newctx->B_delta = 0; 15903425bc38SStefano Zampini newctx->B_Ddelta = 0; /* theoretically belongs to the FETIDP preconditioner */ 15913425bc38SStefano Zampini newctx->l2g_lambda = 0; 15923425bc38SStefano Zampini /* increase the reference count for BDDC preconditioner */ 15933425bc38SStefano Zampini ierr = PetscObjectReference((PetscObject)pc);CHKERRQ(ierr); 15943425bc38SStefano Zampini newctx->pc = pc; 15953425bc38SStefano Zampini *fetidpmat_ctx = newctx; 15963425bc38SStefano Zampini PetscFunctionReturn(0); 15973425bc38SStefano Zampini } 15983425bc38SStefano Zampini 15993425bc38SStefano Zampini #undef __FUNCT__ 16003425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPPCContext" 16013425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPPCContext(PC pc, FETIDPPC_ctx **fetidppc_ctx) 16023425bc38SStefano Zampini { 16033425bc38SStefano Zampini FETIDPPC_ctx *newctx; 16043425bc38SStefano Zampini PetscErrorCode ierr; 16053425bc38SStefano Zampini 16063425bc38SStefano Zampini PetscFunctionBegin; 16073425bc38SStefano Zampini ierr = PetscMalloc(sizeof(*newctx),&newctx);CHKERRQ(ierr); 16083425bc38SStefano Zampini newctx->lambda_local = 0; 16093425bc38SStefano Zampini newctx->B_Ddelta = 0; 16103425bc38SStefano Zampini newctx->l2g_lambda = 0; 16113425bc38SStefano Zampini /* increase the reference count for BDDC preconditioner */ 16123425bc38SStefano Zampini ierr = PetscObjectReference((PetscObject)pc);CHKERRQ(ierr); 16133425bc38SStefano Zampini newctx->pc = pc; 16143425bc38SStefano Zampini *fetidppc_ctx = newctx; 16153425bc38SStefano Zampini PetscFunctionReturn(0); 16163425bc38SStefano Zampini } 16173425bc38SStefano Zampini 16183425bc38SStefano Zampini #undef __FUNCT__ 16193425bc38SStefano Zampini #define __FUNCT__ "PCBDDCDestroyFETIDPMat" 16203425bc38SStefano Zampini static PetscErrorCode PCBDDCDestroyFETIDPMat(Mat A) 16213425bc38SStefano Zampini { 16223425bc38SStefano Zampini FETIDPMat_ctx *mat_ctx; 16233425bc38SStefano Zampini PetscErrorCode ierr; 16243425bc38SStefano Zampini 16253425bc38SStefano Zampini PetscFunctionBegin; 16263425bc38SStefano Zampini ierr = MatShellGetContext(A,(void**)&mat_ctx);CHKERRQ(ierr); 16273425bc38SStefano Zampini ierr = VecDestroy(&mat_ctx->lambda_local);CHKERRQ(ierr); 16283425bc38SStefano Zampini ierr = VecDestroy(&mat_ctx->temp_solution_D);CHKERRQ(ierr); 16293425bc38SStefano Zampini ierr = VecDestroy(&mat_ctx->temp_solution_B);CHKERRQ(ierr); 16303425bc38SStefano Zampini ierr = MatDestroy(&mat_ctx->B_delta);CHKERRQ(ierr); 16313425bc38SStefano Zampini ierr = MatDestroy(&mat_ctx->B_Ddelta);CHKERRQ(ierr); 16323425bc38SStefano Zampini ierr = VecScatterDestroy(&mat_ctx->l2g_lambda);CHKERRQ(ierr); 16333425bc38SStefano Zampini ierr = PCDestroy(&mat_ctx->pc);CHKERRQ(ierr); /* actually it does not destroy BDDC, only decrease its reference count */ 16343425bc38SStefano Zampini ierr = PetscFree(mat_ctx);CHKERRQ(ierr); 16353425bc38SStefano Zampini PetscFunctionReturn(0); 16363425bc38SStefano Zampini } 16373425bc38SStefano Zampini 16383425bc38SStefano Zampini #undef __FUNCT__ 16393425bc38SStefano Zampini #define __FUNCT__ "PCBDDCDestroyFETIDPPC" 16403425bc38SStefano Zampini static PetscErrorCode PCBDDCDestroyFETIDPPC(PC pc) 16413425bc38SStefano Zampini { 16423425bc38SStefano Zampini FETIDPPC_ctx *pc_ctx; 16433425bc38SStefano Zampini PetscErrorCode ierr; 16443425bc38SStefano Zampini 16453425bc38SStefano Zampini PetscFunctionBegin; 16463425bc38SStefano Zampini ierr = PCShellGetContext(pc,(void**)&pc_ctx);CHKERRQ(ierr); 16473425bc38SStefano Zampini ierr = VecDestroy(&pc_ctx->lambda_local);CHKERRQ(ierr); 16483425bc38SStefano Zampini ierr = MatDestroy(&pc_ctx->B_Ddelta);CHKERRQ(ierr); 16493425bc38SStefano Zampini ierr = VecScatterDestroy(&pc_ctx->l2g_lambda);CHKERRQ(ierr); 16503425bc38SStefano Zampini ierr = PCDestroy(&pc_ctx->pc);CHKERRQ(ierr); /* actually it does not destroy BDDC, only decrease its reference count */ 16513425bc38SStefano Zampini ierr = PetscFree(pc_ctx);CHKERRQ(ierr); 16523425bc38SStefano Zampini PetscFunctionReturn(0); 16533425bc38SStefano Zampini } 16543425bc38SStefano Zampini 16553425bc38SStefano Zampini #undef __FUNCT__ 16563425bc38SStefano Zampini #define __FUNCT__ "PCBDDCSetupFETIDPMatContext" 16573425bc38SStefano Zampini static PetscErrorCode PCBDDCSetupFETIDPMatContext(FETIDPMat_ctx *fetidpmat_ctx) 16583425bc38SStefano Zampini { 16593425bc38SStefano Zampini PetscErrorCode ierr; 16603425bc38SStefano Zampini PC_IS *pcis=(PC_IS*)fetidpmat_ctx->pc->data; 16613425bc38SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)fetidpmat_ctx->pc->data; 16623425bc38SStefano Zampini PCBDDCGraph mat_graph=pcbddc->mat_graph; 16633425bc38SStefano Zampini Mat_IS *matis = (Mat_IS*)fetidpmat_ctx->pc->pmat->data; 16643425bc38SStefano Zampini MPI_Comm comm = ((PetscObject)(fetidpmat_ctx->pc))->comm; 16653425bc38SStefano Zampini 16663425bc38SStefano Zampini Mat ScalingMat; 16673425bc38SStefano Zampini Vec lambda_global; 16683425bc38SStefano Zampini IS IS_l2g_lambda; 16693425bc38SStefano Zampini 16703425bc38SStefano Zampini PetscBool skip_node,fully_redundant; 1671ef028eecSStefano Zampini PetscInt i,j,k,s,n_boundary_dofs,n_global_lambda,n_vertices,partial_sum; 16723425bc38SStefano Zampini PetscInt n_local_lambda,n_lambda_for_dof,dual_size,n_neg_values,n_pos_values; 1673ef028eecSStefano Zampini PetscMPIInt rank,nprocs; 16743425bc38SStefano Zampini PetscScalar scalar_value; 16753425bc38SStefano Zampini 16763425bc38SStefano Zampini PetscInt *vertex_indices,*temp_indices; 16773425bc38SStefano Zampini PetscInt *dual_dofs_boundary_indices,*aux_local_numbering_1,*aux_global_numbering; 16783425bc38SStefano Zampini PetscInt *aux_sums,*cols_B_delta,*l2g_indices; 16793425bc38SStefano Zampini PetscScalar *array,*scaling_factors,*vals_B_delta; 1680ef028eecSStefano Zampini PetscInt *aux_local_numbering_2,*dof_sizes,*dof_displs; 1681ef028eecSStefano Zampini PetscInt first_index,old_index; 1682ef028eecSStefano Zampini PetscBool first_found = PETSC_FALSE; 16833425bc38SStefano Zampini 16843425bc38SStefano Zampini /* For communication of scaling factors */ 16853425bc38SStefano Zampini PetscInt *ptrs_buffer,neigh_position; 16863425bc38SStefano Zampini PetscScalar **all_factors,*send_buffer,*recv_buffer; 16873425bc38SStefano Zampini MPI_Request *send_reqs,*recv_reqs; 16883425bc38SStefano Zampini 16893425bc38SStefano Zampini /* tests */ 16903425bc38SStefano Zampini Vec test_vec; 16913425bc38SStefano Zampini PetscBool test_fetidp; 16923425bc38SStefano Zampini PetscViewer viewer; 16933425bc38SStefano Zampini 16943425bc38SStefano Zampini PetscFunctionBegin; 16953425bc38SStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 16963425bc38SStefano Zampini ierr = MPI_Comm_size(comm,&nprocs);CHKERRQ(ierr); 16973425bc38SStefano Zampini 16983425bc38SStefano Zampini /* Default type of lagrange multipliers is non-redundant */ 16993425bc38SStefano Zampini fully_redundant = PETSC_FALSE; 17003425bc38SStefano Zampini ierr = PetscOptionsGetBool(PETSC_NULL,"-fetidp_fullyredundant",&fully_redundant,PETSC_NULL);CHKERRQ(ierr); 17013425bc38SStefano Zampini 17023425bc38SStefano Zampini /* Evaluate local and global number of lagrange multipliers */ 17033425bc38SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 17043425bc38SStefano Zampini n_local_lambda = 0; 17053425bc38SStefano Zampini partial_sum = 0; 17063425bc38SStefano Zampini n_boundary_dofs = 0; 17073425bc38SStefano Zampini s = 0; 17083425bc38SStefano Zampini n_vertices = 0; 17093425bc38SStefano Zampini /* Get Vertices used to define the BDDC */ 17103425bc38SStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(*vertex_indices),&vertex_indices);CHKERRQ(ierr); 17113425bc38SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 17123425bc38SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&j,(const PetscInt**)&temp_indices,PETSC_NULL);CHKERRQ(ierr); 17133425bc38SStefano Zampini if (j == 1) { 17143425bc38SStefano Zampini vertex_indices[n_vertices]=temp_indices[0]; 17153425bc38SStefano Zampini n_vertices++; 17163425bc38SStefano Zampini } 17173425bc38SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&j,(const PetscInt**)&temp_indices,PETSC_NULL);CHKERRQ(ierr); 17183425bc38SStefano Zampini } 17193425bc38SStefano Zampini dual_size = pcis->n_B-n_vertices; 1720f0474715SStefano Zampini ierr = PetscSortInt(n_vertices,vertex_indices);CHKERRQ(ierr); 17213425bc38SStefano Zampini ierr = PetscMalloc(dual_size*sizeof(*dual_dofs_boundary_indices),&dual_dofs_boundary_indices);CHKERRQ(ierr); 17223425bc38SStefano Zampini ierr = PetscMalloc(dual_size*sizeof(*aux_local_numbering_1),&aux_local_numbering_1);CHKERRQ(ierr); 17233425bc38SStefano Zampini ierr = PetscMalloc(dual_size*sizeof(*aux_local_numbering_2),&aux_local_numbering_2);CHKERRQ(ierr); 17243425bc38SStefano Zampini 17253425bc38SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 17263425bc38SStefano Zampini for (i=0;i<pcis->n;i++) { 17273425bc38SStefano Zampini j = mat_graph->count[i]; /* RECALL: mat_graph->count[i] does not count myself */ 1728c6582918SStefano Zampini k = 0; 1729c6582918SStefano Zampini if (j > 0) { 17303425bc38SStefano Zampini k = (mat_graph->neighbours_set[i][0] == -1 ? 1 : 0); 1731c6582918SStefano Zampini } 17323425bc38SStefano Zampini j = j - k ; 17333425bc38SStefano Zampini if (j > 0) { n_boundary_dofs++; } 17343425bc38SStefano Zampini 17353425bc38SStefano Zampini skip_node = PETSC_FALSE; 1736c6582918SStefano Zampini if (s < n_vertices && vertex_indices[s]==i) { /* it works for a sorted set of vertices */ 17373425bc38SStefano Zampini skip_node = PETSC_TRUE; 17383425bc38SStefano Zampini s++; 17393425bc38SStefano Zampini } 17403425bc38SStefano Zampini if (j < 1) {skip_node = PETSC_TRUE;} 17413425bc38SStefano Zampini if (!skip_node) { 17423425bc38SStefano Zampini if (fully_redundant) { 17433425bc38SStefano Zampini /* fully redundant set of lagrange multipliers */ 17443425bc38SStefano Zampini n_lambda_for_dof = (j*(j+1))/2; 17453425bc38SStefano Zampini } else { 17463425bc38SStefano Zampini n_lambda_for_dof = j; 17473425bc38SStefano Zampini } 17483425bc38SStefano Zampini n_local_lambda += j; 17493425bc38SStefano Zampini /* needed to evaluate global number of lagrange multipliers */ 17503425bc38SStefano Zampini array[i]=(1.0*n_lambda_for_dof)/(j+1.0); /* already scaled for the next global sum */ 17513425bc38SStefano Zampini /* store some data needed */ 17523425bc38SStefano Zampini dual_dofs_boundary_indices[partial_sum] = n_boundary_dofs-1; 17533425bc38SStefano Zampini aux_local_numbering_1[partial_sum] = i; 1754ef028eecSStefano Zampini aux_local_numbering_2[partial_sum] = n_lambda_for_dof; 17553425bc38SStefano Zampini partial_sum++; 17563425bc38SStefano Zampini } 17573425bc38SStefano Zampini } 17583425bc38SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1759ef028eecSStefano Zampini 17603425bc38SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 17613425bc38SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 17623425bc38SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 17633425bc38SStefano Zampini ierr = VecSum(pcis->vec1_global,&scalar_value);CHKERRQ(ierr); 17643425bc38SStefano Zampini fetidpmat_ctx->n_lambda = (PetscInt) scalar_value; 17653425bc38SStefano Zampini /* printf("I found %d global multipliers (%f)\n",fetidpmat_ctx->n_lambda,scalar_value); */ 17663425bc38SStefano Zampini 17673425bc38SStefano Zampini /* compute global ordering of lagrange multipliers and associate l2g map */ 1768ef028eecSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 1769ef028eecSStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 1770ef028eecSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1771ef028eecSStefano Zampini for (i=0;i<dual_size;i++) { 1772ef028eecSStefano Zampini array[aux_local_numbering_1[i]] = aux_local_numbering_2[i]; 1773ef028eecSStefano Zampini } 1774ef028eecSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1775ef028eecSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1776ef028eecSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1777ef028eecSStefano Zampini ierr = VecSum(pcis->vec1_global,&scalar_value);CHKERRQ(ierr); 1778ef028eecSStefano Zampini if (pcbddc->dbg_flag && (PetscInt)scalar_value != fetidpmat_ctx->n_lambda) { 1779acee19a7SJed Brown SETERRQ2(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Global number of multipliers mismatch! (%d!=%d)\n",(PetscInt)scalar_value,fetidpmat_ctx->n_lambda); 1780ef028eecSStefano Zampini } 17813425bc38SStefano Zampini 1782ef028eecSStefano Zampini /* Fill pcis->vec1_global with cumulative function for global numbering */ 1783ef028eecSStefano Zampini ierr = VecGetArray(pcis->vec1_global,&array);CHKERRQ(ierr); 1784ef028eecSStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&s);CHKERRQ(ierr); 1785ef028eecSStefano Zampini k = 0; 1786ef028eecSStefano Zampini first_index = -1; 1787ef028eecSStefano Zampini for (i=0;i<s;i++) { 1788ef028eecSStefano Zampini if (!first_found && array[i] > 0.0) { 1789ef028eecSStefano Zampini first_found = PETSC_TRUE; 1790ef028eecSStefano Zampini first_index = i; 1791ef028eecSStefano Zampini } 1792ef028eecSStefano Zampini k += (PetscInt)array[i]; 1793ef028eecSStefano Zampini } 1794ef028eecSStefano Zampini j = (!rank ? nprocs : 0); 17953425bc38SStefano Zampini ierr = PetscMalloc(j*sizeof(*dof_sizes),&dof_sizes);CHKERRQ(ierr); 17963425bc38SStefano Zampini ierr = PetscMalloc(j*sizeof(*dof_displs),&dof_displs);CHKERRQ(ierr); 1797ef028eecSStefano Zampini ierr = MPI_Gather(&k,1,MPIU_INT,dof_sizes,1,MPIU_INT,0,comm);CHKERRQ(ierr); 1798ef028eecSStefano Zampini if (!rank) { 17993425bc38SStefano Zampini dof_displs[0]=0; 18003425bc38SStefano Zampini for (i=1;i<nprocs;i++) { 18013425bc38SStefano Zampini dof_displs[i] = dof_displs[i-1]+dof_sizes[i-1]; 18023425bc38SStefano Zampini } 18033425bc38SStefano Zampini } 1804ef028eecSStefano Zampini ierr = MPI_Scatter(dof_displs,1,MPIU_INT,&k,1,MPIU_INT,0,comm);CHKERRQ(ierr); 1805ef028eecSStefano Zampini if (first_found) { 1806ef028eecSStefano Zampini array[first_index] += k; 1807ef028eecSStefano Zampini old_index = first_index; 1808ef028eecSStefano Zampini for (i=first_index+1;i<s;i++) { 1809ef028eecSStefano Zampini if (array[i] > 0.0) { 1810ef028eecSStefano Zampini array[i] += array[old_index]; 1811ef028eecSStefano Zampini old_index = i; 1812ef028eecSStefano Zampini } 1813ef028eecSStefano Zampini } 1814ef028eecSStefano Zampini } 1815ef028eecSStefano Zampini ierr = VecRestoreArray(pcis->vec1_global,&array);CHKERRQ(ierr); 1816ef028eecSStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 1817ef028eecSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1818ef028eecSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1819ef028eecSStefano Zampini ierr = PetscMalloc(dual_size*sizeof(*aux_global_numbering),&aux_global_numbering);CHKERRQ(ierr); 1820ef028eecSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 18213425bc38SStefano Zampini for (i=0;i<dual_size;i++) { 1822ef028eecSStefano Zampini aux_global_numbering[i] = (PetscInt)array[aux_local_numbering_1[i]]-aux_local_numbering_2[i]; 18233425bc38SStefano Zampini } 1824ef028eecSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1825f0474715SStefano Zampini ierr = PetscFree(aux_local_numbering_2);CHKERRQ(ierr); 1826f0474715SStefano Zampini ierr = PetscFree(dof_displs);CHKERRQ(ierr); 1827f0474715SStefano Zampini ierr = PetscFree(dof_sizes);CHKERRQ(ierr); 18283425bc38SStefano Zampini 18293425bc38SStefano Zampini /* init data for scaling factors exchange */ 18303425bc38SStefano Zampini partial_sum = 0; 18313425bc38SStefano Zampini j = 0; 18323425bc38SStefano Zampini ierr = PetscMalloc(pcis->n_neigh*sizeof(PetscInt),&ptrs_buffer);CHKERRQ(ierr); 18333425bc38SStefano Zampini ierr = PetscMalloc((pcis->n_neigh-1)*sizeof(MPI_Request),&send_reqs);CHKERRQ(ierr); 18343425bc38SStefano Zampini ierr = PetscMalloc((pcis->n_neigh-1)*sizeof(MPI_Request),&recv_reqs);CHKERRQ(ierr); 18353425bc38SStefano Zampini ierr = PetscMalloc(pcis->n*sizeof(PetscScalar*),&all_factors);CHKERRQ(ierr); 18363425bc38SStefano Zampini ptrs_buffer[0]=0; 18373425bc38SStefano Zampini for (i=1;i<pcis->n_neigh;i++) { 18383425bc38SStefano Zampini partial_sum += pcis->n_shared[i]; 18393425bc38SStefano Zampini ptrs_buffer[i] = ptrs_buffer[i-1]+pcis->n_shared[i]; 18403425bc38SStefano Zampini } 18413425bc38SStefano Zampini ierr = PetscMalloc(partial_sum*sizeof(PetscScalar),&send_buffer);CHKERRQ(ierr); 18423425bc38SStefano Zampini ierr = PetscMalloc(partial_sum*sizeof(PetscScalar),&recv_buffer);CHKERRQ(ierr); 18433425bc38SStefano Zampini ierr = PetscMalloc(partial_sum*sizeof(PetscScalar),&all_factors[0]);CHKERRQ(ierr); 18443425bc38SStefano Zampini for (i=0;i<pcis->n-1;i++) { 18453425bc38SStefano Zampini j = mat_graph->count[i]; 18463425bc38SStefano Zampini if (j>0) { 18473425bc38SStefano Zampini k = (mat_graph->neighbours_set[i][0] == -1 ? 1 : 0); 18483425bc38SStefano Zampini j = j - k; 18493425bc38SStefano Zampini } 18503425bc38SStefano Zampini all_factors[i+1]=all_factors[i]+j; 18513425bc38SStefano Zampini } 18523425bc38SStefano Zampini /* scatter B scaling to N vec */ 18533425bc38SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 18543425bc38SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->D,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 18553425bc38SStefano Zampini /* communications */ 18563425bc38SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 18573425bc38SStefano Zampini for (i=1;i<pcis->n_neigh;i++) { 18583425bc38SStefano Zampini for (j=0;j<pcis->n_shared[i];j++) { 18593425bc38SStefano Zampini send_buffer[ptrs_buffer[i-1]+j]=array[pcis->shared[i][j]]; 18603425bc38SStefano Zampini } 18613425bc38SStefano Zampini j = ptrs_buffer[i]-ptrs_buffer[i-1]; 1862ea7e1babSStefano Zampini ierr = MPI_Isend(&send_buffer[ptrs_buffer[i-1]],j,MPIU_SCALAR,pcis->neigh[i],0,comm,&send_reqs[i-1]);CHKERRQ(ierr); 1863ea7e1babSStefano Zampini ierr = MPI_Irecv(&recv_buffer[ptrs_buffer[i-1]],j,MPIU_SCALAR,pcis->neigh[i],0,comm,&recv_reqs[i-1]);CHKERRQ(ierr); 18643425bc38SStefano Zampini } 18653425bc38SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1866ea7e1babSStefano Zampini ierr = MPI_Waitall((pcis->n_neigh-1),recv_reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 18673425bc38SStefano Zampini /* put values in correct places */ 18683425bc38SStefano Zampini for (i=1;i<pcis->n_neigh;i++) { 18693425bc38SStefano Zampini for (j=0;j<pcis->n_shared[i];j++) { 18703425bc38SStefano Zampini k = pcis->shared[i][j]; 18713425bc38SStefano Zampini neigh_position = 0; 18723425bc38SStefano Zampini while (mat_graph->neighbours_set[k][neigh_position] != pcis->neigh[i]) {neigh_position++;} 18733425bc38SStefano Zampini s = (mat_graph->neighbours_set[k][0] == -1 ? 1 : 0); 18743425bc38SStefano Zampini neigh_position = neigh_position - s; 18753425bc38SStefano Zampini all_factors[k][neigh_position]=recv_buffer[ptrs_buffer[i-1]+j]; 18763425bc38SStefano Zampini } 18773425bc38SStefano Zampini } 1878ea7e1babSStefano Zampini ierr = MPI_Waitall((pcis->n_neigh-1),send_reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 18793425bc38SStefano Zampini ierr = PetscFree(send_reqs);CHKERRQ(ierr); 18803425bc38SStefano Zampini ierr = PetscFree(recv_reqs);CHKERRQ(ierr); 18813425bc38SStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 18823425bc38SStefano Zampini ierr = PetscFree(recv_buffer);CHKERRQ(ierr); 18833425bc38SStefano Zampini ierr = PetscFree(ptrs_buffer);CHKERRQ(ierr); 18843425bc38SStefano Zampini 18853425bc38SStefano Zampini /* Compute B and B_delta (local actions) */ 18863425bc38SStefano Zampini ierr = PetscMalloc(pcis->n_neigh*sizeof(*aux_sums),&aux_sums);CHKERRQ(ierr); 18873425bc38SStefano Zampini ierr = PetscMalloc(n_local_lambda*sizeof(*l2g_indices),&l2g_indices);CHKERRQ(ierr); 18883425bc38SStefano Zampini ierr = PetscMalloc(n_local_lambda*sizeof(*vals_B_delta),&vals_B_delta);CHKERRQ(ierr); 18893425bc38SStefano Zampini ierr = PetscMalloc(n_local_lambda*sizeof(*cols_B_delta),&cols_B_delta);CHKERRQ(ierr); 18903425bc38SStefano Zampini ierr = PetscMalloc(n_local_lambda*sizeof(*scaling_factors),&scaling_factors);CHKERRQ(ierr); 18913425bc38SStefano Zampini n_global_lambda=0; 18923425bc38SStefano Zampini partial_sum=0; 18933425bc38SStefano Zampini for (i=0;i<dual_size;i++) { 1894ef028eecSStefano Zampini n_global_lambda = aux_global_numbering[i]; 18953425bc38SStefano Zampini j = mat_graph->count[aux_local_numbering_1[i]]; 18963425bc38SStefano Zampini k = (mat_graph->neighbours_set[aux_local_numbering_1[i]][0] == -1 ? 1 : 0); 18973425bc38SStefano Zampini j = j - k; 18983425bc38SStefano Zampini aux_sums[0]=0; 18993425bc38SStefano Zampini for (s=1;s<j;s++) { 19003425bc38SStefano Zampini aux_sums[s]=aux_sums[s-1]+j-s+1; 19013425bc38SStefano Zampini } 19023425bc38SStefano Zampini array = all_factors[aux_local_numbering_1[i]]; 19033425bc38SStefano Zampini n_neg_values = 0; 19043425bc38SStefano Zampini while (n_neg_values < j && mat_graph->neighbours_set[aux_local_numbering_1[i]][n_neg_values+k] < rank) {n_neg_values++;} 19053425bc38SStefano Zampini n_pos_values = j - n_neg_values; 19063425bc38SStefano Zampini if (fully_redundant) { 19073425bc38SStefano Zampini for (s=0;s<n_neg_values;s++) { 19083425bc38SStefano Zampini l2g_indices [partial_sum+s]=aux_sums[s]+n_neg_values-s-1+n_global_lambda; 19093425bc38SStefano Zampini cols_B_delta [partial_sum+s]=dual_dofs_boundary_indices[i]; 19103425bc38SStefano Zampini vals_B_delta [partial_sum+s]=-1.0; 19113425bc38SStefano Zampini scaling_factors[partial_sum+s]=array[s]; 19123425bc38SStefano Zampini } 19133425bc38SStefano Zampini for (s=0;s<n_pos_values;s++) { 19143425bc38SStefano Zampini l2g_indices [partial_sum+s+n_neg_values]=aux_sums[n_neg_values]+s+n_global_lambda; 19153425bc38SStefano Zampini cols_B_delta [partial_sum+s+n_neg_values]=dual_dofs_boundary_indices[i]; 19163425bc38SStefano Zampini vals_B_delta [partial_sum+s+n_neg_values]=1.0; 19173425bc38SStefano Zampini scaling_factors[partial_sum+s+n_neg_values]=array[s+n_neg_values]; 19183425bc38SStefano Zampini } 19193425bc38SStefano Zampini partial_sum += j; 19203425bc38SStefano Zampini } else { 19213425bc38SStefano Zampini /* l2g_indices and default cols and vals of B_delta */ 19223425bc38SStefano Zampini for (s=0;s<j;s++) { 19233425bc38SStefano Zampini l2g_indices [partial_sum+s]=n_global_lambda+s; 19243425bc38SStefano Zampini cols_B_delta [partial_sum+s]=dual_dofs_boundary_indices[i]; 19253425bc38SStefano Zampini vals_B_delta [partial_sum+s]=0.0; 19263425bc38SStefano Zampini } 19273425bc38SStefano Zampini /* B_delta */ 19283425bc38SStefano Zampini if (n_neg_values > 0) { /* there's a rank next to me to the left */ 19293425bc38SStefano Zampini vals_B_delta [partial_sum+n_neg_values-1]=-1.0; 19303425bc38SStefano Zampini } 19313425bc38SStefano Zampini if (n_neg_values < j) { /* there's a rank next to me to the right */ 19323425bc38SStefano Zampini vals_B_delta [partial_sum+n_neg_values]=1.0; 19333425bc38SStefano Zampini } 19343425bc38SStefano Zampini /* scaling as in Klawonn-Widlund 1999*/ 19353425bc38SStefano Zampini for (s=0;s<n_neg_values;s++) { 19363425bc38SStefano Zampini scalar_value = 0.0; 19373425bc38SStefano Zampini for (k=0;k<s+1;k++) { 19383425bc38SStefano Zampini scalar_value += array[k]; 19393425bc38SStefano Zampini } 1940ef028eecSStefano Zampini scaling_factors[partial_sum+s] = -scalar_value; 19413425bc38SStefano Zampini } 19423425bc38SStefano Zampini for (s=0;s<n_pos_values;s++) { 19433425bc38SStefano Zampini scalar_value = 0.0; 19443425bc38SStefano Zampini for (k=s+n_neg_values;k<j;k++) { 19453425bc38SStefano Zampini scalar_value += array[k]; 19463425bc38SStefano Zampini } 19473425bc38SStefano Zampini scaling_factors[partial_sum+s+n_neg_values] = scalar_value; 19483425bc38SStefano Zampini } 19493425bc38SStefano Zampini partial_sum += j; 19503425bc38SStefano Zampini } 19513425bc38SStefano Zampini } 1952ef028eecSStefano Zampini ierr = PetscFree(aux_global_numbering);CHKERRQ(ierr); 1953f0474715SStefano Zampini ierr = PetscFree(aux_sums);CHKERRQ(ierr); 1954f0474715SStefano Zampini ierr = PetscFree(aux_local_numbering_1);CHKERRQ(ierr); 1955f0474715SStefano Zampini ierr = PetscFree(dual_dofs_boundary_indices);CHKERRQ(ierr); 19563425bc38SStefano Zampini ierr = PetscFree(all_factors[0]);CHKERRQ(ierr); 19573425bc38SStefano Zampini ierr = PetscFree(all_factors);CHKERRQ(ierr); 19583425bc38SStefano Zampini /* printf("I found %d local lambda dofs when numbering them (should be %d)\n",partial_sum,n_local_lambda); */ 1959f0474715SStefano Zampini 1960f0474715SStefano Zampini /* Local to global mapping of fetidpmat */ 1961f0474715SStefano Zampini ierr = VecCreate(PETSC_COMM_SELF,&fetidpmat_ctx->lambda_local);CHKERRQ(ierr); 1962f0474715SStefano Zampini ierr = VecSetSizes(fetidpmat_ctx->lambda_local,n_local_lambda,n_local_lambda);CHKERRQ(ierr); 1963f0474715SStefano Zampini ierr = VecSetType(fetidpmat_ctx->lambda_local,VECSEQ);CHKERRQ(ierr); 1964f0474715SStefano Zampini ierr = VecCreate(comm,&lambda_global);CHKERRQ(ierr); 1965f0474715SStefano Zampini ierr = VecSetSizes(lambda_global,PETSC_DECIDE,fetidpmat_ctx->n_lambda);CHKERRQ(ierr); 1966f0474715SStefano Zampini ierr = VecSetType(lambda_global,VECMPI);CHKERRQ(ierr); 19673425bc38SStefano Zampini ierr = ISCreateGeneral(comm,n_local_lambda,l2g_indices,PETSC_OWN_POINTER,&IS_l2g_lambda);CHKERRQ(ierr); 19683425bc38SStefano Zampini ierr = VecScatterCreate(fetidpmat_ctx->lambda_local,(IS)0,lambda_global,IS_l2g_lambda,&fetidpmat_ctx->l2g_lambda);CHKERRQ(ierr); 1969f0474715SStefano Zampini ierr = ISDestroy(&IS_l2g_lambda);CHKERRQ(ierr); 19703425bc38SStefano Zampini 19713425bc38SStefano Zampini /* Create local part of B_delta */ 19723425bc38SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&fetidpmat_ctx->B_delta); 19733425bc38SStefano Zampini ierr = MatSetSizes(fetidpmat_ctx->B_delta,n_local_lambda,pcis->n_B,n_local_lambda,pcis->n_B);CHKERRQ(ierr); 19743425bc38SStefano Zampini ierr = MatSetType(fetidpmat_ctx->B_delta,MATSEQAIJ);CHKERRQ(ierr); 19753425bc38SStefano Zampini ierr = MatSeqAIJSetPreallocation(fetidpmat_ctx->B_delta,1,PETSC_NULL);CHKERRQ(ierr); 19763425bc38SStefano Zampini ierr = MatSetOption(fetidpmat_ctx->B_delta,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 19773425bc38SStefano Zampini for (i=0;i<n_local_lambda;i++) { 19783425bc38SStefano Zampini ierr = MatSetValue(fetidpmat_ctx->B_delta,i,cols_B_delta[i],vals_B_delta[i],INSERT_VALUES);CHKERRQ(ierr); 19793425bc38SStefano Zampini } 1980f0474715SStefano Zampini ierr = PetscFree(vals_B_delta);CHKERRQ(ierr); 19813425bc38SStefano Zampini ierr = MatAssemblyBegin(fetidpmat_ctx->B_delta,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19823425bc38SStefano Zampini ierr = MatAssemblyEnd (fetidpmat_ctx->B_delta,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19833425bc38SStefano Zampini 19843425bc38SStefano Zampini if (fully_redundant) { 19853425bc38SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&ScalingMat); 19863425bc38SStefano Zampini ierr = MatSetSizes(ScalingMat,n_local_lambda,n_local_lambda,n_local_lambda,n_local_lambda);CHKERRQ(ierr); 19873425bc38SStefano Zampini ierr = MatSetType(ScalingMat,MATSEQAIJ);CHKERRQ(ierr); 19883425bc38SStefano Zampini ierr = MatSeqAIJSetPreallocation(ScalingMat,1,PETSC_NULL);CHKERRQ(ierr); 19893425bc38SStefano Zampini for (i=0;i<n_local_lambda;i++) { 19903425bc38SStefano Zampini ierr = MatSetValue(ScalingMat,i,i,scaling_factors[i],INSERT_VALUES);CHKERRQ(ierr); 19913425bc38SStefano Zampini } 19923425bc38SStefano Zampini ierr = MatAssemblyBegin(ScalingMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19933425bc38SStefano Zampini ierr = MatAssemblyEnd (ScalingMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19943425bc38SStefano Zampini ierr = MatMatMult(ScalingMat,fetidpmat_ctx->B_delta,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&fetidpmat_ctx->B_Ddelta);CHKERRQ(ierr); 19953425bc38SStefano Zampini ierr = MatDestroy(&ScalingMat);CHKERRQ(ierr); 19963425bc38SStefano Zampini } else { 19973425bc38SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&fetidpmat_ctx->B_Ddelta); 19983425bc38SStefano Zampini ierr = MatSetSizes(fetidpmat_ctx->B_Ddelta,n_local_lambda,pcis->n_B,n_local_lambda,pcis->n_B);CHKERRQ(ierr); 19993425bc38SStefano Zampini ierr = MatSetType(fetidpmat_ctx->B_Ddelta,MATSEQAIJ);CHKERRQ(ierr); 20003425bc38SStefano Zampini ierr = MatSeqAIJSetPreallocation(fetidpmat_ctx->B_Ddelta,1,PETSC_NULL);CHKERRQ(ierr); 20013425bc38SStefano Zampini for (i=0;i<n_local_lambda;i++) { 20023425bc38SStefano Zampini ierr = MatSetValue(fetidpmat_ctx->B_Ddelta,i,cols_B_delta[i],scaling_factors[i],INSERT_VALUES);CHKERRQ(ierr); 20033425bc38SStefano Zampini } 20043425bc38SStefano Zampini ierr = MatAssemblyBegin(fetidpmat_ctx->B_Ddelta,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20053425bc38SStefano Zampini ierr = MatAssemblyEnd (fetidpmat_ctx->B_Ddelta,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20063425bc38SStefano Zampini } 2007f0474715SStefano Zampini ierr = PetscFree(scaling_factors);CHKERRQ(ierr); 2008f0474715SStefano Zampini ierr = PetscFree(cols_B_delta);CHKERRQ(ierr); 20093425bc38SStefano Zampini 20103425bc38SStefano Zampini /* Create some vectors needed by fetidp */ 20113425bc38SStefano Zampini ierr = VecDuplicate(pcis->vec1_B,&fetidpmat_ctx->temp_solution_B);CHKERRQ(ierr); 20123425bc38SStefano Zampini ierr = VecDuplicate(pcis->vec1_D,&fetidpmat_ctx->temp_solution_D);CHKERRQ(ierr); 20133425bc38SStefano Zampini 20143425bc38SStefano Zampini test_fetidp = PETSC_FALSE; 20153425bc38SStefano Zampini ierr = PetscOptionsGetBool(PETSC_NULL,"-fetidp_check",&test_fetidp,PETSC_NULL);CHKERRQ(ierr); 20163425bc38SStefano Zampini 20173425bc38SStefano Zampini if (test_fetidp) { 20183425bc38SStefano Zampini 20193425bc38SStefano Zampini ierr = PetscViewerASCIIGetStdout(((PetscObject)(fetidpmat_ctx->pc))->comm,&viewer);CHKERRQ(ierr); 20203425bc38SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 20213425bc38SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------FETI_DP TESTS--------------\n");CHKERRQ(ierr); 20223425bc38SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"All tests should return zero!\n");CHKERRQ(ierr); 20233425bc38SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"FETIDP MAT context in the ");CHKERRQ(ierr); 20243425bc38SStefano Zampini if (fully_redundant) { 20253425bc38SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"fully redundant case for lagrange multipliers.\n");CHKERRQ(ierr); 20263425bc38SStefano Zampini } else { 20273425bc38SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Non-fully redundant case for lagrange multiplier.\n");CHKERRQ(ierr); 20283425bc38SStefano Zampini } 20293425bc38SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 20303425bc38SStefano Zampini 20313425bc38SStefano Zampini /* TEST A/B: Test numbering of global lambda dofs */ 20323425bc38SStefano Zampini 20333425bc38SStefano Zampini ierr = VecDuplicate(fetidpmat_ctx->lambda_local,&test_vec);CHKERRQ(ierr); 20343425bc38SStefano Zampini ierr = VecSet(lambda_global,1.0);CHKERRQ(ierr); 20353425bc38SStefano Zampini ierr = VecSet(test_vec,1.0);CHKERRQ(ierr); 20363425bc38SStefano Zampini ierr = VecScatterBegin(fetidpmat_ctx->l2g_lambda,lambda_global,fetidpmat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20373425bc38SStefano Zampini ierr = VecScatterEnd (fetidpmat_ctx->l2g_lambda,lambda_global,fetidpmat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20383425bc38SStefano Zampini scalar_value = -1.0; 20393425bc38SStefano Zampini ierr = VecAXPY(test_vec,scalar_value,fetidpmat_ctx->lambda_local);CHKERRQ(ierr); 20403425bc38SStefano Zampini ierr = VecNorm(test_vec,NORM_INFINITY,&scalar_value);CHKERRQ(ierr); 20413425bc38SStefano Zampini ierr = VecDestroy(&test_vec);CHKERRQ(ierr); 20423425bc38SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"A[%04d]: CHECK glob to loc: % 1.14e\n",rank,scalar_value);CHKERRQ(ierr); 20433425bc38SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 20443425bc38SStefano Zampini if (fully_redundant) { 20453425bc38SStefano Zampini ierr = VecSet(lambda_global,0.0);CHKERRQ(ierr); 20463425bc38SStefano Zampini ierr = VecSet(fetidpmat_ctx->lambda_local,0.5);CHKERRQ(ierr); 20473425bc38SStefano Zampini ierr = VecScatterBegin(fetidpmat_ctx->l2g_lambda,fetidpmat_ctx->lambda_local,lambda_global,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20483425bc38SStefano Zampini ierr = VecScatterEnd (fetidpmat_ctx->l2g_lambda,fetidpmat_ctx->lambda_local,lambda_global,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20493425bc38SStefano Zampini ierr = VecSum(lambda_global,&scalar_value);CHKERRQ(ierr); 20503425bc38SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"B[%04d]: CHECK loc to glob: % 1.14e\n",rank,scalar_value-fetidpmat_ctx->n_lambda);CHKERRQ(ierr); 20513425bc38SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 20523425bc38SStefano Zampini } 20533425bc38SStefano Zampini 20543425bc38SStefano Zampini /* TEST C: It should holds B_delta*w=0, w\in\widehat{W} */ 20553425bc38SStefano Zampini /* This is the meaning of the B matrix */ 20563425bc38SStefano Zampini 20573425bc38SStefano Zampini ierr = VecSetRandom(pcis->vec1_N,PETSC_NULL);CHKERRQ(ierr); 20583425bc38SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 20593425bc38SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20603425bc38SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20613425bc38SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20623425bc38SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20633425bc38SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20643425bc38SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20653425bc38SStefano Zampini /* Action of B_delta */ 20663425bc38SStefano Zampini ierr = MatMult(fetidpmat_ctx->B_delta,pcis->vec1_B,fetidpmat_ctx->lambda_local);CHKERRQ(ierr); 20673425bc38SStefano Zampini ierr = VecSet(lambda_global,0.0);CHKERRQ(ierr); 20683425bc38SStefano Zampini ierr = VecScatterBegin(fetidpmat_ctx->l2g_lambda,fetidpmat_ctx->lambda_local,lambda_global,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20693425bc38SStefano Zampini ierr = VecScatterEnd (fetidpmat_ctx->l2g_lambda,fetidpmat_ctx->lambda_local,lambda_global,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20703425bc38SStefano Zampini ierr = VecNorm(lambda_global,NORM_INFINITY,&scalar_value);CHKERRQ(ierr); 20713425bc38SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"C[coll]: CHECK infty norm of B_delta*w (w continuous): % 1.14e\n",scalar_value);CHKERRQ(ierr); 20723425bc38SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 20733425bc38SStefano Zampini 20743425bc38SStefano Zampini /* TEST D: It should holds E_Dw = w - P_Dw w\in\widetilde{W} */ 20753425bc38SStefano Zampini /* E_D = R_D^TR */ 20763425bc38SStefano Zampini /* P_D = B_{D,delta}^T B_{delta} */ 20773425bc38SStefano Zampini /* eq.44 Mandel Tezaur and Dohrmann 2005 */ 20783425bc38SStefano Zampini 20793425bc38SStefano Zampini /* compute a random vector in \widetilde{W} */ 20803425bc38SStefano Zampini ierr = VecSetRandom(pcis->vec1_N,PETSC_NULL);CHKERRQ(ierr); 20813425bc38SStefano Zampini scalar_value = 0.0; /* set zero at vertices */ 20823425bc38SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 20833425bc38SStefano Zampini for (i=0;i<n_vertices;i++) { array[vertex_indices[i]]=scalar_value; } 20843425bc38SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 20853425bc38SStefano Zampini /* store w for final comparison */ 20863425bc38SStefano Zampini ierr = VecDuplicate(pcis->vec1_B,&test_vec);CHKERRQ(ierr); 20873425bc38SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,test_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20883425bc38SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,test_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20893425bc38SStefano Zampini 20903425bc38SStefano Zampini /* Jump operator P_D : results stored in pcis->vec1_B */ 20913425bc38SStefano Zampini 20923425bc38SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20933425bc38SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20943425bc38SStefano Zampini /* Action of B_delta */ 20953425bc38SStefano Zampini ierr = MatMult(fetidpmat_ctx->B_delta,pcis->vec1_B,fetidpmat_ctx->lambda_local);CHKERRQ(ierr); 20963425bc38SStefano Zampini ierr = VecSet(lambda_global,0.0);CHKERRQ(ierr); 20973425bc38SStefano Zampini ierr = VecScatterBegin(fetidpmat_ctx->l2g_lambda,fetidpmat_ctx->lambda_local,lambda_global,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20983425bc38SStefano Zampini ierr = VecScatterEnd (fetidpmat_ctx->l2g_lambda,fetidpmat_ctx->lambda_local,lambda_global,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20993425bc38SStefano Zampini /* Action of B_Ddelta^T */ 21003425bc38SStefano Zampini ierr = VecScatterBegin(fetidpmat_ctx->l2g_lambda,lambda_global,fetidpmat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21013425bc38SStefano Zampini ierr = VecScatterEnd (fetidpmat_ctx->l2g_lambda,lambda_global,fetidpmat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21023425bc38SStefano Zampini ierr = MatMultTranspose(fetidpmat_ctx->B_Ddelta,fetidpmat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 21033425bc38SStefano Zampini 21043425bc38SStefano Zampini /* Average operator E_D : results stored in pcis->vec2_B */ 21053425bc38SStefano Zampini 21063425bc38SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 21073425bc38SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 21083425bc38SStefano Zampini ierr = VecPointwiseMult(pcis->vec2_B,pcis->D,pcis->vec2_B);CHKERRQ(ierr); 21093425bc38SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec2_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21103425bc38SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec2_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21113425bc38SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 21123425bc38SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21133425bc38SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21143425bc38SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 21153425bc38SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 21163425bc38SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 21173425bc38SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 21183425bc38SStefano Zampini 21193425bc38SStefano Zampini /* test E_D=I-P_D */ 21203425bc38SStefano Zampini scalar_value = 1.0; 21213425bc38SStefano Zampini ierr = VecAXPY(pcis->vec1_B,scalar_value,pcis->vec2_B);CHKERRQ(ierr); 21223425bc38SStefano Zampini scalar_value = -1.0; 21233425bc38SStefano Zampini ierr = VecAXPY(pcis->vec1_B,scalar_value,test_vec);CHKERRQ(ierr); 21243425bc38SStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&scalar_value);CHKERRQ(ierr); 21253425bc38SStefano Zampini ierr = VecDestroy(&test_vec);CHKERRQ(ierr); 21263425bc38SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"D[%04d] CHECK infty norm of E_D + P_D - I: % 1.14e\n",rank,scalar_value);CHKERRQ(ierr); 21273425bc38SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 21283425bc38SStefano Zampini 21293425bc38SStefano Zampini /* TEST E: It should holds R_D^TP_Dw=0 w\in\widetilde{W} */ 21303425bc38SStefano Zampini /* eq.48 Mandel Tezaur and Dohrmann 2005 */ 21313425bc38SStefano Zampini 21323425bc38SStefano Zampini ierr = VecSetRandom(pcis->vec1_N,PETSC_NULL);CHKERRQ(ierr); 21333425bc38SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 21343425bc38SStefano Zampini scalar_value = 0.0; /* set zero at vertices */ 21353425bc38SStefano Zampini for (i=0;i<n_vertices;i++) { array[vertex_indices[i]]=scalar_value; } 21363425bc38SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 21373425bc38SStefano Zampini 21383425bc38SStefano Zampini /* Jump operator P_D : results stored in pcis->vec1_B */ 21393425bc38SStefano Zampini 21403425bc38SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 21413425bc38SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 21423425bc38SStefano Zampini /* Action of B_delta */ 21433425bc38SStefano Zampini ierr = MatMult(fetidpmat_ctx->B_delta,pcis->vec1_B,fetidpmat_ctx->lambda_local);CHKERRQ(ierr); 21443425bc38SStefano Zampini ierr = VecSet(lambda_global,0.0);CHKERRQ(ierr); 21453425bc38SStefano Zampini ierr = VecScatterBegin(fetidpmat_ctx->l2g_lambda,fetidpmat_ctx->lambda_local,lambda_global,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 21463425bc38SStefano Zampini ierr = VecScatterEnd (fetidpmat_ctx->l2g_lambda,fetidpmat_ctx->lambda_local,lambda_global,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 21473425bc38SStefano Zampini /* Action of B_Ddelta^T */ 21483425bc38SStefano Zampini ierr = VecScatterBegin(fetidpmat_ctx->l2g_lambda,lambda_global,fetidpmat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21493425bc38SStefano Zampini ierr = VecScatterEnd (fetidpmat_ctx->l2g_lambda,lambda_global,fetidpmat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21503425bc38SStefano Zampini ierr = MatMultTranspose(fetidpmat_ctx->B_Ddelta,fetidpmat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 21513425bc38SStefano Zampini /* diagonal scaling */ 21523425bc38SStefano Zampini ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 21533425bc38SStefano Zampini /* sum on the interface */ 21543425bc38SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 21553425bc38SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21563425bc38SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21573425bc38SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 21583425bc38SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21593425bc38SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21603425bc38SStefano Zampini ierr = VecNorm(pcis->vec1_global,NORM_INFINITY,&scalar_value);CHKERRQ(ierr); 21613425bc38SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"E[coll]: CHECK infty norm of R^T_D P_D: % 1.14e\n",scalar_value);CHKERRQ(ierr); 21623425bc38SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 21633425bc38SStefano Zampini 21643425bc38SStefano Zampini if (!fully_redundant) { 21653425bc38SStefano Zampini /* TEST F: It should holds B_{delta}B^T_{D,delta}=I */ 21663425bc38SStefano Zampini /* Corollary thm 14 Mandel Tezaur and Dohrmann 2005 */ 21673425bc38SStefano Zampini ierr = VecDuplicate(lambda_global,&test_vec);CHKERRQ(ierr); 21683425bc38SStefano Zampini ierr = VecSetRandom(lambda_global,PETSC_NULL);CHKERRQ(ierr); 21693425bc38SStefano Zampini /* Action of B_Ddelta^T */ 21703425bc38SStefano Zampini ierr = VecScatterBegin(fetidpmat_ctx->l2g_lambda,lambda_global,fetidpmat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21713425bc38SStefano Zampini ierr = VecScatterEnd (fetidpmat_ctx->l2g_lambda,lambda_global,fetidpmat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21723425bc38SStefano Zampini ierr = MatMultTranspose(fetidpmat_ctx->B_Ddelta,fetidpmat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 21733425bc38SStefano Zampini /* Action of B_delta */ 21743425bc38SStefano Zampini ierr = MatMult(fetidpmat_ctx->B_delta,pcis->vec1_B,fetidpmat_ctx->lambda_local);CHKERRQ(ierr); 21753425bc38SStefano Zampini ierr = VecSet(test_vec,0.0);CHKERRQ(ierr); 21763425bc38SStefano Zampini ierr = VecScatterBegin(fetidpmat_ctx->l2g_lambda,fetidpmat_ctx->lambda_local,test_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 21773425bc38SStefano Zampini ierr = VecScatterEnd (fetidpmat_ctx->l2g_lambda,fetidpmat_ctx->lambda_local,test_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 21783425bc38SStefano Zampini scalar_value = -1.0; 21793425bc38SStefano Zampini ierr = VecAXPY(lambda_global,scalar_value,test_vec);CHKERRQ(ierr); 21803425bc38SStefano Zampini ierr = VecNorm(lambda_global,NORM_INFINITY,&scalar_value);CHKERRQ(ierr); 21813425bc38SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"E[coll]: CHECK infty norm of P^T_D - I: % 1.14e\n",scalar_value);CHKERRQ(ierr); 21823425bc38SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 21833425bc38SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 21843425bc38SStefano Zampini ierr = VecDestroy(&test_vec);CHKERRQ(ierr); 21853425bc38SStefano Zampini } 21863425bc38SStefano Zampini } 21873425bc38SStefano Zampini /* final cleanup */ 21883425bc38SStefano Zampini ierr = PetscFree(vertex_indices);CHKERRQ(ierr); 21893425bc38SStefano Zampini ierr = VecDestroy(&lambda_global);CHKERRQ(ierr); 21903425bc38SStefano Zampini 21913425bc38SStefano Zampini PetscFunctionReturn(0); 21923425bc38SStefano Zampini } 21933425bc38SStefano Zampini 21943425bc38SStefano Zampini #undef __FUNCT__ 21953425bc38SStefano Zampini #define __FUNCT__ "PCBDDCSetupFETIDPPCContext" 21963425bc38SStefano Zampini static PetscErrorCode PCBDDCSetupFETIDPPCContext(Mat fetimat, FETIDPPC_ctx *fetidppc_ctx) 21973425bc38SStefano Zampini { 21983425bc38SStefano Zampini FETIDPMat_ctx *mat_ctx; 21993425bc38SStefano Zampini PetscErrorCode ierr; 22003425bc38SStefano Zampini 22013425bc38SStefano Zampini PetscFunctionBegin; 22023425bc38SStefano Zampini ierr = MatShellGetContext(fetimat,&mat_ctx);CHKERRQ(ierr); 22033425bc38SStefano Zampini /* get references from objects created when setting up feti mat context */ 22043425bc38SStefano Zampini ierr = PetscObjectReference((PetscObject)mat_ctx->lambda_local);CHKERRQ(ierr); 22053425bc38SStefano Zampini fetidppc_ctx->lambda_local = mat_ctx->lambda_local; 22063425bc38SStefano Zampini ierr = PetscObjectReference((PetscObject)mat_ctx->B_Ddelta);CHKERRQ(ierr); 22073425bc38SStefano Zampini fetidppc_ctx->B_Ddelta = mat_ctx->B_Ddelta; 22083425bc38SStefano Zampini ierr = PetscObjectReference((PetscObject)mat_ctx->l2g_lambda);CHKERRQ(ierr); 22093425bc38SStefano Zampini fetidppc_ctx->l2g_lambda = mat_ctx->l2g_lambda; 22103425bc38SStefano Zampini PetscFunctionReturn(0); 22113425bc38SStefano Zampini } 22123425bc38SStefano Zampini 22133425bc38SStefano Zampini #undef __FUNCT__ 22143425bc38SStefano Zampini #define __FUNCT__ "FETIDPMatMult" 22153425bc38SStefano Zampini static PetscErrorCode FETIDPMatMult(Mat fetimat, Vec x, Vec y) 22163425bc38SStefano Zampini { 22173425bc38SStefano Zampini FETIDPMat_ctx *mat_ctx; 22183425bc38SStefano Zampini PC_IS *pcis; 22193425bc38SStefano Zampini PetscErrorCode ierr; 22203425bc38SStefano Zampini 22213425bc38SStefano Zampini PetscFunctionBegin; 22223425bc38SStefano Zampini ierr = MatShellGetContext(fetimat,&mat_ctx);CHKERRQ(ierr); 22233425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 22243425bc38SStefano Zampini /* Application of B_delta^T */ 22253425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,x,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 22263425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,x,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 22273425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 22283425bc38SStefano Zampini /* Application of \widetilde{S}^-1 */ 22293425bc38SStefano Zampini ierr = VecSet(pcis->vec1_D,0.0);CHKERRQ(ierr); 22303425bc38SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr); 22313425bc38SStefano Zampini /* Application of B_delta */ 22323425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 22333425bc38SStefano Zampini ierr = VecSet(y,0.0);CHKERRQ(ierr); 22343425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,y,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22353425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,mat_ctx->lambda_local,y,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22363425bc38SStefano Zampini PetscFunctionReturn(0); 22373425bc38SStefano Zampini } 22383425bc38SStefano Zampini 22393425bc38SStefano Zampini #undef __FUNCT__ 22403425bc38SStefano Zampini #define __FUNCT__ "FETIDPPCApply" 22413425bc38SStefano Zampini static PetscErrorCode FETIDPPCApply(PC fetipc, Vec x, Vec y) 22423425bc38SStefano Zampini { 22433425bc38SStefano Zampini FETIDPPC_ctx *pc_ctx; 22443425bc38SStefano Zampini PC_IS *pcis; 22453425bc38SStefano Zampini PetscErrorCode ierr; 22463425bc38SStefano Zampini 22473425bc38SStefano Zampini PetscFunctionBegin; 22483425bc38SStefano Zampini ierr = PCShellGetContext(fetipc,(void**)&pc_ctx); 22493425bc38SStefano Zampini pcis = (PC_IS*)pc_ctx->pc->data; 22503425bc38SStefano Zampini /* Application of B_Ddelta^T */ 22513425bc38SStefano Zampini ierr = VecScatterBegin(pc_ctx->l2g_lambda,x,pc_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 22523425bc38SStefano Zampini ierr = VecScatterEnd(pc_ctx->l2g_lambda,x,pc_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 22533425bc38SStefano Zampini ierr = VecSet(pcis->vec2_B,0.0);CHKERRQ(ierr); 22543425bc38SStefano Zampini ierr = MatMultTranspose(pc_ctx->B_Ddelta,pc_ctx->lambda_local,pcis->vec2_B);CHKERRQ(ierr); 22553425bc38SStefano Zampini /* Application of S */ 22563425bc38SStefano Zampini ierr = PCISApplySchur(pc_ctx->pc,pcis->vec2_B,pcis->vec1_B,(Vec)0,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 22573425bc38SStefano Zampini /* Application of B_Ddelta */ 22583425bc38SStefano Zampini ierr = MatMult(pc_ctx->B_Ddelta,pcis->vec1_B,pc_ctx->lambda_local);CHKERRQ(ierr); 22593425bc38SStefano Zampini ierr = VecSet(y,0.0);CHKERRQ(ierr); 22603425bc38SStefano Zampini ierr = VecScatterBegin(pc_ctx->l2g_lambda,pc_ctx->lambda_local,y,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22613425bc38SStefano Zampini ierr = VecScatterEnd(pc_ctx->l2g_lambda,pc_ctx->lambda_local,y,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22623425bc38SStefano Zampini PetscFunctionReturn(0); 22633425bc38SStefano Zampini } 22643425bc38SStefano Zampini 2265da1bb401SStefano Zampini #undef __FUNCT__ 2266da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetupLocalAdjacencyGraph" 2267da1bb401SStefano Zampini static PetscErrorCode PCBDDCSetupLocalAdjacencyGraph(PC pc) 2268da1bb401SStefano Zampini { 2269da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2270da1bb401SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 22711a83f524SJed Brown PetscInt nvtxs; 22721a83f524SJed Brown const PetscInt *xadj,*adjncy; 2273da1bb401SStefano Zampini Mat mat_adj; 2274da1bb401SStefano Zampini PetscBool symmetrize_rowij=PETSC_TRUE,compressed_rowij=PETSC_FALSE,flg_row=PETSC_TRUE; 2275da1bb401SStefano Zampini PCBDDCGraph mat_graph=pcbddc->mat_graph; 2276da1bb401SStefano Zampini PetscErrorCode ierr; 2277da1bb401SStefano Zampini 2278da1bb401SStefano Zampini PetscFunctionBegin; 2279da1bb401SStefano Zampini /* get CSR adjacency from local matrix if user has not yet provided local graph using PCBDDCSetLocalAdjacencyGraph function */ 2280da1bb401SStefano Zampini if (!mat_graph->xadj) { 2281da1bb401SStefano Zampini ierr = MatConvert(matis->A,MATMPIADJ,MAT_INITIAL_MATRIX,&mat_adj);CHKERRQ(ierr); 2282da1bb401SStefano Zampini ierr = MatGetRowIJ(mat_adj,0,symmetrize_rowij,compressed_rowij,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2283acee19a7SJed Brown if (!flg_row) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatGetRowIJ()\n"); 2284da1bb401SStefano Zampini /* Get adjacency into BDDC workspace */ 2285da1bb401SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 2286da1bb401SStefano Zampini ierr = MatRestoreRowIJ(mat_adj,0,symmetrize_rowij,compressed_rowij,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2287acee19a7SJed Brown if (!flg_row) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatRestoreRowIJ()\n"); 2288da1bb401SStefano Zampini ierr = MatDestroy(&mat_adj);CHKERRQ(ierr); 2289da1bb401SStefano Zampini } 2290da1bb401SStefano Zampini PetscFunctionReturn(0); 2291da1bb401SStefano Zampini } 2292da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 22930c7d97c5SJed Brown #undef __FUNCT__ 22940c7d97c5SJed Brown #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 22952617d88aSStefano Zampini static PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc) 22960c7d97c5SJed Brown { 22970c7d97c5SJed Brown PetscErrorCode ierr; 22980c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 22990c7d97c5SJed Brown PC_IS* pcis = (PC_IS*) (pc->data); 23003b03a366Sstefano_zampini const PetscScalar zero = 0.0; 23010c7d97c5SJed Brown 23020c7d97c5SJed Brown PetscFunctionBegin; 23030c7d97c5SJed Brown /* Application of PHI^T */ 23040c7d97c5SJed Brown ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 230529622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 23060c7d97c5SJed Brown 23070c7d97c5SJed Brown /* Scatter data of coarse_rhs */ 2308142dfd88SStefano Zampini if (pcbddc->coarse_rhs) { ierr = VecSet(pcbddc->coarse_rhs,zero);CHKERRQ(ierr); } 23090c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23100c7d97c5SJed Brown 23110c7d97c5SJed Brown /* Local solution on R nodes */ 23120c7d97c5SJed Brown ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 23130c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23140c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 231529622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { 23160c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23170c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23180c7d97c5SJed Brown } 23190c7d97c5SJed Brown ierr = PCBDDCSolveSaddlePoint(pc);CHKERRQ(ierr); 23200c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 23210c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23220c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 232329622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { 23240c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23250c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23260c7d97c5SJed Brown } 23270c7d97c5SJed Brown 23280c7d97c5SJed Brown /* Coarse solution */ 23290c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23300bdf917eSStefano Zampini if (pcbddc->coarse_rhs) { 23310bdf917eSStefano Zampini if (pcbddc->CoarseNullSpace) { 23320bdf917eSStefano Zampini ierr = MatNullSpaceRemove(pcbddc->CoarseNullSpace,pcbddc->coarse_rhs,PETSC_NULL);CHKERRQ(ierr); 23330bdf917eSStefano Zampini } 23340bdf917eSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 23350bdf917eSStefano Zampini if (pcbddc->CoarseNullSpace) { 23360bdf917eSStefano Zampini ierr = MatNullSpaceRemove(pcbddc->CoarseNullSpace,pcbddc->coarse_vec,PETSC_NULL);CHKERRQ(ierr); 23370bdf917eSStefano Zampini } 23380bdf917eSStefano Zampini } 23390c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23400c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd (pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23410c7d97c5SJed Brown 23420c7d97c5SJed Brown /* Sum contributions from two levels */ 23430c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 234429622bf0SStefano Zampini if (pcbddc->inexact_prec_type) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 23450c7d97c5SJed Brown PetscFunctionReturn(0); 23460c7d97c5SJed Brown } 23470c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 23480c7d97c5SJed Brown #undef __FUNCT__ 23490c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSolveSaddlePoint" 235053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSolveSaddlePoint(PC pc) 23510c7d97c5SJed Brown { 23520c7d97c5SJed Brown PetscErrorCode ierr; 23530c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 23540c7d97c5SJed Brown 23550c7d97c5SJed Brown PetscFunctionBegin; 235653cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 2357534831adSStefano Zampini if (pcbddc->local_auxmat1) { 23580c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec2_R,pcbddc->vec1_C);CHKERRQ(ierr); 23590c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 23600c7d97c5SJed Brown } 23610c7d97c5SJed Brown PetscFunctionReturn(0); 23620c7d97c5SJed Brown } 23630c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 23640c7d97c5SJed Brown #undef __FUNCT__ 23650c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 236653cdbc3dSStefano Zampini static PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,Vec vec_from, Vec vec_to, InsertMode imode, ScatterMode smode) 23670c7d97c5SJed Brown { 23680c7d97c5SJed Brown PetscErrorCode ierr; 23690c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 23700c7d97c5SJed Brown 23710c7d97c5SJed Brown PetscFunctionBegin; 23720c7d97c5SJed Brown switch (pcbddc->coarse_communications_type) { 23730c7d97c5SJed Brown case SCATTERS_BDDC: 23740c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 23750c7d97c5SJed Brown break; 23760c7d97c5SJed Brown case GATHERS_BDDC: 23770c7d97c5SJed Brown break; 23780c7d97c5SJed Brown } 23790c7d97c5SJed Brown PetscFunctionReturn(0); 23800c7d97c5SJed Brown } 23810c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 23820c7d97c5SJed Brown #undef __FUNCT__ 23830c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 238453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc,Vec vec_from, Vec vec_to, InsertMode imode, ScatterMode smode) 23850c7d97c5SJed Brown { 23860c7d97c5SJed Brown PetscErrorCode ierr; 23870c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 23880c7d97c5SJed Brown PetscScalar* array_to; 23890c7d97c5SJed Brown PetscScalar* array_from; 23900c7d97c5SJed Brown MPI_Comm comm=((PetscObject)pc)->comm; 23910c7d97c5SJed Brown PetscInt i; 23920c7d97c5SJed Brown 23930c7d97c5SJed Brown PetscFunctionBegin; 23940c7d97c5SJed Brown switch (pcbddc->coarse_communications_type) { 23950c7d97c5SJed Brown case SCATTERS_BDDC: 23960c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 23970c7d97c5SJed Brown break; 23980c7d97c5SJed Brown case GATHERS_BDDC: 23990c7d97c5SJed Brown if (vec_from) VecGetArray(vec_from,&array_from); 24000c7d97c5SJed Brown if (vec_to) VecGetArray(vec_to,&array_to); 24010c7d97c5SJed Brown switch (pcbddc->coarse_problem_type) { 24020c7d97c5SJed Brown case SEQUENTIAL_BDDC: 24030c7d97c5SJed Brown if (smode == SCATTER_FORWARD) { 240453cdbc3dSStefano Zampini ierr = MPI_Gatherv(&array_from[0],pcbddc->local_primal_size,MPIU_SCALAR,&pcbddc->replicated_local_primal_values[0],pcbddc->local_primal_sizes,pcbddc->local_primal_displacements,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 24050c7d97c5SJed Brown if (vec_to) { 24060bdf917eSStefano Zampini if (imode == ADD_VALUES) { 24070bdf917eSStefano Zampini for (i=0;i<pcbddc->replicated_primal_size;i++) { 24080c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 24090c7d97c5SJed Brown } 24100c7d97c5SJed Brown } else { 24110bdf917eSStefano Zampini for (i=0;i<pcbddc->replicated_primal_size;i++) { 24120bdf917eSStefano Zampini array_to[pcbddc->replicated_local_primal_indices[i]]=pcbddc->replicated_local_primal_values[i]; 24130bdf917eSStefano Zampini } 24140bdf917eSStefano Zampini } 24150bdf917eSStefano Zampini } 24160bdf917eSStefano Zampini } else { 24170bdf917eSStefano Zampini if (vec_from) { 24180bdf917eSStefano Zampini if (imode == ADD_VALUES) { 24190bdf917eSStefano Zampini printf("Scatter mode %d, insert mode %d for case %d not implemented!\n",smode,imode,pcbddc->coarse_problem_type); 24200bdf917eSStefano Zampini } 24210bdf917eSStefano Zampini for (i=0;i<pcbddc->replicated_primal_size;i++) { 24220c7d97c5SJed Brown pcbddc->replicated_local_primal_values[i]=array_from[pcbddc->replicated_local_primal_indices[i]]; 24230bdf917eSStefano Zampini } 24240bdf917eSStefano Zampini } 242553cdbc3dSStefano Zampini ierr = MPI_Scatterv(&pcbddc->replicated_local_primal_values[0],pcbddc->local_primal_sizes,pcbddc->local_primal_displacements,MPIU_SCALAR,&array_to[0],pcbddc->local_primal_size,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 24260c7d97c5SJed Brown } 24270c7d97c5SJed Brown break; 24280c7d97c5SJed Brown case REPLICATED_BDDC: 24290c7d97c5SJed Brown if (smode == SCATTER_FORWARD) { 243053cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&array_from[0],pcbddc->local_primal_size,MPIU_SCALAR,&pcbddc->replicated_local_primal_values[0],pcbddc->local_primal_sizes,pcbddc->local_primal_displacements,MPIU_SCALAR,comm);CHKERRQ(ierr); 24310bdf917eSStefano Zampini if (imode == ADD_VALUES) { 24320bdf917eSStefano Zampini for (i=0;i<pcbddc->replicated_primal_size;i++) { 24330c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 24340bdf917eSStefano Zampini } 24350bdf917eSStefano Zampini } else { 24360bdf917eSStefano Zampini for (i=0;i<pcbddc->replicated_primal_size;i++) { 24370bdf917eSStefano Zampini array_to[pcbddc->replicated_local_primal_indices[i]]=pcbddc->replicated_local_primal_values[i]; 24380bdf917eSStefano Zampini } 24390bdf917eSStefano Zampini } 24400c7d97c5SJed Brown } else { /* no communications needed for SCATTER_REVERSE since needed data is already present */ 24410bdf917eSStefano Zampini if (imode == ADD_VALUES) { 24420bdf917eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 24430bdf917eSStefano Zampini array_to[i]+=array_from[pcbddc->local_primal_indices[i]]; 24440bdf917eSStefano Zampini } 24450bdf917eSStefano Zampini } else { 24460bdf917eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 24470c7d97c5SJed Brown array_to[i]=array_from[pcbddc->local_primal_indices[i]]; 24480c7d97c5SJed Brown } 24490bdf917eSStefano Zampini } 24500bdf917eSStefano Zampini } 24510c7d97c5SJed Brown break; 245253cdbc3dSStefano Zampini case MULTILEVEL_BDDC: 245353cdbc3dSStefano Zampini break; 245453cdbc3dSStefano Zampini case PARALLEL_BDDC: 245553cdbc3dSStefano Zampini break; 24560c7d97c5SJed Brown } 24570c7d97c5SJed Brown if (vec_from) VecRestoreArray(vec_from,&array_from); 24580c7d97c5SJed Brown if (vec_to) VecRestoreArray(vec_to,&array_to); 24590c7d97c5SJed Brown break; 24600c7d97c5SJed Brown } 24610c7d97c5SJed Brown PetscFunctionReturn(0); 24620c7d97c5SJed Brown } 24630c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 24643b03a366Sstefano_zampini #undef __FUNCT__ 24653b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCCreateConstraintMatrix" 24663b03a366Sstefano_zampini static PetscErrorCode PCBDDCCreateConstraintMatrix(PC pc) 24673b03a366Sstefano_zampini { 24683b03a366Sstefano_zampini PetscErrorCode ierr; 24693b03a366Sstefano_zampini PC_IS* pcis = (PC_IS*)(pc->data); 24703b03a366Sstefano_zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 24713b03a366Sstefano_zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 247223d4d1a5SStefano Zampini PetscInt *nnz,*is_indices; 24733b03a366Sstefano_zampini PetscScalar *temp_quadrature_constraint; 2474534831adSStefano Zampini PetscInt *temp_indices,*temp_indices_to_constraint,*temp_indices_to_constraint_B,*local_to_B; 24753b03a366Sstefano_zampini PetscInt local_primal_size,i,j,k,total_counts,max_size_of_constraint; 24763b03a366Sstefano_zampini PetscInt n_constraints,n_vertices,size_of_constraint; 2477534831adSStefano Zampini PetscScalar quad_value; 24783b03a366Sstefano_zampini PetscBool nnsp_has_cnst=PETSC_FALSE,use_nnsp_true=pcbddc->use_nnsp_true; 24793b03a366Sstefano_zampini PetscInt nnsp_size=0,nnsp_addone=0,temp_constraints,temp_start_ptr; 24803b03a366Sstefano_zampini IS *used_IS; 248119fd82e9SBarry Smith MatType impMatType=MATSEQAIJ; 24823b03a366Sstefano_zampini PetscBLASInt Bs,Bt,lwork,lierr; 24833b03a366Sstefano_zampini PetscReal tol=1.0e-8; 2484fcda91b4SJed Brown MatNullSpace nearnullsp; 2485fcda91b4SJed Brown const Vec *nearnullvecs; 24863b03a366Sstefano_zampini Vec *localnearnullsp; 24873b03a366Sstefano_zampini PetscScalar *work,*temp_basis,*array_vector,*correlation_mat; 24883b03a366Sstefano_zampini PetscReal *rwork,*singular_vals; 2489534831adSStefano Zampini PetscBLASInt Bone=1,*ipiv; 2490534831adSStefano Zampini Vec temp_vec; 2491534831adSStefano Zampini Mat temp_mat; 2492534831adSStefano Zampini KSP temp_ksp; 2493ffe5efe1SStefano Zampini PC temp_pc; 2494534831adSStefano Zampini PetscInt s,start_constraint,dual_dofs; 2495534831adSStefano Zampini PetscBool compute_submatrix,useksp=PETSC_FALSE; 2496534831adSStefano Zampini PetscInt *aux_primal_permutation,*aux_primal_numbering; 2497534831adSStefano Zampini PetscBool boolforface,*change_basis; 2498de534f79Sstefano_zampini /* some ugly conditional declarations */ 24993b03a366Sstefano_zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 25003b03a366Sstefano_zampini PetscScalar dot_result; 25013b03a366Sstefano_zampini PetscScalar one=1.0,zero=0.0; 25023b03a366Sstefano_zampini PetscInt ii; 25033425bc38SStefano Zampini PetscScalar *singular_vectors; 25043425bc38SStefano Zampini PetscBLASInt *iwork,*ifail; 25053425bc38SStefano Zampini PetscReal dummy_real,abs_tol; 25063425bc38SStefano Zampini PetscBLASInt eigs_found; 25073b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 25083b03a366Sstefano_zampini PetscScalar val1,val2; 25093b03a366Sstefano_zampini #endif 25103425bc38SStefano Zampini #endif 25113b03a366Sstefano_zampini PetscBLASInt dummy_int; 25123b03a366Sstefano_zampini PetscScalar dummy_scalar; 25133b03a366Sstefano_zampini 25143b03a366Sstefano_zampini PetscFunctionBegin; 25153b03a366Sstefano_zampini /* check if near null space is attached to global mat */ 2516fcda91b4SJed Brown ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 2517fcda91b4SJed Brown if (nearnullsp) { 2518fcda91b4SJed Brown ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 25193b03a366Sstefano_zampini } else { /* if near null space is not provided it uses constants */ 25203b03a366Sstefano_zampini nnsp_has_cnst = PETSC_TRUE; 25213b03a366Sstefano_zampini use_nnsp_true = PETSC_TRUE; 25223b03a366Sstefano_zampini } 25233b03a366Sstefano_zampini if (nnsp_has_cnst) { 25243b03a366Sstefano_zampini nnsp_addone = 1; 25253b03a366Sstefano_zampini } 25263b03a366Sstefano_zampini /* 25273b03a366Sstefano_zampini Evaluate maximum storage size needed by the procedure 25283b03a366Sstefano_zampini - temp_indices will contain start index of each constraint stored as follows 25293b03a366Sstefano_zampini - temp_indices_to_constraint [temp_indices[i],...,temp[indices[i+1]-1] will contain the indices (in local numbering) on which the constraint acts 2530534831adSStefano Zampini - temp_indices_to_constraint_B[temp_indices[i],...,temp[indices[i+1]-1] will contain the indices (in boundary numbering) on which the constraint acts 25313b03a366Sstefano_zampini - temp_quadrature_constraint [temp_indices[i],...,temp[indices[i+1]-1] will contain the scalars representing the constraint itself 25323b03a366Sstefano_zampini */ 2533da1bb401SStefano Zampini 25343b03a366Sstefano_zampini total_counts = pcbddc->n_ISForFaces+pcbddc->n_ISForEdges; 25353b03a366Sstefano_zampini total_counts *= (nnsp_addone+nnsp_size); 2536da1bb401SStefano Zampini ierr = ISGetSize(pcbddc->ISForVertices,&n_vertices);CHKERRQ(ierr); 2537da1bb401SStefano Zampini total_counts += n_vertices; 25383b03a366Sstefano_zampini ierr = PetscMalloc((total_counts+1)*sizeof(PetscInt),&temp_indices);CHKERRQ(ierr); 2539534831adSStefano Zampini ierr = PetscMalloc((total_counts+1)*sizeof(PetscBool),&change_basis);CHKERRQ(ierr); 25403b03a366Sstefano_zampini total_counts = 0; 25413b03a366Sstefano_zampini max_size_of_constraint = 0; 25423b03a366Sstefano_zampini for (i=0;i<pcbddc->n_ISForEdges+pcbddc->n_ISForFaces;i++) { 25433b03a366Sstefano_zampini if (i<pcbddc->n_ISForEdges) { 25443b03a366Sstefano_zampini used_IS = &pcbddc->ISForEdges[i]; 25453b03a366Sstefano_zampini } else { 25463b03a366Sstefano_zampini used_IS = &pcbddc->ISForFaces[i-pcbddc->n_ISForEdges]; 25473b03a366Sstefano_zampini } 25483b03a366Sstefano_zampini ierr = ISGetSize(*used_IS,&j);CHKERRQ(ierr); 25493b03a366Sstefano_zampini total_counts += j; 25503b03a366Sstefano_zampini if (j>max_size_of_constraint) max_size_of_constraint=j; 25513b03a366Sstefano_zampini } 25523b03a366Sstefano_zampini total_counts *= (nnsp_addone+nnsp_size); 2553da1bb401SStefano Zampini total_counts += n_vertices; 25543b03a366Sstefano_zampini ierr = PetscMalloc(total_counts*sizeof(PetscScalar),&temp_quadrature_constraint);CHKERRQ(ierr); 25553b03a366Sstefano_zampini ierr = PetscMalloc(total_counts*sizeof(PetscInt),&temp_indices_to_constraint);CHKERRQ(ierr); 2556534831adSStefano Zampini ierr = PetscMalloc(total_counts*sizeof(PetscInt),&temp_indices_to_constraint_B);CHKERRQ(ierr); 2557534831adSStefano Zampini ierr = PetscMalloc(pcis->n*sizeof(PetscInt),&local_to_B);CHKERRQ(ierr); 2558534831adSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2559534831adSStefano Zampini for (i=0;i<pcis->n;i++) { 2560534831adSStefano Zampini local_to_B[i]=-1; 2561534831adSStefano Zampini } 2562534831adSStefano Zampini for (i=0;i<pcis->n_B;i++) { 2563534831adSStefano Zampini local_to_B[is_indices[i]]=i; 2564534831adSStefano Zampini } 2565534831adSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2566534831adSStefano Zampini 25673b03a366Sstefano_zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd or LAPACKsyev/LAPACKheev */ 25683b03a366Sstefano_zampini rwork = 0; 25693b03a366Sstefano_zampini work = 0; 25703b03a366Sstefano_zampini singular_vals = 0; 25713b03a366Sstefano_zampini temp_basis = 0; 25723b03a366Sstefano_zampini correlation_mat = 0; 25733b03a366Sstefano_zampini if (!pcbddc->use_nnsp_true) { 25743b03a366Sstefano_zampini PetscScalar temp_work; 25753b03a366Sstefano_zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 25763b03a366Sstefano_zampini /* POD */ 25773b03a366Sstefano_zampini PetscInt max_n; 25783b03a366Sstefano_zampini max_n = nnsp_addone+nnsp_size; 25793b03a366Sstefano_zampini /* using some techniques borrowed from Proper Orthogonal Decomposition */ 25803b03a366Sstefano_zampini ierr = PetscMalloc(max_n*max_n*sizeof(PetscScalar),&correlation_mat);CHKERRQ(ierr); 25813425bc38SStefano Zampini ierr = PetscMalloc(max_n*max_n*sizeof(PetscScalar),&singular_vectors);CHKERRQ(ierr); 25823b03a366Sstefano_zampini ierr = PetscMalloc(max_n*sizeof(PetscReal),&singular_vals);CHKERRQ(ierr); 25833b03a366Sstefano_zampini ierr = PetscMalloc(max_size_of_constraint*(nnsp_addone+nnsp_size)*sizeof(PetscScalar),&temp_basis);CHKERRQ(ierr); 25843b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 25853b03a366Sstefano_zampini ierr = PetscMalloc(3*max_n*sizeof(PetscReal),&rwork);CHKERRQ(ierr); 25863b03a366Sstefano_zampini #endif 25873425bc38SStefano Zampini ierr = PetscMalloc(5*max_n*sizeof(PetscBLASInt),&iwork);CHKERRQ(ierr); 25883425bc38SStefano Zampini ierr = PetscMalloc(max_n*sizeof(PetscBLASInt),&ifail);CHKERRQ(ierr); 25893b03a366Sstefano_zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 2590*c5df96a5SBarry Smith ierr = PetscBLASIntCast(max_n,&Bt);CHKERRQ(ierr); 25913b03a366Sstefano_zampini lwork =-1; 25923425bc38SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 25933b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 25943425bc38SStefano Zampini abs_tol=1.e-8; 25953425bc38SStefano Zampini LAPACKsyevx_("V","A","U",&Bt,correlation_mat,&Bt,&dummy_real,&dummy_real,&dummy_int,&dummy_int, 25963425bc38SStefano Zampini &abs_tol,&eigs_found,singular_vals,singular_vectors,&Bt,&temp_work,&lwork,iwork,ifail,&lierr); 25973b03a366Sstefano_zampini #else 25983425bc38SStefano Zampini SETERRQ(((PetscObject) pc)->comm, PETSC_ERR_SUP, "Not yet implemented for complexes when PETSC_MISSING_GESVD = 1"); 25993b03a366Sstefano_zampini #endif 26003425bc38SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEVX Lapack routine %d",(int)lierr); 26013425bc38SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 26023b03a366Sstefano_zampini #else /* on missing GESVD */ 26033b03a366Sstefano_zampini /* SVD */ 26043b03a366Sstefano_zampini PetscInt max_n,min_n; 26053b03a366Sstefano_zampini max_n = max_size_of_constraint; 26063b03a366Sstefano_zampini min_n = nnsp_addone+nnsp_size; 26073b03a366Sstefano_zampini if (max_size_of_constraint < (nnsp_addone+nnsp_size)) { 26083b03a366Sstefano_zampini min_n = max_size_of_constraint; 26093b03a366Sstefano_zampini max_n = nnsp_addone+nnsp_size; 26103b03a366Sstefano_zampini } 26113b03a366Sstefano_zampini ierr = PetscMalloc(min_n*sizeof(PetscReal),&singular_vals);CHKERRQ(ierr); 26123b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 26133b03a366Sstefano_zampini ierr = PetscMalloc(5*min_n*sizeof(PetscReal),&rwork);CHKERRQ(ierr); 26143b03a366Sstefano_zampini #endif 26153b03a366Sstefano_zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 26163b03a366Sstefano_zampini lwork =-1; 2617*c5df96a5SBarry Smith ierr = PetscBLASIntCast(max_n,&Bs);CHKERRQ(ierr); 2618*c5df96a5SBarry Smith ierr = PetscBLASIntCast(min_n,&Bt);CHKERRQ(ierr); 26193b03a366Sstefano_zampini dummy_int = Bs; 2620670f3ff9SJed Brown ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 26213b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 26223b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[0],&Bs,singular_vals, 26233b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,&temp_work,&lwork,&lierr); 26243b03a366Sstefano_zampini #else 26253b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[0],&Bs,singular_vals, 26263b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,&temp_work,&lwork,rwork,&lierr); 26273b03a366Sstefano_zampini #endif 26283b03a366Sstefano_zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SVD Lapack routine %d",(int)lierr); 2629670f3ff9SJed Brown ierr = PetscFPTrapPop();CHKERRQ(ierr); 26303b03a366Sstefano_zampini #endif 26313b03a366Sstefano_zampini /* Allocate optimal workspace */ 2632*c5df96a5SBarry Smith ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 26333b03a366Sstefano_zampini total_counts = (PetscInt)lwork; 26343b03a366Sstefano_zampini ierr = PetscMalloc(total_counts*sizeof(PetscScalar),&work);CHKERRQ(ierr); 26353b03a366Sstefano_zampini } 26363b03a366Sstefano_zampini /* get local part of global near null space vectors */ 26373b03a366Sstefano_zampini ierr = PetscMalloc(nnsp_size*sizeof(Vec),&localnearnullsp);CHKERRQ(ierr); 26383b03a366Sstefano_zampini for (k=0;k<nnsp_size;k++) { 26393b03a366Sstefano_zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 2640fcda91b4SJed Brown ierr = VecScatterBegin(matis->ctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2641fcda91b4SJed Brown ierr = VecScatterEnd (matis->ctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 26423b03a366Sstefano_zampini } 26433b03a366Sstefano_zampini /* Now we can loop on constraining sets */ 26443b03a366Sstefano_zampini total_counts=0; 26453b03a366Sstefano_zampini temp_indices[0]=0; 2646da1bb401SStefano Zampini /* vertices */ 2647da1bb401SStefano Zampini PetscBool used_vertex; 2648da1bb401SStefano Zampini ierr = ISGetIndices(pcbddc->ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2649da1bb401SStefano Zampini if (nnsp_has_cnst) { /* consider all vertices */ 2650da1bb401SStefano Zampini for (i=0;i<n_vertices;i++) { 2651da1bb401SStefano Zampini temp_indices_to_constraint[temp_indices[total_counts]]=is_indices[i]; 2652534831adSStefano Zampini temp_indices_to_constraint_B[temp_indices[total_counts]]=local_to_B[is_indices[i]]; 2653da1bb401SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]]=1.0; 2654da1bb401SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+1; 2655534831adSStefano Zampini change_basis[total_counts]=PETSC_FALSE; 2656da1bb401SStefano Zampini total_counts++; 2657da1bb401SStefano Zampini } 2658da1bb401SStefano Zampini } else { /* consider vertices for which exist at least a localnearnullsp which is not null there */ 2659da1bb401SStefano Zampini for (i=0;i<n_vertices;i++) { 2660da1bb401SStefano Zampini used_vertex=PETSC_FALSE; 2661da1bb401SStefano Zampini k=0; 2662da1bb401SStefano Zampini while (!used_vertex && k<nnsp_size) { 2663da1bb401SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array_vector);CHKERRQ(ierr); 2664da1bb401SStefano Zampini if (PetscAbsScalar(array_vector[is_indices[i]])>0.0) { 2665da1bb401SStefano Zampini temp_indices_to_constraint[temp_indices[total_counts]]=is_indices[i]; 2666534831adSStefano Zampini temp_indices_to_constraint_B[temp_indices[total_counts]]=local_to_B[is_indices[i]]; 2667da1bb401SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]]=1.0; 2668da1bb401SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+1; 2669534831adSStefano Zampini change_basis[total_counts]=PETSC_FALSE; 2670da1bb401SStefano Zampini total_counts++; 2671da1bb401SStefano Zampini used_vertex=PETSC_TRUE; 2672da1bb401SStefano Zampini } 2673da1bb401SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array_vector);CHKERRQ(ierr); 2674da1bb401SStefano Zampini k++; 2675da1bb401SStefano Zampini } 2676da1bb401SStefano Zampini } 2677da1bb401SStefano Zampini } 2678da1bb401SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2679da1bb401SStefano Zampini n_vertices=total_counts; 2680da1bb401SStefano Zampini /* edges and faces */ 26813b03a366Sstefano_zampini for (i=0;i<pcbddc->n_ISForEdges+pcbddc->n_ISForFaces;i++) { 26823b03a366Sstefano_zampini if (i<pcbddc->n_ISForEdges) { 26833b03a366Sstefano_zampini used_IS = &pcbddc->ISForEdges[i]; 2684534831adSStefano Zampini boolforface = pcbddc->usechangeofbasis; 26853b03a366Sstefano_zampini } else { 26863b03a366Sstefano_zampini used_IS = &pcbddc->ISForFaces[i-pcbddc->n_ISForEdges]; 2687534831adSStefano Zampini boolforface = pcbddc->usechangeonfaces; 26883b03a366Sstefano_zampini } 26893b03a366Sstefano_zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 26903b03a366Sstefano_zampini temp_start_ptr = total_counts; /* need to know the starting index of constraints stored */ 26913b03a366Sstefano_zampini ierr = ISGetSize(*used_IS,&size_of_constraint);CHKERRQ(ierr); 26923b03a366Sstefano_zampini ierr = ISGetIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 26933b03a366Sstefano_zampini if (nnsp_has_cnst) { 26943b03a366Sstefano_zampini temp_constraints++; 2695534831adSStefano Zampini quad_value = (PetscScalar) (1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 26963b03a366Sstefano_zampini for (j=0;j<size_of_constraint;j++) { 26973b03a366Sstefano_zampini temp_indices_to_constraint[temp_indices[total_counts]+j]=is_indices[j]; 2698534831adSStefano Zampini temp_indices_to_constraint_B[temp_indices[total_counts]+j]=local_to_B[is_indices[j]]; 26993b03a366Sstefano_zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=quad_value; 27003b03a366Sstefano_zampini } 27013b03a366Sstefano_zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 2702534831adSStefano Zampini change_basis[total_counts]=boolforface; 27033b03a366Sstefano_zampini total_counts++; 27043b03a366Sstefano_zampini } 27053b03a366Sstefano_zampini for (k=0;k<nnsp_size;k++) { 27063b03a366Sstefano_zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array_vector);CHKERRQ(ierr); 27073b03a366Sstefano_zampini for (j=0;j<size_of_constraint;j++) { 27083b03a366Sstefano_zampini temp_indices_to_constraint[temp_indices[total_counts]+j]=is_indices[j]; 2709534831adSStefano Zampini temp_indices_to_constraint_B[temp_indices[total_counts]+j]=local_to_B[is_indices[j]]; 27103b03a366Sstefano_zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=array_vector[is_indices[j]]; 27113b03a366Sstefano_zampini } 27123b03a366Sstefano_zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array_vector);CHKERRQ(ierr); 2713de534f79Sstefano_zampini quad_value = 1.0; 2714de534f79Sstefano_zampini if (use_nnsp_true) { /* check if array is null on the connected component in case use_nnsp_true has been requested */ 2715*c5df96a5SBarry Smith ierr = PetscBLASIntCast(size_of_constraint,&Bs);CHKERRQ(ierr); 2716de534f79Sstefano_zampini quad_value = BLASasum_(&Bs,&temp_quadrature_constraint[temp_indices[total_counts]],&Bone); 2717de534f79Sstefano_zampini } 2718de534f79Sstefano_zampini if (quad_value > 0.0) { /* keep indices and values */ 2719de534f79Sstefano_zampini temp_constraints++; 27203b03a366Sstefano_zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 2721534831adSStefano Zampini change_basis[total_counts]=boolforface; 27223b03a366Sstefano_zampini total_counts++; 27233b03a366Sstefano_zampini } 2724de534f79Sstefano_zampini } 27253b03a366Sstefano_zampini ierr = ISRestoreIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2726de534f79Sstefano_zampini /* perform SVD on the constraint if use_nnsp_true has not be requested by the user */ 27273b03a366Sstefano_zampini if (!use_nnsp_true) { 2728*c5df96a5SBarry Smith ierr = PetscBLASIntCast(size_of_constraint,&Bs);CHKERRQ(ierr); 2729*c5df96a5SBarry Smith ierr = PetscBLASIntCast(temp_constraints,&Bt);CHKERRQ(ierr); 2730de534f79Sstefano_zampini 27313b03a366Sstefano_zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 27323b03a366Sstefano_zampini ierr = PetscMemzero(correlation_mat,Bt*Bt*sizeof(PetscScalar));CHKERRQ(ierr); 27333b03a366Sstefano_zampini /* Store upper triangular part of correlation matrix */ 27343b03a366Sstefano_zampini for (j=0;j<temp_constraints;j++) { 27353b03a366Sstefano_zampini for (k=0;k<j+1;k++) { 27363b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 27373425bc38SStefano Zampini /* hand made complex dot product -> replace */ 27383b03a366Sstefano_zampini dot_result = 0.0; 27393b03a366Sstefano_zampini for (ii=0; ii<size_of_constraint; ii++) { 27403b03a366Sstefano_zampini val1 = temp_quadrature_constraint[temp_indices[temp_start_ptr+j]+ii]; 27413b03a366Sstefano_zampini val2 = temp_quadrature_constraint[temp_indices[temp_start_ptr+k]+ii]; 27423b03a366Sstefano_zampini dot_result += val1*PetscConj(val2); 27433b03a366Sstefano_zampini } 27443b03a366Sstefano_zampini #else 27453b03a366Sstefano_zampini dot_result = BLASdot_(&Bs,&temp_quadrature_constraint[temp_indices[temp_start_ptr+j]],&Bone, 27463b03a366Sstefano_zampini &temp_quadrature_constraint[temp_indices[temp_start_ptr+k]],&Bone); 27473b03a366Sstefano_zampini #endif 27483b03a366Sstefano_zampini correlation_mat[j*temp_constraints+k]=dot_result; 27493b03a366Sstefano_zampini } 27503b03a366Sstefano_zampini } 27513425bc38SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 27523b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 27533425bc38SStefano Zampini /* LAPACKsyev_("V","U",&Bt,correlation_mat,&Bt,singular_vals,work,&lwork,&lierr); */ 27543425bc38SStefano Zampini LAPACKsyevx_("V","A","U",&Bt,correlation_mat,&Bt,&dummy_real,&dummy_real,&dummy_int,&dummy_int, 27553425bc38SStefano Zampini &abs_tol,&eigs_found,singular_vals,singular_vectors,&Bt,work,&lwork,iwork,ifail,&lierr); 27563b03a366Sstefano_zampini #else 27573425bc38SStefano Zampini /* LAPACK call is missing here! TODO */ 27583425bc38SStefano Zampini SETERRQ(((PetscObject) pc)->comm, PETSC_ERR_SUP, "Not yet implemented for complexes when PETSC_MISSING_GESVD = 1"); 27593b03a366Sstefano_zampini #endif 27603425bc38SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEVX Lapack routine %d",(int)lierr); 27613425bc38SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 27623b03a366Sstefano_zampini /* retain eigenvalues greater than tol: note that lapack SYEV gives eigs in ascending order */ 27633b03a366Sstefano_zampini j=0; 27643b03a366Sstefano_zampini while (j < Bt && singular_vals[j] < tol) j++; 27653b03a366Sstefano_zampini total_counts=total_counts-j; 27663b03a366Sstefano_zampini if (j<temp_constraints) { 27673b03a366Sstefano_zampini for (k=j;k<Bt;k++) { singular_vals[k]=1.0/PetscSqrtReal(singular_vals[k]); } 27683425bc38SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 27693b03a366Sstefano_zampini BLASgemm_("N","N",&Bs,&Bt,&Bt,&one,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Bs,correlation_mat,&Bt,&zero,temp_basis,&Bs); 27703425bc38SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 27713b03a366Sstefano_zampini /* copy POD basis into used quadrature memory */ 27723b03a366Sstefano_zampini for (k=0;k<Bt-j;k++) { 27733b03a366Sstefano_zampini for (ii=0;ii<size_of_constraint;ii++) { 27743b03a366Sstefano_zampini temp_quadrature_constraint[temp_indices[temp_start_ptr+k]+ii]=singular_vals[Bt-1-k]*temp_basis[(Bt-1-k)*size_of_constraint+ii]; 27753b03a366Sstefano_zampini } 27763b03a366Sstefano_zampini } 27773b03a366Sstefano_zampini } 2778de534f79Sstefano_zampini 27793b03a366Sstefano_zampini #else /* on missing GESVD */ 27803b03a366Sstefano_zampini PetscInt min_n = temp_constraints; 27813b03a366Sstefano_zampini if (min_n > size_of_constraint) min_n = size_of_constraint; 27823b03a366Sstefano_zampini dummy_int = Bs; 2783670f3ff9SJed Brown ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 27843b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 27853b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Bs,singular_vals, 27863b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,work,&lwork,&lierr); 27873b03a366Sstefano_zampini #else 27883b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Bs,singular_vals, 27893b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,work,&lwork,rwork,&lierr); 27903b03a366Sstefano_zampini #endif 27913b03a366Sstefano_zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SVD Lapack routine %d",(int)lierr); 2792670f3ff9SJed Brown ierr = PetscFPTrapPop();CHKERRQ(ierr); 27933b03a366Sstefano_zampini /* retain eigenvalues greater than tol: note that lapack SVD gives eigs in descending order */ 27943b03a366Sstefano_zampini j=0; 27953b03a366Sstefano_zampini while (j < min_n && singular_vals[min_n-j-1] < tol) j++; 27963b03a366Sstefano_zampini total_counts = total_counts-(PetscInt)Bt+(min_n-j); 27973b03a366Sstefano_zampini #endif 27983b03a366Sstefano_zampini } 27993b03a366Sstefano_zampini } 2800534831adSStefano Zampini 2801da1bb401SStefano Zampini n_constraints=total_counts-n_vertices; 2802da1bb401SStefano Zampini local_primal_size = total_counts; 28033b03a366Sstefano_zampini /* set quantities in pcbddc data structure */ 28043b03a366Sstefano_zampini pcbddc->n_vertices = n_vertices; 28053b03a366Sstefano_zampini pcbddc->n_constraints = n_constraints; 2806da1bb401SStefano Zampini pcbddc->local_primal_size = local_primal_size; 2807534831adSStefano Zampini 2808534831adSStefano Zampini /* Create constraint matrix */ 2809534831adSStefano Zampini /* The constraint matrix is used to compute the l2g map of primal dofs */ 2810534831adSStefano Zampini /* so we need to set it up properly either with or without change of basis */ 2811534831adSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 2812534831adSStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,impMatType);CHKERRQ(ierr); 2813534831adSStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,local_primal_size,pcis->n,local_primal_size,pcis->n);CHKERRQ(ierr); 2814534831adSStefano Zampini /* compute a local numbering of constraints : vertices first then constraints */ 2815534831adSStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 2816534831adSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_vector);CHKERRQ(ierr); 2817534831adSStefano Zampini ierr = PetscMalloc(local_primal_size*sizeof(PetscInt),&aux_primal_numbering);CHKERRQ(ierr); 2818534831adSStefano Zampini ierr = PetscMalloc(local_primal_size*sizeof(PetscInt),&aux_primal_permutation);CHKERRQ(ierr); 2819534831adSStefano Zampini total_counts=0; 2820534831adSStefano Zampini /* find vertices: subdomain corners plus dofs with basis changed */ 2821534831adSStefano Zampini for (i=0;i<local_primal_size;i++) { 2822534831adSStefano Zampini size_of_constraint=temp_indices[i+1]-temp_indices[i]; 2823534831adSStefano Zampini if (change_basis[i] || size_of_constraint == 1) { 2824534831adSStefano Zampini k=0; 2825534831adSStefano Zampini while (k < size_of_constraint && array_vector[temp_indices_to_constraint[temp_indices[i]+size_of_constraint-k-1]] != 0.0) { 2826534831adSStefano Zampini k=k+1; 2827534831adSStefano Zampini } 2828534831adSStefano Zampini j=temp_indices_to_constraint[temp_indices[i]+size_of_constraint-k-1]; 2829534831adSStefano Zampini array_vector[j] = 1.0; 2830534831adSStefano Zampini aux_primal_numbering[total_counts]=j; 2831534831adSStefano Zampini aux_primal_permutation[total_counts]=total_counts; 2832534831adSStefano Zampini total_counts++; 2833534831adSStefano Zampini } 2834534831adSStefano Zampini } 2835534831adSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_vector);CHKERRQ(ierr); 2836534831adSStefano Zampini /* permute indices in order to have a sorted set of vertices */ 2837534831adSStefano Zampini ierr = PetscSortIntWithPermutation(total_counts,aux_primal_numbering,aux_primal_permutation); 2838534831adSStefano Zampini /* nonzero structure */ 2839534831adSStefano Zampini ierr = PetscMalloc(local_primal_size*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 2840534831adSStefano Zampini for (i=0;i<total_counts;i++) { 2841534831adSStefano Zampini nnz[i]=1; 2842534831adSStefano Zampini } 2843534831adSStefano Zampini j=total_counts; 2844534831adSStefano Zampini for (i=n_vertices;i<local_primal_size;i++) { 2845534831adSStefano Zampini if (!change_basis[i]) { 2846534831adSStefano Zampini nnz[j]=temp_indices[i+1]-temp_indices[i]; 2847534831adSStefano Zampini j++; 2848534831adSStefano Zampini } 2849534831adSStefano Zampini } 2850534831adSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 2851534831adSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2852534831adSStefano Zampini /* set values in constraint matrix */ 2853534831adSStefano Zampini for (i=0;i<total_counts;i++) { 2854534831adSStefano Zampini j = aux_primal_permutation[i]; 2855534831adSStefano Zampini k = aux_primal_numbering[j]; 2856534831adSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,k,1.0,INSERT_VALUES);CHKERRQ(ierr); 2857534831adSStefano Zampini } 2858534831adSStefano Zampini for (i=n_vertices;i<local_primal_size;i++) { 2859534831adSStefano Zampini if (!change_basis[i]) { 2860534831adSStefano Zampini size_of_constraint=temp_indices[i+1]-temp_indices[i]; 2861534831adSStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&total_counts,size_of_constraint,&temp_indices_to_constraint[temp_indices[i]],&temp_quadrature_constraint[temp_indices[i]],INSERT_VALUES);CHKERRQ(ierr); 2862534831adSStefano Zampini total_counts++; 2863534831adSStefano Zampini } 2864534831adSStefano Zampini } 2865534831adSStefano Zampini ierr = PetscFree(aux_primal_numbering);CHKERRQ(ierr); 2866534831adSStefano Zampini ierr = PetscFree(aux_primal_permutation);CHKERRQ(ierr); 2867534831adSStefano Zampini /* assembling */ 2868534831adSStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2869534831adSStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2870534831adSStefano Zampini 2871534831adSStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->usechangeofbasis is FALSE */ 2872534831adSStefano Zampini if (pcbddc->usechangeofbasis) { 2873534831adSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 2874534831adSStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,impMatType);CHKERRQ(ierr); 2875534831adSStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,pcis->n_B,pcis->n_B,pcis->n_B,pcis->n_B);CHKERRQ(ierr); 2876534831adSStefano Zampini /* work arrays */ 2877534831adSStefano Zampini /* we need to reuse these arrays, so we free them */ 2878534831adSStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 2879534831adSStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2880534831adSStefano Zampini ierr = PetscMalloc(pcis->n_B*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 2881534831adSStefano Zampini ierr = PetscMalloc((nnsp_addone+nnsp_size)*(nnsp_addone+nnsp_size)*sizeof(PetscScalar),&temp_basis);CHKERRQ(ierr); 2882534831adSStefano Zampini ierr = PetscMalloc((nnsp_addone+nnsp_size)*sizeof(PetscScalar),&work);CHKERRQ(ierr); 2883534831adSStefano Zampini ierr = PetscMalloc((nnsp_addone+nnsp_size)*sizeof(PetscBLASInt),&ipiv);CHKERRQ(ierr); 2884534831adSStefano Zampini for (i=0;i<pcis->n_B;i++) { 2885534831adSStefano Zampini nnz[i]=1; 2886534831adSStefano Zampini } 2887534831adSStefano Zampini /* Overestimated nonzeros per row */ 2888534831adSStefano Zampini k=1; 2889534831adSStefano Zampini for (i=pcbddc->n_vertices;i<local_primal_size;i++) { 2890534831adSStefano Zampini if (change_basis[i]) { 2891534831adSStefano Zampini size_of_constraint = temp_indices[i+1]-temp_indices[i]; 2892534831adSStefano Zampini if (k < size_of_constraint) { 2893534831adSStefano Zampini k = size_of_constraint; 2894534831adSStefano Zampini } 2895534831adSStefano Zampini for (j=0;j<size_of_constraint;j++) { 2896534831adSStefano Zampini nnz[temp_indices_to_constraint_B[temp_indices[i]+j]] = size_of_constraint; 2897534831adSStefano Zampini } 2898534831adSStefano Zampini } 2899534831adSStefano Zampini } 2900534831adSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 2901534831adSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2902534831adSStefano Zampini /* Temporary array to store indices */ 2903534831adSStefano Zampini ierr = PetscMalloc(k*sizeof(PetscInt),&is_indices);CHKERRQ(ierr); 2904534831adSStefano Zampini /* Set initial identity in the matrix */ 2905534831adSStefano Zampini for (i=0;i<pcis->n_B;i++) { 2906534831adSStefano Zampini ierr = MatSetValue(pcbddc->ChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 2907534831adSStefano Zampini } 2908534831adSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 2909534831adSStefano Zampini /* Change of basis matrix is evaluated as the FIRST APPROACH in */ 2910534831adSStefano Zampini /* Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (6.2.1) */ 2911534831adSStefano Zampini temp_constraints = 0; 291293dc3b60SStefano Zampini if (pcbddc->n_vertices < local_primal_size) { 2913534831adSStefano Zampini temp_start_ptr = temp_indices_to_constraint_B[temp_indices[pcbddc->n_vertices]]; 291493dc3b60SStefano Zampini } 2915534831adSStefano Zampini for (i=pcbddc->n_vertices;i<local_primal_size;i++) { 2916534831adSStefano Zampini if (change_basis[i]) { 2917534831adSStefano Zampini compute_submatrix = PETSC_FALSE; 2918534831adSStefano Zampini useksp = PETSC_FALSE; 2919534831adSStefano Zampini if (temp_start_ptr == temp_indices_to_constraint_B[temp_indices[i]]) { 2920534831adSStefano Zampini temp_constraints++; 292104eaf177SStefano Zampini if (i == local_primal_size -1 || temp_start_ptr != temp_indices_to_constraint_B[temp_indices[i+1]]) { 2922534831adSStefano Zampini compute_submatrix = PETSC_TRUE; 2923534831adSStefano Zampini } 2924534831adSStefano Zampini } 2925534831adSStefano Zampini if (compute_submatrix) { 2926534831adSStefano Zampini if (temp_constraints > 1 || pcbddc->use_nnsp_true) { 2927534831adSStefano Zampini useksp = PETSC_TRUE; 2928534831adSStefano Zampini } 2929534831adSStefano Zampini size_of_constraint = temp_indices[i+1]-temp_indices[i]; 2930534831adSStefano Zampini if (useksp) { /* experimental */ 2931534831adSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&temp_mat);CHKERRQ(ierr); 2932534831adSStefano Zampini ierr = MatSetType(temp_mat,impMatType);CHKERRQ(ierr); 2933534831adSStefano Zampini ierr = MatSetSizes(temp_mat,size_of_constraint,size_of_constraint,size_of_constraint,size_of_constraint);CHKERRQ(ierr); 2934534831adSStefano Zampini ierr = MatSeqAIJSetPreallocation(temp_mat,size_of_constraint,PETSC_NULL);CHKERRQ(ierr); 2935534831adSStefano Zampini } 2936534831adSStefano Zampini /* First _size_of_constraint-temp_constraints_ columns */ 2937534831adSStefano Zampini dual_dofs = size_of_constraint-temp_constraints; 2938534831adSStefano Zampini start_constraint = i+1-temp_constraints; 2939534831adSStefano Zampini for (s=0;s<dual_dofs;s++) { 2940534831adSStefano Zampini is_indices[0] = s; 2941534831adSStefano Zampini for (j=0;j<temp_constraints;j++) { 2942534831adSStefano Zampini for (k=0;k<temp_constraints;k++) { 2943534831adSStefano Zampini temp_basis[j*temp_constraints+k]=temp_quadrature_constraint[temp_indices[start_constraint+k]+s+j+1]; 2944534831adSStefano Zampini } 2945534831adSStefano Zampini work[j]=-temp_quadrature_constraint[temp_indices[start_constraint+j]+s]; 2946534831adSStefano Zampini is_indices[j+1]=s+j+1; 2947534831adSStefano Zampini } 2948534831adSStefano Zampini Bt = temp_constraints; 2949534831adSStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2950534831adSStefano Zampini LAPACKgesv_(&Bt,&Bone,temp_basis,&Bt,ipiv,work,&Bt,&lierr); 2951534831adSStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESV Lapack routine %d",(int)lierr); 2952534831adSStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2953534831adSStefano Zampini j = temp_indices_to_constraint_B[temp_indices[start_constraint]+s]; 2954534831adSStefano Zampini ierr = MatSetValues(pcbddc->ChangeOfBasisMatrix,temp_constraints,&temp_indices_to_constraint_B[temp_indices[start_constraint]+s+1],1,&j,work,INSERT_VALUES);CHKERRQ(ierr); 2955534831adSStefano Zampini if (useksp) { 2956534831adSStefano Zampini /* temp mat with transposed rows and columns */ 2957534831adSStefano Zampini ierr = MatSetValues(temp_mat,1,&s,temp_constraints,&is_indices[1],work,INSERT_VALUES);CHKERRQ(ierr); 2958534831adSStefano Zampini ierr = MatSetValue(temp_mat,is_indices[0],is_indices[0],1.0,INSERT_VALUES);CHKERRQ(ierr); 2959534831adSStefano Zampini } 2960534831adSStefano Zampini } 2961534831adSStefano Zampini if (useksp) { 2962534831adSStefano Zampini /* last rows of temp_mat */ 2963534831adSStefano Zampini for (j=0;j<size_of_constraint;j++) { 2964534831adSStefano Zampini is_indices[j] = j; 2965534831adSStefano Zampini } 2966534831adSStefano Zampini for (s=0;s<temp_constraints;s++) { 2967534831adSStefano Zampini k = s + dual_dofs; 2968534831adSStefano Zampini ierr = MatSetValues(temp_mat,1,&k,size_of_constraint,is_indices,&temp_quadrature_constraint[temp_indices[start_constraint+s]],INSERT_VALUES);CHKERRQ(ierr); 2969534831adSStefano Zampini } 2970534831adSStefano Zampini ierr = MatAssemblyBegin(temp_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2971534831adSStefano Zampini ierr = MatAssemblyEnd(temp_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2972534831adSStefano Zampini ierr = MatGetVecs(temp_mat,&temp_vec,PETSC_NULL);CHKERRQ(ierr); 2973534831adSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&temp_ksp);CHKERRQ(ierr); 2974534831adSStefano Zampini ierr = KSPSetOperators(temp_ksp,temp_mat,temp_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 2975534831adSStefano Zampini ierr = KSPSetType(temp_ksp,KSPPREONLY);CHKERRQ(ierr); 2976ffe5efe1SStefano Zampini ierr = KSPGetPC(temp_ksp,&temp_pc);CHKERRQ(ierr); 2977ffe5efe1SStefano Zampini ierr = PCSetType(temp_pc,PCLU);CHKERRQ(ierr); 2978534831adSStefano Zampini ierr = KSPSetUp(temp_ksp);CHKERRQ(ierr); 2979534831adSStefano Zampini for (s=0;s<temp_constraints;s++) { 2980534831adSStefano Zampini ierr = VecSet(temp_vec,0.0);CHKERRQ(ierr); 2981534831adSStefano Zampini ierr = VecSetValue(temp_vec,s+dual_dofs,1.0,INSERT_VALUES);CHKERRQ(ierr); 2982534831adSStefano Zampini ierr = VecAssemblyBegin(temp_vec);CHKERRQ(ierr); 2983534831adSStefano Zampini ierr = VecAssemblyEnd(temp_vec);CHKERRQ(ierr); 2984534831adSStefano Zampini ierr = KSPSolve(temp_ksp,temp_vec,temp_vec);CHKERRQ(ierr); 2985534831adSStefano Zampini ierr = VecGetArray(temp_vec,&array_vector);CHKERRQ(ierr); 2986534831adSStefano Zampini j = temp_indices_to_constraint_B[temp_indices[start_constraint+s]+size_of_constraint-s-1]; 2987534831adSStefano Zampini /* last columns of change of basis matrix associated to new primal dofs */ 2988534831adSStefano Zampini ierr = MatSetValues(pcbddc->ChangeOfBasisMatrix,size_of_constraint,&temp_indices_to_constraint_B[temp_indices[start_constraint+s]],1,&j,array_vector,INSERT_VALUES);CHKERRQ(ierr); 2989534831adSStefano Zampini ierr = VecRestoreArray(temp_vec,&array_vector);CHKERRQ(ierr); 2990534831adSStefano Zampini } 2991534831adSStefano Zampini ierr = MatDestroy(&temp_mat);CHKERRQ(ierr); 2992534831adSStefano Zampini ierr = KSPDestroy(&temp_ksp);CHKERRQ(ierr); 2993534831adSStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 2994534831adSStefano Zampini } else { 2995534831adSStefano Zampini /* last columns of change of basis matrix associated to new primal dofs */ 2996534831adSStefano Zampini for (s=0;s<temp_constraints;s++) { 2997534831adSStefano Zampini j = temp_indices_to_constraint_B[temp_indices[start_constraint+s]+size_of_constraint-s-1]; 2998534831adSStefano Zampini ierr = MatSetValues(pcbddc->ChangeOfBasisMatrix,size_of_constraint,&temp_indices_to_constraint_B[temp_indices[start_constraint+s]],1,&j,&temp_quadrature_constraint[temp_indices[start_constraint+s]],INSERT_VALUES);CHKERRQ(ierr); 2999534831adSStefano Zampini } 3000534831adSStefano Zampini } 3001534831adSStefano Zampini /* prepare for the next cycle */ 3002534831adSStefano Zampini temp_constraints = 0; 300304eaf177SStefano Zampini if (i != local_primal_size -1) { 3004534831adSStefano Zampini temp_start_ptr = temp_indices_to_constraint_B[temp_indices[i+1]]; 3005534831adSStefano Zampini } 3006534831adSStefano Zampini } 3007534831adSStefano Zampini } 300804eaf177SStefano Zampini } 3009534831adSStefano Zampini /* assembling */ 3010534831adSStefano Zampini ierr = MatAssemblyBegin(pcbddc->ChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3011534831adSStefano Zampini ierr = MatAssemblyEnd(pcbddc->ChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3012534831adSStefano Zampini ierr = PetscFree(ipiv);CHKERRQ(ierr); 3013534831adSStefano Zampini ierr = PetscFree(is_indices);CHKERRQ(ierr); 3014534831adSStefano Zampini } 30153b03a366Sstefano_zampini /* free workspace no longer needed */ 30163b03a366Sstefano_zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 30173b03a366Sstefano_zampini ierr = PetscFree(work);CHKERRQ(ierr); 30183b03a366Sstefano_zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 30193b03a366Sstefano_zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 30203b03a366Sstefano_zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 30213b03a366Sstefano_zampini ierr = PetscFree(temp_indices);CHKERRQ(ierr); 3022534831adSStefano Zampini ierr = PetscFree(change_basis);CHKERRQ(ierr); 30233b03a366Sstefano_zampini ierr = PetscFree(temp_indices_to_constraint);CHKERRQ(ierr); 3024534831adSStefano Zampini ierr = PetscFree(temp_indices_to_constraint_B);CHKERRQ(ierr); 3025534831adSStefano Zampini ierr = PetscFree(local_to_B);CHKERRQ(ierr); 30263b03a366Sstefano_zampini ierr = PetscFree(temp_quadrature_constraint);CHKERRQ(ierr); 30273425bc38SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 30283425bc38SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 30293425bc38SStefano Zampini ierr = PetscFree(ifail);CHKERRQ(ierr); 30303425bc38SStefano Zampini ierr = PetscFree(singular_vectors);CHKERRQ(ierr); 30313425bc38SStefano Zampini #endif 3032da1bb401SStefano Zampini for (k=0;k<nnsp_size;k++) { 3033da1bb401SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 3034da1bb401SStefano Zampini } 30353b03a366Sstefano_zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 30363b03a366Sstefano_zampini PetscFunctionReturn(0); 30373b03a366Sstefano_zampini } 30383b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 30390c7d97c5SJed Brown #undef __FUNCT__ 30400c7d97c5SJed Brown #define __FUNCT__ "PCBDDCCoarseSetUp" 304153cdbc3dSStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC pc) 30420c7d97c5SJed Brown { 30430c7d97c5SJed Brown PetscErrorCode ierr; 30440c7d97c5SJed Brown PC_IS* pcis = (PC_IS*)(pc->data); 30450c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 30460c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 3047534831adSStefano Zampini Mat change_mat_all; 30480c7d97c5SJed Brown IS is_R_local; 30490c7d97c5SJed Brown IS is_V_local; 30500c7d97c5SJed Brown IS is_C_local; 30510c7d97c5SJed Brown IS is_aux1; 30520c7d97c5SJed Brown IS is_aux2; 305319fd82e9SBarry Smith VecType impVecType; 305419fd82e9SBarry Smith MatType impMatType; 30550c7d97c5SJed Brown PetscInt n_R=0; 30560c7d97c5SJed Brown PetscInt n_D=0; 30570c7d97c5SJed Brown PetscInt n_B=0; 30580c7d97c5SJed Brown PetscScalar zero=0.0; 30590c7d97c5SJed Brown PetscScalar one=1.0; 30600c7d97c5SJed Brown PetscScalar m_one=-1.0; 30610c7d97c5SJed Brown PetscScalar* array; 30620c7d97c5SJed Brown PetscScalar *coarse_submat_vals; 30630c7d97c5SJed Brown PetscInt *idx_R_local; 30640c7d97c5SJed Brown PetscInt *idx_V_B; 30650c7d97c5SJed Brown PetscScalar *coarsefunctions_errors; 30660c7d97c5SJed Brown PetscScalar *constraints_errors; 30670c7d97c5SJed Brown /* auxiliary indices */ 3068534831adSStefano Zampini PetscInt i,j,k; 3069e269702eSStefano Zampini /* for verbose output of bddc */ 3070e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 3071e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 3072a0ba757dSStefano Zampini /* for counting coarse dofs */ 3073534831adSStefano Zampini PetscInt n_vertices,n_constraints; 30743b03a366Sstefano_zampini PetscInt size_of_constraint; 30753b03a366Sstefano_zampini PetscInt *row_cmat_indices; 30763b03a366Sstefano_zampini PetscScalar *row_cmat_values; 3077534831adSStefano Zampini PetscInt *vertices,*nnz,*is_indices,*temp_indices; 30780c7d97c5SJed Brown 30790c7d97c5SJed Brown PetscFunctionBegin; 30800c7d97c5SJed Brown /* Set Non-overlapping dimensions */ 30810c7d97c5SJed Brown n_B = pcis->n_B; n_D = pcis->n - n_B; 3082534831adSStefano Zampini /* Set types for local objects needed by BDDC precondtioner */ 3083534831adSStefano Zampini impMatType = MATSEQDENSE; 3084534831adSStefano Zampini impVecType = VECSEQ; 3085da1bb401SStefano Zampini /* get vertex indices from constraint matrix */ 3086534831adSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscInt),&vertices);CHKERRQ(ierr); 3087534831adSStefano Zampini n_vertices=0; 3088da1bb401SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 3089da1bb401SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 3090da1bb401SStefano Zampini if (size_of_constraint == 1) { 3091534831adSStefano Zampini vertices[n_vertices]=row_cmat_indices[0]; 3092534831adSStefano Zampini n_vertices++; 3093a0ba757dSStefano Zampini } 3094da1bb401SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 3095a0ba757dSStefano Zampini } 3096534831adSStefano Zampini /* Set number of constraints */ 3097534831adSStefano Zampini n_constraints = pcbddc->local_primal_size-n_vertices; 3098534831adSStefano Zampini 3099534831adSStefano Zampini /* vertices in boundary numbering */ 3100534831adSStefano Zampini if (n_vertices) { 3101534831adSStefano Zampini ierr = VecSet(pcis->vec1_N,m_one);CHKERRQ(ierr); 3102534831adSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 3103534831adSStefano Zampini for (i=0; i<n_vertices; i++) { array[ vertices[i] ] = i; } 3104534831adSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 3105534831adSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3106534831adSStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3107534831adSStefano Zampini ierr = PetscMalloc(n_vertices*sizeof(PetscInt),&idx_V_B);CHKERRQ(ierr); 3108534831adSStefano Zampini ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 3109534831adSStefano Zampini for (i=0; i<n_vertices; i++) { 3110534831adSStefano Zampini j=0; 3111534831adSStefano Zampini while (array[j] != i) {j++;} 3112534831adSStefano Zampini idx_V_B[i]=j; 3113534831adSStefano Zampini } 3114534831adSStefano Zampini ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 3115534831adSStefano Zampini } 3116534831adSStefano Zampini 3117534831adSStefano Zampini /* transform local matrices if needed */ 3118534831adSStefano Zampini if (pcbddc->usechangeofbasis) { 3119534831adSStefano Zampini ierr = PetscMalloc(pcis->n*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 3120534831adSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3121534831adSStefano Zampini for (i=0;i<n_D;i++) { 3122534831adSStefano Zampini nnz[is_indices[i]]=1; 3123534831adSStefano Zampini } 3124534831adSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3125534831adSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3126534831adSStefano Zampini k=1; 3127534831adSStefano Zampini for (i=0;i<n_B;i++) { 3128534831adSStefano Zampini ierr = MatGetRow(pcbddc->ChangeOfBasisMatrix,i,&j,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 3129534831adSStefano Zampini nnz[is_indices[i]]=j; 3130534831adSStefano Zampini if (k < j) { 3131534831adSStefano Zampini k = j; 3132534831adSStefano Zampini } 3133534831adSStefano Zampini ierr = MatRestoreRow(pcbddc->ChangeOfBasisMatrix,i,&j,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 3134534831adSStefano Zampini } 3135534831adSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3136534831adSStefano Zampini /* assemble change of basis matrix on the whole set of local dofs */ 3137534831adSStefano Zampini ierr = PetscMalloc(k*sizeof(PetscInt),&temp_indices);CHKERRQ(ierr); 3138534831adSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&change_mat_all);CHKERRQ(ierr); 3139534831adSStefano Zampini ierr = MatSetSizes(change_mat_all,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 3140534831adSStefano Zampini ierr = MatSetType(change_mat_all,MATSEQAIJ);CHKERRQ(ierr); 3141534831adSStefano Zampini ierr = MatSeqAIJSetPreallocation(change_mat_all,0,nnz);CHKERRQ(ierr); 3142534831adSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3143534831adSStefano Zampini for (i=0;i<n_D;i++) { 3144534831adSStefano Zampini ierr = MatSetValue(change_mat_all,is_indices[i],is_indices[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 3145534831adSStefano Zampini } 3146534831adSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3147534831adSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3148534831adSStefano Zampini for (i=0;i<n_B;i++) { 3149534831adSStefano Zampini ierr = MatGetRow(pcbddc->ChangeOfBasisMatrix,i,&j,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 3150534831adSStefano Zampini for (k=0;k<j;k++) { 3151534831adSStefano Zampini temp_indices[k]=is_indices[row_cmat_indices[k]]; 3152534831adSStefano Zampini } 3153534831adSStefano Zampini ierr = MatSetValues(change_mat_all,1,&is_indices[i],j,temp_indices,row_cmat_values,INSERT_VALUES);CHKERRQ(ierr); 3154534831adSStefano Zampini ierr = MatRestoreRow(pcbddc->ChangeOfBasisMatrix,i,&j,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 3155534831adSStefano Zampini } 3156534831adSStefano Zampini ierr = MatAssemblyBegin(change_mat_all,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3157534831adSStefano Zampini ierr = MatAssemblyEnd(change_mat_all,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3158534831adSStefano Zampini ierr = MatPtAP(matis->A,change_mat_all,MAT_INITIAL_MATRIX,1.0,&pcbddc->local_mat);CHKERRQ(ierr); 3159534831adSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 3160534831adSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 3161534831adSStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 3162534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 3163534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 3164534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 3165534831adSStefano Zampini ierr = MatDestroy(&change_mat_all);CHKERRQ(ierr); 3166534831adSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3167534831adSStefano Zampini ierr = PetscFree(temp_indices);CHKERRQ(ierr); 3168534831adSStefano Zampini } else { 3169534831adSStefano Zampini /* without change of basis, the local matrix is unchanged */ 3170534831adSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 3171534831adSStefano Zampini pcbddc->local_mat = matis->A; 3172534831adSStefano Zampini } 31730bdf917eSStefano Zampini /* Change global null space passed in by the user if change of basis has been performed */ 31740bdf917eSStefano Zampini if (pcbddc->NullSpace && pcbddc->usechangeofbasis) { 31750bdf917eSStefano Zampini ierr = PCBDDCAdaptNullSpace(pc);CHKERRQ(ierr); 31760bdf917eSStefano Zampini } 3177a0ba757dSStefano Zampini 31780c7d97c5SJed Brown /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 31790c7d97c5SJed Brown ierr = VecSet(pcis->vec1_N,one);CHKERRQ(ierr); 31800c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 31813b03a366Sstefano_zampini for (i=0;i<n_vertices;i++) { array[ vertices[i] ] = zero; } 31823b03a366Sstefano_zampini ierr = PetscMalloc((pcis->n - n_vertices)*sizeof(PetscInt),&idx_R_local);CHKERRQ(ierr); 31830c7d97c5SJed Brown for (i=0, n_R=0; i<pcis->n; i++) { if (array[i] == one) { idx_R_local[n_R] = i; n_R++; } } 31840c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 3185e269702eSStefano Zampini if (dbg_flag) { 31860c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 31870c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 31880c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 31890c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 31903b03a366Sstefano_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); 3191534831adSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"pcbddc->n_vertices = %d, pcbddc->n_constraints = %d\n",pcbddc->n_vertices,pcbddc->n_constraints);CHKERRQ(ierr); 31920c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 31930c7d97c5SJed Brown } 3194534831adSStefano Zampini 31950c7d97c5SJed Brown /* Allocate needed vectors */ 3196534831adSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 31973972b0daSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 31980c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_D,&pcbddc->vec4_D);CHKERRQ(ierr); 31990c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_R);CHKERRQ(ierr); 32000c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_R,n_R,n_R);CHKERRQ(ierr); 32010c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 3202d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 32030c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_P);CHKERRQ(ierr); 32040c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_P,pcbddc->local_primal_size,pcbddc->local_primal_size);CHKERRQ(ierr); 32050c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 32060c7d97c5SJed Brown 32070c7d97c5SJed Brown /* Creating some index sets needed */ 32080c7d97c5SJed Brown /* For submatrices */ 3209da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n_R,idx_R_local,PETSC_OWN_POINTER,&is_R_local);CHKERRQ(ierr); 32103b03a366Sstefano_zampini if (n_vertices) { 3211da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n_vertices,vertices,PETSC_OWN_POINTER,&is_V_local);CHKERRQ(ierr); 32123b03a366Sstefano_zampini } 3213da1bb401SStefano Zampini if (n_constraints) { 3214da1bb401SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_C_local);CHKERRQ(ierr); 3215da1bb401SStefano Zampini } 3216da1bb401SStefano Zampini 32170c7d97c5SJed Brown /* For VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 32180c7d97c5SJed Brown { 32190c7d97c5SJed Brown PetscInt *aux_array1; 32200c7d97c5SJed Brown PetscInt *aux_array2; 32212e8d2280SStefano Zampini PetscInt *idx_I_local; 32220c7d97c5SJed Brown 32233b03a366Sstefano_zampini ierr = PetscMalloc((pcis->n_B-n_vertices)*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 32243b03a366Sstefano_zampini ierr = PetscMalloc((pcis->n_B-n_vertices)*sizeof(PetscInt),&aux_array2);CHKERRQ(ierr); 32250c7d97c5SJed Brown 32262e8d2280SStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&idx_I_local);CHKERRQ(ierr); 32270c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 32282e8d2280SStefano Zampini for (i=0; i<n_D; i++) { array[idx_I_local[i]] = 0; } 32292e8d2280SStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&idx_I_local);CHKERRQ(ierr); 32302e8d2280SStefano Zampini for (i=0, j=0; i<n_R; i++) { if (array[idx_R_local[i]] == one) { aux_array1[j] = i; j++; } } 32310c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 3232da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 32332e8d2280SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 32342e8d2280SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 32350c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 32362e8d2280SStefano Zampini for (i=0, j=0; i<n_B; i++) { if (array[i] == one) { aux_array2[j] = i; j++; } } 32373828260eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 3238da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_COPY_VALUES,&is_aux2);CHKERRQ(ierr); 32390c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 32400c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 32410c7d97c5SJed Brown ierr = PetscFree(aux_array2);CHKERRQ(ierr); 32420c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 32430c7d97c5SJed Brown ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 32440c7d97c5SJed Brown 324529622bf0SStefano Zampini if (pcbddc->inexact_prec_type || dbg_flag) { 32460c7d97c5SJed Brown ierr = PetscMalloc(n_D*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 32470c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 32482e8d2280SStefano Zampini for (i=0, j=0; i<n_R; i++) { if (array[idx_R_local[i]] == zero) { aux_array1[j] = i; j++; } } 32490c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 3250da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 32510c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 32520c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 32530c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 32540c7d97c5SJed Brown } 32550c7d97c5SJed Brown } 32560c7d97c5SJed Brown 32570c7d97c5SJed Brown /* Creating PC contexts for local Dirichlet and Neumann problems */ 32580c7d97c5SJed Brown { 32590c7d97c5SJed Brown Mat A_RR; 326053cdbc3dSStefano Zampini PC pc_temp; 32610c7d97c5SJed Brown /* Matrix for Dirichlet problem is A_II -> we already have it from pcis.c code */ 326253cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 326353cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 326453cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II,SAME_PRECONDITIONER);CHKERRQ(ierr); 326553cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 3266da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,"dirichlet_");CHKERRQ(ierr); 32670c7d97c5SJed Brown /* default */ 326853cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 326953cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 32700c7d97c5SJed Brown /* Allow user's customization */ 327153cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 3272950d796eSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero */ 3273950d796eSStefano Zampini if (!n_D) { 32742e8d2280SStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 3275950d796eSStefano Zampini } 327653cdbc3dSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 327753cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 32783972b0daSStefano Zampini /* set ksp_D into pcis data */ 32793972b0daSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 32803972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 32813972b0daSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 32820c7d97c5SJed Brown /* Matrix for Neumann problem is A_RR -> we need to create it */ 3283534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_R_local,is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 328453cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 328553cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 328653cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR,SAME_PRECONDITIONER);CHKERRQ(ierr); 328753cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 3288da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,"neumann_");CHKERRQ(ierr); 32890c7d97c5SJed Brown /* default */ 329053cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 329153cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 32920c7d97c5SJed Brown /* Allow user's customization */ 329353cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 3294950d796eSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero */ 3295950d796eSStefano Zampini if (!pcis->n) { 32962e8d2280SStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 3297950d796eSStefano Zampini } 329853cdbc3dSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 329953cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 330029622bf0SStefano Zampini /* check Dirichlet and Neumann solvers and adapt them is a nullspace correction is needed */ 3301b76ba322SStefano Zampini { 33020c7d97c5SJed Brown Vec temp_vec; 3303b76ba322SStefano Zampini PetscReal value; 3304b76ba322SStefano Zampini PetscMPIInt use_exact,use_exact_reduced; 33050c7d97c5SJed Brown 3306a0ba757dSStefano Zampini ierr = VecDuplicate(pcis->vec1_D,&temp_vec);CHKERRQ(ierr); 3307a0ba757dSStefano Zampini ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL);CHKERRQ(ierr); 3308a0ba757dSStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 3309a0ba757dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,temp_vec);CHKERRQ(ierr); 3310a0ba757dSStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcis->vec1_D);CHKERRQ(ierr); 3311a0ba757dSStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 331229622bf0SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 3313b76ba322SStefano Zampini use_exact = 1; 3314b76ba322SStefano Zampini if (PetscAbsReal(value) > 1.e-4) { 3315b76ba322SStefano Zampini use_exact = 0; 3316b76ba322SStefano Zampini } 3317b76ba322SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_INT,MPI_LAND,((PetscObject)pc)->comm);CHKERRQ(ierr); 3318b76ba322SStefano Zampini pcbddc->use_exact_dirichlet = (PetscBool) use_exact_reduced; 3319b76ba322SStefano Zampini if (dbg_flag) { 3320a0ba757dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 3321a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3322a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Checking solution of Dirichlet and Neumann problems\n");CHKERRQ(ierr); 3323a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Dirichlet solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 332429622bf0SStefano Zampini } 332529622bf0SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced && !pcbddc->inexact_prec_type) { 332629622bf0SStefano Zampini ierr = PCBDDCAdaptLocalProblem(pc,pcis->is_I_local); 332729622bf0SStefano Zampini } 3328d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&temp_vec);CHKERRQ(ierr); 3329d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 3330d49ef151SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 3331d49ef151SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,temp_vec);CHKERRQ(ierr); 3332d49ef151SStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 3333d49ef151SStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 3334e269702eSStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 333529622bf0SStefano Zampini use_exact = 1; 333629622bf0SStefano Zampini if (PetscAbsReal(value) > 1.e-4) { 333729622bf0SStefano Zampini use_exact = 0; 333829622bf0SStefano Zampini } 333929622bf0SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_INT,MPI_LAND,((PetscObject)pc)->comm);CHKERRQ(ierr); 334029622bf0SStefano Zampini if (dbg_flag) { 33410c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Neumann solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 3342d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 33430c7d97c5SJed Brown } 334429622bf0SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced) { 334529622bf0SStefano Zampini ierr = PCBDDCAdaptLocalProblem(pc,is_R_local); 334629622bf0SStefano Zampini } 3347b76ba322SStefano Zampini } 33480c7d97c5SJed Brown /* free Neumann problem's matrix */ 33490c7d97c5SJed Brown ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 33500c7d97c5SJed Brown } 33510c7d97c5SJed Brown 33520c7d97c5SJed Brown /* Assemble all remaining stuff needed to apply BDDC */ 33530c7d97c5SJed Brown { 33540c7d97c5SJed Brown Mat A_RV,A_VR,A_VV; 33550bdf917eSStefano Zampini Mat M1; 33560c7d97c5SJed Brown Mat C_CR; 33573b03a366Sstefano_zampini Mat AUXMAT; 33580c7d97c5SJed Brown Vec vec1_C; 33590c7d97c5SJed Brown Vec vec2_C; 33600c7d97c5SJed Brown Vec vec1_V; 33610c7d97c5SJed Brown Vec vec2_V; 33620c7d97c5SJed Brown PetscInt *nnz; 33630c7d97c5SJed Brown PetscInt *auxindices; 336453cdbc3dSStefano Zampini PetscInt index; 33650c7d97c5SJed Brown PetscScalar* array2; 33660c7d97c5SJed Brown MatFactorInfo matinfo; 33670c7d97c5SJed Brown 33680c7d97c5SJed Brown /* Allocating some extra storage just to be safe */ 33690c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 33700c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&auxindices);CHKERRQ(ierr); 33710c7d97c5SJed Brown for (i=0;i<pcis->n;i++) {auxindices[i]=i;} 33720c7d97c5SJed Brown 33730c7d97c5SJed Brown /* some work vectors on vertices and/or constraints */ 33743b03a366Sstefano_zampini if (n_vertices) { 33750c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_V);CHKERRQ(ierr); 33763b03a366Sstefano_zampini ierr = VecSetSizes(vec1_V,n_vertices,n_vertices);CHKERRQ(ierr); 33770c7d97c5SJed Brown ierr = VecSetType(vec1_V,impVecType);CHKERRQ(ierr); 33780c7d97c5SJed Brown ierr = VecDuplicate(vec1_V,&vec2_V);CHKERRQ(ierr); 33790c7d97c5SJed Brown } 3380534831adSStefano Zampini if (n_constraints) { 33810c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_C);CHKERRQ(ierr); 3382534831adSStefano Zampini ierr = VecSetSizes(vec1_C,n_constraints,n_constraints);CHKERRQ(ierr); 33830c7d97c5SJed Brown ierr = VecSetType(vec1_C,impVecType);CHKERRQ(ierr); 33840c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&vec2_C);CHKERRQ(ierr); 33850c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&pcbddc->vec1_C);CHKERRQ(ierr); 33860c7d97c5SJed Brown } 33870c7d97c5SJed Brown /* Precompute stuffs needed for preprocessing and application of BDDC*/ 33883b03a366Sstefano_zampini if (n_constraints) { 33890c7d97c5SJed Brown ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->local_auxmat2);CHKERRQ(ierr); 33903b03a366Sstefano_zampini ierr = MatSetSizes(pcbddc->local_auxmat2,n_R,n_constraints,n_R,n_constraints);CHKERRQ(ierr); 33910c7d97c5SJed Brown ierr = MatSetType(pcbddc->local_auxmat2,impMatType);CHKERRQ(ierr); 33923b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(pcbddc->local_auxmat2,PETSC_NULL);CHKERRQ(ierr); 33930c7d97c5SJed Brown 339457a90decSStefano Zampini /* Create Constraint matrix on R nodes: C_{CR} */ 339557a90decSStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_C_local,is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 339657a90decSStefano Zampini ierr = ISDestroy(&is_C_local);CHKERRQ(ierr); 339757a90decSStefano Zampini 33980c7d97c5SJed Brown /* Assemble local_auxmat2 = - A_{RR}^{-1} C^T_{CR} needed by BDDC application */ 33993b03a366Sstefano_zampini for (i=0;i<n_constraints;i++) { 34003b03a366Sstefano_zampini ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 34013b03a366Sstefano_zampini /* Get row of constraint matrix in R numbering */ 340257a90decSStefano Zampini ierr = VecGetArray(pcbddc->vec1_R,&array);CHKERRQ(ierr); 340357a90decSStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 34043b03a366Sstefano_zampini for (j=0;j<size_of_constraint;j++) { array[ row_cmat_indices[j] ] = - row_cmat_values[j]; } 340557a90decSStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 340657a90decSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_R,&array);CHKERRQ(ierr); 34073b03a366Sstefano_zampini /* Solve for row of constraint matrix in R numbering */ 340853cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 34093b03a366Sstefano_zampini /* Set values */ 34100c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 34113b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->local_auxmat2,n_R,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 34120c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 34130c7d97c5SJed Brown } 34140c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 34150c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 34160c7d97c5SJed Brown 34170c7d97c5SJed Brown /* Assemble AUXMAT = (LUFactor)(-C_{CR} A_{RR}^{-1} C^T_{CR})^{-1} */ 34180c7d97c5SJed Brown ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AUXMAT);CHKERRQ(ierr); 3419d49ef151SStefano Zampini ierr = MatFactorInfoInitialize(&matinfo);CHKERRQ(ierr); 34203b03a366Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,0,1,&is_aux1);CHKERRQ(ierr); 34210c7d97c5SJed Brown ierr = MatLUFactor(AUXMAT,is_aux1,is_aux1,&matinfo);CHKERRQ(ierr); 34220c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 34230c7d97c5SJed Brown 34243b03a366Sstefano_zampini /* Assemble explicitly M1 = (C_{CR} A_{RR}^{-1} C^T_{CR})^{-1} needed in preproc */ 3425d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M1);CHKERRQ(ierr); 34263b03a366Sstefano_zampini ierr = MatSetSizes(M1,n_constraints,n_constraints,n_constraints,n_constraints);CHKERRQ(ierr); 34270c7d97c5SJed Brown ierr = MatSetType(M1,impMatType);CHKERRQ(ierr); 34283b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(M1,PETSC_NULL);CHKERRQ(ierr); 34293b03a366Sstefano_zampini for (i=0;i<n_constraints;i++) { 34300c7d97c5SJed Brown ierr = VecSet(vec1_C,zero);CHKERRQ(ierr); 34310c7d97c5SJed Brown ierr = VecSetValue(vec1_C,i,one,INSERT_VALUES);CHKERRQ(ierr); 34320c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_C);CHKERRQ(ierr); 34330c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_C);CHKERRQ(ierr); 34340c7d97c5SJed Brown ierr = MatSolve(AUXMAT,vec1_C,vec2_C);CHKERRQ(ierr); 34350c7d97c5SJed Brown ierr = VecScale(vec2_C,m_one);CHKERRQ(ierr); 34360c7d97c5SJed Brown ierr = VecGetArray(vec2_C,&array);CHKERRQ(ierr); 34373b03a366Sstefano_zampini ierr = MatSetValues(M1,n_constraints,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 34380c7d97c5SJed Brown ierr = VecRestoreArray(vec2_C,&array);CHKERRQ(ierr); 34390c7d97c5SJed Brown } 34400c7d97c5SJed Brown ierr = MatAssemblyBegin(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 34410c7d97c5SJed Brown ierr = MatAssemblyEnd(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 34420c7d97c5SJed Brown ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 34430c7d97c5SJed Brown /* Assemble local_auxmat1 = M1*C_{CR} needed by BDDC application in KSP and in preproc */ 34440c7d97c5SJed Brown ierr = MatMatMult(M1,C_CR,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 34450c7d97c5SJed Brown 34460c7d97c5SJed Brown } 34470c7d97c5SJed Brown 34480c7d97c5SJed Brown /* Get submatrices from subdomain matrix */ 34493b03a366Sstefano_zampini if (n_vertices) { 3450534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_R_local,is_V_local,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 3451534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_V_local,is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 3452534831adSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_V_local,is_V_local,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 34530c7d97c5SJed Brown } 34540c7d97c5SJed Brown 34550c7d97c5SJed Brown /* Matrix of coarse basis functions (local) */ 3456d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 34570c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 34580c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_B,impMatType);CHKERRQ(ierr); 34593b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_phi_B,PETSC_NULL);CHKERRQ(ierr); 346029622bf0SStefano Zampini if (pcbddc->inexact_prec_type || dbg_flag) { 3461d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 34620c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 34630c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_D,impMatType);CHKERRQ(ierr); 34643b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_phi_D,PETSC_NULL);CHKERRQ(ierr); 34650c7d97c5SJed Brown } 34660c7d97c5SJed Brown 3467e269702eSStefano Zampini if (dbg_flag) { 34680c7d97c5SJed Brown ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscScalar),&coarsefunctions_errors);CHKERRQ(ierr); 34690c7d97c5SJed Brown ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscScalar),&constraints_errors);CHKERRQ(ierr); 34700c7d97c5SJed Brown } 34713b03a366Sstefano_zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 34720c7d97c5SJed Brown ierr = PetscMalloc ((pcbddc->local_primal_size)*(pcbddc->local_primal_size)*sizeof(PetscScalar),&coarse_submat_vals);CHKERRQ(ierr); 34730c7d97c5SJed Brown 34740c7d97c5SJed Brown /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 34753b03a366Sstefano_zampini for (i=0;i<n_vertices;i++) { 34760c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 34770c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 34780c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 34790c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 34800c7d97c5SJed Brown /* solution of saddle point problem */ 34810bdf917eSStefano Zampini ierr = MatMult(A_RV,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 34820bdf917eSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 34830c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_R,m_one);CHKERRQ(ierr); 34843b03a366Sstefano_zampini if (n_constraints) { 34850c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec1_R,vec1_C);CHKERRQ(ierr); 34860c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 34870c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 34880c7d97c5SJed Brown } 34890c7d97c5SJed Brown ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); 34900c7d97c5SJed Brown ierr = MatMultAdd(A_VV,vec1_V,vec2_V,vec2_V);CHKERRQ(ierr); 34910c7d97c5SJed Brown 34920c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 34930c7d97c5SJed Brown /* coarse basis functions */ 34940c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 34950c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 34960c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 34970c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 34983b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 34990c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 35000c7d97c5SJed Brown ierr = MatSetValue(pcbddc->coarse_phi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 350129622bf0SStefano Zampini if (pcbddc->inexact_prec_type || dbg_flag) { 35020c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 35030c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 35040c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 35053b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 35060c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 35070c7d97c5SJed Brown } 35080c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 35090c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 3510da1bb401SStefano Zampini for (j=0;j<n_vertices;j++) { coarse_submat_vals[i*pcbddc->local_primal_size+j] = array[j]; } /* WARNING -> column major ordering */ 35110c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 35123b03a366Sstefano_zampini if (n_constraints) { 35130c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 3514da1bb401SStefano Zampini for (j=0;j<n_constraints;j++) { coarse_submat_vals[i*pcbddc->local_primal_size+j+n_vertices] = array[j]; } /* WARNING -> column major ordering */ 35150c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 35160c7d97c5SJed Brown } 35170c7d97c5SJed Brown 3518e269702eSStefano Zampini if (dbg_flag) { 35190c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 3520d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 35210c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 35220c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 35230c7d97c5SJed Brown for (j=0;j<n_R;j++) { array[idx_R_local[j]] = array2[j]; } 35243b03a366Sstefano_zampini array[ vertices[i] ] = one; 35250c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 35260c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 35270c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers (i.e. primal nodes) */ 3528d49ef151SStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 35290c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 35300c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 35313b03a366Sstefano_zampini for (j=0;j<n_vertices;j++) { array2[j]=array[j]; } 35320c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 35333b03a366Sstefano_zampini if (n_constraints) { 35340c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 35353b03a366Sstefano_zampini for (j=0;j<n_constraints;j++) { array2[j+n_vertices]=array[j]; } 35360c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 35370c7d97c5SJed Brown } 35380c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 35390c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_P,m_one);CHKERRQ(ierr); 35400c7d97c5SJed Brown /* check saddle point solution */ 3541534831adSStefano Zampini ierr = MatMult(pcbddc->local_mat,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 35423b03a366Sstefano_zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 35433b03a366Sstefano_zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[i]);CHKERRQ(ierr); 35443b03a366Sstefano_zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 35450c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 35463b03a366Sstefano_zampini array[i]=array[i]+m_one; /* shift by the identity matrix */ 35470c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 35483b03a366Sstefano_zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[i]);CHKERRQ(ierr); 35490c7d97c5SJed Brown } 35500c7d97c5SJed Brown } 35510c7d97c5SJed Brown 35523b03a366Sstefano_zampini for (i=0;i<n_constraints;i++) { 3553d49ef151SStefano Zampini ierr = VecSet(vec2_C,zero);CHKERRQ(ierr); 35540c7d97c5SJed Brown ierr = VecSetValue(vec2_C,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 35550c7d97c5SJed Brown ierr = VecAssemblyBegin(vec2_C);CHKERRQ(ierr); 35560c7d97c5SJed Brown ierr = VecAssemblyEnd(vec2_C);CHKERRQ(ierr); 35570c7d97c5SJed Brown /* solution of saddle point problem */ 35580c7d97c5SJed Brown ierr = MatMult(M1,vec2_C,vec1_C);CHKERRQ(ierr); 35590c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 35600c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 35613b03a366Sstefano_zampini if (n_vertices) { ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); } 35620c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 35630c7d97c5SJed Brown /* coarse basis functions */ 35643b03a366Sstefano_zampini index=i+n_vertices; 35650c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 35660c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 35670c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 35680c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 356953cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 35700c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 357129622bf0SStefano Zampini if (pcbddc->inexact_prec_type || dbg_flag) { 35720c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 35730c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 35740c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 357553cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 35760c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 35770c7d97c5SJed Brown } 35780c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 35793b03a366Sstefano_zampini if (n_vertices) { 35800c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 3581da1bb401SStefano Zampini for (j=0;j<n_vertices;j++) {coarse_submat_vals[index*pcbddc->local_primal_size+j]=array[j];} /* WARNING -> column major ordering */ 35820c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 35830c7d97c5SJed Brown } 35840c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 3585da1bb401SStefano Zampini for (j=0;j<n_constraints;j++) {coarse_submat_vals[index*pcbddc->local_primal_size+j+n_vertices]=array[j];} /* WARNING -> column major ordering */ 35860c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 35870c7d97c5SJed Brown 3588e269702eSStefano Zampini if (dbg_flag) { 35890c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 359053cdbc3dSStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 35910c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 35920c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 35930c7d97c5SJed Brown for (j=0;j<n_R;j++) { array[ idx_R_local[j] ] = array2[j]; } 35940c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 35950c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 35960c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers */ 359753cdbc3dSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 35980c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 35993b03a366Sstefano_zampini if (n_vertices) { 36000c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 36013b03a366Sstefano_zampini for (j=0;j<n_vertices;j++) {array2[j]=-array[j];} 36020c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 36030c7d97c5SJed Brown } 36040c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 36053b03a366Sstefano_zampini for (j=0;j<n_constraints;j++) {array2[j+n_vertices]=-array[j];} 36060c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 36070c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 36083972b0daSStefano Zampini /* check saddle point solution */ 3609534831adSStefano Zampini ierr = MatMult(pcbddc->local_mat,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 36103b03a366Sstefano_zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 361153cdbc3dSStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[index]);CHKERRQ(ierr); 36123b03a366Sstefano_zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 36130c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 361453cdbc3dSStefano Zampini array[index]=array[index]+m_one; /* shift by the identity matrix */ 36150c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 361653cdbc3dSStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[index]);CHKERRQ(ierr); 36170c7d97c5SJed Brown } 36180c7d97c5SJed Brown } 36190c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 36200c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 362129622bf0SStefano Zampini if (pcbddc->inexact_prec_type || dbg_flag) { 36220c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 36230c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 36240c7d97c5SJed Brown } 36250c7d97c5SJed Brown /* Checking coarse_sub_mat and coarse basis functios */ 36260c7d97c5SJed Brown /* It shuld be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 36279d2fce94SStefano Zampini if (dbg_flag) { 36280c7d97c5SJed Brown Mat coarse_sub_mat; 36290c7d97c5SJed Brown Mat TM1,TM2,TM3,TM4; 36300c7d97c5SJed Brown Mat coarse_phi_D,coarse_phi_B,A_II,A_BB,A_IB,A_BI; 363119fd82e9SBarry Smith MatType checkmattype=MATSEQAIJ; 36320c7d97c5SJed Brown PetscScalar value; 36330c7d97c5SJed Brown 3634c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 3635c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 3636c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 3637c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 3638c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 3639c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 3640c042a7c3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 3641c042a7c3SStefano Zampini ierr = MatConvert(coarse_sub_mat,checkmattype,MAT_REUSE_MATRIX,&coarse_sub_mat);CHKERRQ(ierr); 36420c7d97c5SJed Brown 36430c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 36440c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Check coarse sub mat and local basis functions\n");CHKERRQ(ierr); 36450c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 364653cdbc3dSStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 364753cdbc3dSStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 364853cdbc3dSStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 3649c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 365053cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 365153cdbc3dSStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 3652c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 365353cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 365453cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 365553cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 365653cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 365753cdbc3dSStefano Zampini ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 365853cdbc3dSStefano Zampini ierr = MatNorm(TM1,NORM_INFINITY,&value);CHKERRQ(ierr); 36590c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"----------------------------------\n");CHKERRQ(ierr); 36600c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d \n",PetscGlobalRank);CHKERRQ(ierr); 36610c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"matrix error = % 1.14e\n",value);CHKERRQ(ierr); 36620c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"coarse functions errors\n");CHKERRQ(ierr); 366353cdbc3dSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local %02d-th function error = % 1.14e\n",i,coarsefunctions_errors[i]);CHKERRQ(ierr); } 36640c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"constraints errors\n");CHKERRQ(ierr); 366553cdbc3dSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local %02d-th function error = % 1.14e\n",i,constraints_errors[i]);CHKERRQ(ierr); } 36660c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 366753cdbc3dSStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 366853cdbc3dSStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 366953cdbc3dSStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 367053cdbc3dSStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 367153cdbc3dSStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 367253cdbc3dSStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 367353cdbc3dSStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 367453cdbc3dSStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 367553cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 367653cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 367753cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 36780c7d97c5SJed Brown ierr = PetscFree(coarsefunctions_errors);CHKERRQ(ierr); 36790c7d97c5SJed Brown ierr = PetscFree(constraints_errors);CHKERRQ(ierr); 36800c7d97c5SJed Brown } 36810c7d97c5SJed Brown /* free memory */ 36823b03a366Sstefano_zampini if (n_vertices) { 36830c7d97c5SJed Brown ierr = VecDestroy(&vec1_V);CHKERRQ(ierr); 36840c7d97c5SJed Brown ierr = VecDestroy(&vec2_V);CHKERRQ(ierr); 36850c7d97c5SJed Brown ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 36860c7d97c5SJed Brown ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 36870c7d97c5SJed Brown ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 36880c7d97c5SJed Brown } 3689534831adSStefano Zampini if (n_constraints) { 36900c7d97c5SJed Brown ierr = VecDestroy(&vec1_C);CHKERRQ(ierr); 36910c7d97c5SJed Brown ierr = VecDestroy(&vec2_C);CHKERRQ(ierr); 36920c7d97c5SJed Brown ierr = MatDestroy(&M1);CHKERRQ(ierr); 36930c7d97c5SJed Brown ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 36940c7d97c5SJed Brown } 3695a929c220SStefano Zampini ierr = PetscFree(auxindices);CHKERRQ(ierr); 3696a929c220SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3697a929c220SStefano Zampini /* create coarse matrix and data structures for message passing associated actual choice of coarse problem type */ 3698a929c220SStefano Zampini ierr = PCBDDCSetupCoarseEnvironment(pc,coarse_submat_vals);CHKERRQ(ierr); 3699a929c220SStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 37000c7d97c5SJed Brown } 37010c7d97c5SJed Brown /* free memory */ 37023b03a366Sstefano_zampini if (n_vertices) { 37030c7d97c5SJed Brown ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 37040c7d97c5SJed Brown ierr = ISDestroy(&is_V_local);CHKERRQ(ierr); 37050c7d97c5SJed Brown } 37060c7d97c5SJed Brown ierr = ISDestroy(&is_R_local);CHKERRQ(ierr); 37070c7d97c5SJed Brown 37080c7d97c5SJed Brown PetscFunctionReturn(0); 37090c7d97c5SJed Brown } 37100c7d97c5SJed Brown 37110c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 37120c7d97c5SJed Brown 37130c7d97c5SJed Brown #undef __FUNCT__ 37140c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetupCoarseEnvironment" 371553cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetupCoarseEnvironment(PC pc,PetscScalar* coarse_submat_vals) 37160c7d97c5SJed Brown { 37170c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 37180c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 37190c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 37200c7d97c5SJed Brown MPI_Comm prec_comm = ((PetscObject)pc)->comm; 37210c7d97c5SJed Brown MPI_Comm coarse_comm; 37220c7d97c5SJed Brown 37230c7d97c5SJed Brown /* common to all choiches */ 37240c7d97c5SJed Brown PetscScalar *temp_coarse_mat_vals; 37250c7d97c5SJed Brown PetscScalar *ins_coarse_mat_vals; 37260c7d97c5SJed Brown PetscInt *ins_local_primal_indices; 37270c7d97c5SJed Brown PetscMPIInt *localsizes2,*localdispl2; 37280c7d97c5SJed Brown PetscMPIInt size_prec_comm; 37290c7d97c5SJed Brown PetscMPIInt rank_prec_comm; 37300c7d97c5SJed Brown PetscMPIInt active_rank=MPI_PROC_NULL; 37310c7d97c5SJed Brown PetscMPIInt master_proc=0; 37320c7d97c5SJed Brown PetscInt ins_local_primal_size; 37330c7d97c5SJed Brown /* specific to MULTILEVEL_BDDC */ 37340c7d97c5SJed Brown PetscMPIInt *ranks_recv; 37350c7d97c5SJed Brown PetscMPIInt count_recv=0; 37360c7d97c5SJed Brown PetscMPIInt rank_coarse_proc_send_to; 37370c7d97c5SJed Brown PetscMPIInt coarse_color = MPI_UNDEFINED; 37380c7d97c5SJed Brown ISLocalToGlobalMapping coarse_ISLG; 37390c7d97c5SJed Brown /* some other variables */ 37400c7d97c5SJed Brown PetscErrorCode ierr; 374119fd82e9SBarry Smith MatType coarse_mat_type; 374219fd82e9SBarry Smith PCType coarse_pc_type; 374319fd82e9SBarry Smith KSPType coarse_ksp_type; 374453cdbc3dSStefano Zampini PC pc_temp; 37454fad6a16SStefano Zampini PetscInt i,j,k; 37463b03a366Sstefano_zampini PetscInt max_it_coarse_ksp=1; /* don't increase this value */ 3747e269702eSStefano Zampini /* verbose output viewer */ 3748e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 3749e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 3750142dfd88SStefano Zampini 3751ea7e1babSStefano Zampini PetscInt offset,offset2; 3752a929c220SStefano Zampini PetscMPIInt im_active,active_procs; 3753523858cfSStefano Zampini PetscInt *dnz,*onz; 3754142dfd88SStefano Zampini 3755142dfd88SStefano Zampini PetscBool setsym,issym=PETSC_FALSE; 37560c7d97c5SJed Brown 37570c7d97c5SJed Brown PetscFunctionBegin; 37580c7d97c5SJed Brown ins_local_primal_indices = 0; 37590c7d97c5SJed Brown ins_coarse_mat_vals = 0; 37600c7d97c5SJed Brown localsizes2 = 0; 37610c7d97c5SJed Brown localdispl2 = 0; 37620c7d97c5SJed Brown temp_coarse_mat_vals = 0; 37630c7d97c5SJed Brown coarse_ISLG = 0; 37640c7d97c5SJed Brown 376553cdbc3dSStefano Zampini ierr = MPI_Comm_size(prec_comm,&size_prec_comm);CHKERRQ(ierr); 376653cdbc3dSStefano Zampini ierr = MPI_Comm_rank(prec_comm,&rank_prec_comm);CHKERRQ(ierr); 3767142dfd88SStefano Zampini ierr = MatIsSymmetricKnown(pc->pmat,&setsym,&issym);CHKERRQ(ierr); 3768142dfd88SStefano Zampini 3769beed3852SStefano Zampini /* Assign global numbering to coarse dofs */ 3770beed3852SStefano Zampini { 3771ef028eecSStefano Zampini PetscInt *auxlocal_primal; 3772da1bb401SStefano Zampini PetscInt *row_cmat_indices; 37732e8d2280SStefano Zampini PetscInt *aux_ordering; 37742e8d2280SStefano Zampini PetscInt *row_cmat_global_indices; 3775ef028eecSStefano Zampini PetscInt *dof_sizes,*dof_displs; 37763b03a366Sstefano_zampini PetscInt size_of_constraint; 37772e8d2280SStefano Zampini PetscBool *array_bool; 3778ef028eecSStefano Zampini PetscBool first_found; 3779ef028eecSStefano Zampini PetscInt first_index,old_index,s; 3780ef028eecSStefano Zampini PetscMPIInt mpi_local_primal_size; 3781ef028eecSStefano Zampini PetscScalar coarsesum,*array; 3782ef028eecSStefano Zampini 3783ef028eecSStefano Zampini mpi_local_primal_size = (PetscMPIInt)pcbddc->local_primal_size; 3784beed3852SStefano Zampini 3785beed3852SStefano Zampini /* Construct needed data structures for message passing */ 3786ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscInt),&pcbddc->local_primal_indices);CHKERRQ(ierr); 3787ffe5efe1SStefano Zampini j = 0; 3788142dfd88SStefano Zampini if (rank_prec_comm == 0 || pcbddc->coarse_problem_type == REPLICATED_BDDC || pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 3789ffe5efe1SStefano Zampini j = size_prec_comm; 3790ffe5efe1SStefano Zampini } 3791ffe5efe1SStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->local_primal_sizes);CHKERRQ(ierr); 3792ffe5efe1SStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 3793beed3852SStefano Zampini /* Gather local_primal_size information for all processes */ 3794142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == REPLICATED_BDDC || pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 37955619798eSStefano Zampini ierr = MPI_Allgather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,prec_comm);CHKERRQ(ierr); 3796ffe5efe1SStefano Zampini } else { 3797ffe5efe1SStefano Zampini ierr = MPI_Gather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 3798ffe5efe1SStefano Zampini } 3799beed3852SStefano Zampini pcbddc->replicated_primal_size = 0; 3800ffe5efe1SStefano Zampini for (i=0; i<j; i++) { 3801beed3852SStefano Zampini pcbddc->local_primal_displacements[i] = pcbddc->replicated_primal_size ; 3802beed3852SStefano Zampini pcbddc->replicated_primal_size += pcbddc->local_primal_sizes[i]; 3803beed3852SStefano Zampini } 3804beed3852SStefano Zampini 3805da1bb401SStefano Zampini /* First let's count coarse dofs. 3806beed3852SStefano Zampini This code fragment assumes that the number of local constraints per connected component 3807beed3852SStefano Zampini is not greater than the number of nodes defined for the connected component 3808beed3852SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 3809ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscInt),&auxlocal_primal);CHKERRQ(ierr); 38102e8d2280SStefano Zampini j = 0; 38112e8d2280SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 38122e8d2280SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 38132e8d2280SStefano Zampini if (j < size_of_constraint) { 38142e8d2280SStefano Zampini j = size_of_constraint; 38152e8d2280SStefano Zampini } 38162e8d2280SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 38172e8d2280SStefano Zampini } 38182e8d2280SStefano Zampini ierr = PetscMalloc(j*sizeof(PetscInt),&aux_ordering);CHKERRQ(ierr); 38192e8d2280SStefano Zampini ierr = PetscMalloc(j*sizeof(PetscInt),&row_cmat_global_indices);CHKERRQ(ierr); 38202e8d2280SStefano Zampini ierr = PetscMalloc(pcis->n*sizeof(PetscBool),&array_bool);CHKERRQ(ierr); 38212e8d2280SStefano Zampini for (i=0;i<pcis->n;i++) { 38222e8d2280SStefano Zampini array_bool[i] = PETSC_FALSE; 38232e8d2280SStefano Zampini } 3824da1bb401SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 3825da1bb401SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 38263b03a366Sstefano_zampini for (j=0; j<size_of_constraint; j++) { 38272e8d2280SStefano Zampini aux_ordering[j] = j; 38282e8d2280SStefano Zampini } 38292e8d2280SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,size_of_constraint,row_cmat_indices,row_cmat_global_indices);CHKERRQ(ierr); 38302e8d2280SStefano Zampini ierr = PetscSortIntWithPermutation(size_of_constraint,row_cmat_global_indices,aux_ordering);CHKERRQ(ierr); 38312e8d2280SStefano Zampini for (j=0; j<size_of_constraint; j++) { 38322e8d2280SStefano Zampini k = row_cmat_indices[aux_ordering[j]]; 38332e8d2280SStefano Zampini if (!array_bool[k]) { 38342e8d2280SStefano Zampini array_bool[k] = PETSC_TRUE; 3835da1bb401SStefano Zampini auxlocal_primal[i] = k; 3836beed3852SStefano Zampini break; 3837beed3852SStefano Zampini } 3838beed3852SStefano Zampini } 3839da1bb401SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 3840beed3852SStefano Zampini } 38412e8d2280SStefano Zampini ierr = PetscFree(aux_ordering);CHKERRQ(ierr); 3842ef028eecSStefano Zampini ierr = PetscFree(array_bool);CHKERRQ(ierr); 3843ef028eecSStefano Zampini ierr = PetscFree(row_cmat_global_indices);CHKERRQ(ierr); 38442e8d2280SStefano Zampini 3845ef028eecSStefano Zampini /* Compute number of coarse dofs */ 3846ef028eecSStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 3847ef028eecSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 3848ef028eecSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 3849ef028eecSStefano Zampini array[auxlocal_primal[i]]=1.0; 3850ef028eecSStefano Zampini } 3851ef028eecSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 3852ef028eecSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 3853ef028eecSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3854ef028eecSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3855ef028eecSStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 3856ef028eecSStefano Zampini pcbddc->coarse_size = (PetscInt)coarsesum; 3857ef028eecSStefano Zampini 3858ef028eecSStefano Zampini /* Fill pcis->vec1_global with cumulative function for global numbering */ 3859ef028eecSStefano Zampini ierr = VecGetArray(pcis->vec1_global,&array);CHKERRQ(ierr); 3860ef028eecSStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&s);CHKERRQ(ierr); 3861ef028eecSStefano Zampini k = 0; 3862ef028eecSStefano Zampini first_index = -1; 3863ef028eecSStefano Zampini first_found = PETSC_FALSE; 3864ef028eecSStefano Zampini for (i=0;i<s;i++) { 3865ef028eecSStefano Zampini if (!first_found && array[i] > 0.0) { 3866ef028eecSStefano Zampini first_found = PETSC_TRUE; 3867ef028eecSStefano Zampini first_index = i; 3868ef028eecSStefano Zampini } 3869ef028eecSStefano Zampini k += (PetscInt)array[i]; 3870ef028eecSStefano Zampini } 3871ef028eecSStefano Zampini j = (!rank_prec_comm ? size_prec_comm : 0); 3872ef028eecSStefano Zampini ierr = PetscMalloc(j*sizeof(*dof_sizes),&dof_sizes);CHKERRQ(ierr); 3873ef028eecSStefano Zampini ierr = PetscMalloc(j*sizeof(*dof_displs),&dof_displs);CHKERRQ(ierr); 3874ef028eecSStefano Zampini ierr = MPI_Gather(&k,1,MPIU_INT,dof_sizes,1,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 3875ef028eecSStefano Zampini if (!rank_prec_comm) { 3876ef028eecSStefano Zampini dof_displs[0]=0; 3877ef028eecSStefano Zampini for (i=1;i<size_prec_comm;i++) { 3878ef028eecSStefano Zampini dof_displs[i] = dof_displs[i-1]+dof_sizes[i-1]; 3879ef028eecSStefano Zampini } 3880ef028eecSStefano Zampini } 3881ef028eecSStefano Zampini ierr = MPI_Scatter(dof_displs,1,MPIU_INT,&k,1,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 3882ef028eecSStefano Zampini if (first_found) { 3883ef028eecSStefano Zampini array[first_index] += k; 3884ef028eecSStefano Zampini old_index = first_index; 3885ef028eecSStefano Zampini for (i=first_index+1;i<s;i++) { 3886ef028eecSStefano Zampini if (array[i] > 0.0) { 3887ef028eecSStefano Zampini array[i] += array[old_index]; 3888ef028eecSStefano Zampini old_index = i; 3889ef028eecSStefano Zampini } 3890ef028eecSStefano Zampini } 3891ef028eecSStefano Zampini } 3892ef028eecSStefano Zampini ierr = VecRestoreArray(pcis->vec1_global,&array);CHKERRQ(ierr); 3893ef028eecSStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 3894ef028eecSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3895ef028eecSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3896ef028eecSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 3897ef028eecSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 3898ef028eecSStefano Zampini pcbddc->local_primal_indices[i] = (PetscInt)array[auxlocal_primal[i]]-1; 3899ef028eecSStefano Zampini } 3900ef028eecSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 3901ef028eecSStefano Zampini ierr = PetscFree(dof_displs);CHKERRQ(ierr); 3902ef028eecSStefano Zampini ierr = PetscFree(dof_sizes);CHKERRQ(ierr); 3903ef028eecSStefano Zampini 3904ef028eecSStefano Zampini if (dbg_flag) { 39052e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 39062e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 39072e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Check coarse indices\n");CHKERRQ(ierr); 39082e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 39092e8d2280SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 3910ef028eecSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 3911ef028eecSStefano Zampini array[auxlocal_primal[i]]=1.0; 39122e8d2280SStefano Zampini } 3913beed3852SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 39142e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 3915da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3916da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3917da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3918da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3919da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 39202e8d2280SStefano Zampini for (i=0;i<pcis->n;i++) { 39212e8d2280SStefano Zampini if (array[i] == 1.0) { 39222e8d2280SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,1,&i,&j);CHKERRQ(ierr); 39232e8d2280SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d: WRONG COARSE INDEX %d (local %d)\n",PetscGlobalRank,j,i);CHKERRQ(ierr); 39242e8d2280SStefano Zampini } 39252e8d2280SStefano Zampini } 39262e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 39272e8d2280SStefano Zampini for (i=0;i<pcis->n;i++) { 39282e8d2280SStefano Zampini if (array[i] > 0.0) { 39292e8d2280SStefano Zampini array[i] = 1.0/array[i]; 39302e8d2280SStefano Zampini } 39312e8d2280SStefano Zampini } 3932da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 39332e8d2280SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 3934da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3935da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3936da1bb401SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 39372e8d2280SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem SHOULD be %lf\n",coarsesum);CHKERRQ(ierr); 39382e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 39392e8d2280SStefano Zampini } 3940142dfd88SStefano Zampini ierr = PetscFree(auxlocal_primal);CHKERRQ(ierr); 39410bdf917eSStefano Zampini } 39420bdf917eSStefano Zampini 39432e8d2280SStefano Zampini if (dbg_flag) { 39447cf533a6SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem is %d\n",pcbddc->coarse_size);CHKERRQ(ierr); 39452e8d2280SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 39462e8d2280SStefano Zampini } 39472e8d2280SStefano Zampini 3948a929c220SStefano Zampini im_active = 0; 39490bdf917eSStefano Zampini if (pcis->n) { im_active = 1; } 3950a929c220SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,prec_comm);CHKERRQ(ierr); 39510bdf917eSStefano Zampini 39520bdf917eSStefano Zampini /* adapt coarse problem type */ 39534fad6a16SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 39544fad6a16SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 3955a929c220SStefano Zampini if ((active_procs/pcbddc->coarsening_ratio) < 2) { 39560bdf917eSStefano Zampini if (dbg_flag) { 3957a929c220SStefano 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); 39580bdf917eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 39590bdf917eSStefano Zampini } 39600bdf917eSStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 3961142dfd88SStefano Zampini } 39624fad6a16SStefano Zampini } else { 39634fad6a16SStefano Zampini if (dbg_flag) { 3964a929c220SStefano 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); 39654fad6a16SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 39664fad6a16SStefano Zampini } 39674fad6a16SStefano Zampini pcbddc->coarse_problem_type = PARALLEL_BDDC; 39684fad6a16SStefano Zampini } 39694fad6a16SStefano Zampini } 3970beed3852SStefano Zampini 39710c7d97c5SJed Brown switch (pcbddc->coarse_problem_type) { 39720c7d97c5SJed Brown 3973da1bb401SStefano Zampini case(MULTILEVEL_BDDC): /* we define a coarse mesh where subdomains are elements */ 39740c7d97c5SJed Brown { 39750c7d97c5SJed Brown /* we need additional variables */ 39760c7d97c5SJed Brown MetisInt n_subdomains,n_parts,objval,ncon,faces_nvtxs; 39770c7d97c5SJed Brown MetisInt *metis_coarse_subdivision; 39780c7d97c5SJed Brown MetisInt options[METIS_NOPTIONS]; 39790c7d97c5SJed Brown PetscMPIInt size_coarse_comm,rank_coarse_comm; 39800c7d97c5SJed Brown PetscMPIInt procs_jumps_coarse_comm; 39810c7d97c5SJed Brown PetscMPIInt *coarse_subdivision; 39820c7d97c5SJed Brown PetscMPIInt *total_count_recv; 39830c7d97c5SJed Brown PetscMPIInt *total_ranks_recv; 39840c7d97c5SJed Brown PetscMPIInt *displacements_recv; 39850c7d97c5SJed Brown PetscMPIInt *my_faces_connectivity; 39860c7d97c5SJed Brown PetscMPIInt *petsc_faces_adjncy; 39870c7d97c5SJed Brown MetisInt *faces_adjncy; 39880c7d97c5SJed Brown MetisInt *faces_xadj; 39890c7d97c5SJed Brown PetscMPIInt *number_of_faces; 39900c7d97c5SJed Brown PetscMPIInt *faces_displacements; 39910c7d97c5SJed Brown PetscInt *array_int; 39920c7d97c5SJed Brown PetscMPIInt my_faces=0; 39930c7d97c5SJed Brown PetscMPIInt total_faces=0; 39943828260eSStefano Zampini PetscInt ranks_stretching_ratio; 39950c7d97c5SJed Brown 39960c7d97c5SJed Brown /* define some quantities */ 39970c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 39980c7d97c5SJed Brown coarse_mat_type = MATIS; 39990c7d97c5SJed Brown coarse_pc_type = PCBDDC; 4000142dfd88SStefano Zampini coarse_ksp_type = KSPRICHARDSON; 40010c7d97c5SJed Brown 40020c7d97c5SJed Brown /* details of coarse decomposition */ 4003a929c220SStefano Zampini n_subdomains = active_procs; 40040c7d97c5SJed Brown n_parts = n_subdomains/pcbddc->coarsening_ratio; 4005a929c220SStefano Zampini ranks_stretching_ratio = size_prec_comm/active_procs; 40063828260eSStefano Zampini procs_jumps_coarse_comm = pcbddc->coarsening_ratio*ranks_stretching_ratio; 40073828260eSStefano Zampini 4008a929c220SStefano Zampini #if 0 4009a929c220SStefano Zampini PetscMPIInt *old_ranks; 4010a929c220SStefano Zampini PetscInt *new_ranks,*jj,*ii; 4011a929c220SStefano Zampini MatPartitioning mat_part; 4012a929c220SStefano Zampini IS coarse_new_decomposition,is_numbering; 4013a929c220SStefano Zampini PetscViewer viewer_test; 4014a929c220SStefano Zampini MPI_Comm test_coarse_comm; 4015a929c220SStefano Zampini PetscMPIInt test_coarse_color; 4016a929c220SStefano Zampini Mat mat_adj; 4017a929c220SStefano Zampini /* Create new communicator for coarse problem splitting the old one */ 4018a929c220SStefano Zampini /* procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 4019a929c220SStefano Zampini key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator */ 4020a929c220SStefano Zampini test_coarse_color = (im_active ? 0 : MPI_UNDEFINED); 4021a929c220SStefano Zampini test_coarse_comm = MPI_COMM_NULL; 4022a929c220SStefano Zampini ierr = MPI_Comm_split(prec_comm,test_coarse_color,rank_prec_comm,&test_coarse_comm);CHKERRQ(ierr); 4023a929c220SStefano Zampini if (im_active) { 4024a929c220SStefano Zampini ierr = PetscMalloc(n_subdomains*sizeof(PetscMPIInt),&old_ranks); 4025a929c220SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscInt),&new_ranks); 4026a929c220SStefano Zampini ierr = MPI_Comm_rank(test_coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 4027a929c220SStefano Zampini ierr = MPI_Comm_size(test_coarse_comm,&j);CHKERRQ(ierr); 4028a929c220SStefano Zampini ierr = MPI_Allgather(&rank_prec_comm,1,MPIU_INT,old_ranks,1,MPIU_INT,test_coarse_comm);CHKERRQ(ierr); 4029a929c220SStefano Zampini for (i=0;i<size_prec_comm;i++) { 4030a929c220SStefano Zampini new_ranks[i] = -1; 4031a929c220SStefano Zampini } 4032a929c220SStefano Zampini for (i=0;i<n_subdomains;i++) { 4033a929c220SStefano Zampini new_ranks[old_ranks[i]] = i; 4034a929c220SStefano Zampini } 4035a929c220SStefano Zampini ierr = PetscViewerASCIIOpen(test_coarse_comm,"test_mat_part.out",&viewer_test);CHKERRQ(ierr); 4036a929c220SStefano Zampini k = pcis->n_neigh-1; 4037a929c220SStefano Zampini ierr = PetscMalloc(2*sizeof(PetscInt),&ii); 4038a929c220SStefano Zampini ii[0]=0; 4039a929c220SStefano Zampini ii[1]=k; 4040a929c220SStefano Zampini ierr = PetscMalloc(k*sizeof(PetscInt),&jj); 4041a929c220SStefano Zampini for (i=0;i<k;i++) { 4042a929c220SStefano Zampini jj[i]=new_ranks[pcis->neigh[i+1]]; 4043a929c220SStefano Zampini } 4044a929c220SStefano Zampini ierr = PetscSortInt(k,jj);CHKERRQ(ierr); 4045a929c220SStefano Zampini ierr = MatCreateMPIAdj(test_coarse_comm,1,n_subdomains,ii,jj,PETSC_NULL,&mat_adj);CHKERRQ(ierr); 4046a929c220SStefano Zampini ierr = MatView(mat_adj,viewer_test);CHKERRQ(ierr); 4047a929c220SStefano Zampini ierr = MatPartitioningCreate(test_coarse_comm,&mat_part);CHKERRQ(ierr); 4048a929c220SStefano Zampini ierr = MatPartitioningSetAdjacency(mat_part,mat_adj);CHKERRQ(ierr); 4049a929c220SStefano Zampini ierr = MatPartitioningSetFromOptions(mat_part);CHKERRQ(ierr); 4050a929c220SStefano Zampini printf("Setting Nparts %d\n",n_parts); 4051a929c220SStefano Zampini ierr = MatPartitioningSetNParts(mat_part,n_parts);CHKERRQ(ierr); 4052a929c220SStefano Zampini ierr = MatPartitioningView(mat_part,viewer_test);CHKERRQ(ierr); 4053a929c220SStefano Zampini ierr = MatPartitioningApply(mat_part,&coarse_new_decomposition);CHKERRQ(ierr); 4054a929c220SStefano Zampini ierr = ISView(coarse_new_decomposition,viewer_test);CHKERRQ(ierr); 4055a929c220SStefano Zampini ierr = ISPartitioningToNumbering(coarse_new_decomposition,&is_numbering);CHKERRQ(ierr); 4056a929c220SStefano Zampini ierr = ISView(is_numbering,viewer_test);CHKERRQ(ierr); 4057a929c220SStefano Zampini ierr = PetscViewerDestroy(&viewer_test);CHKERRQ(ierr); 4058a929c220SStefano Zampini ierr = ISDestroy(&coarse_new_decomposition);CHKERRQ(ierr); 4059a929c220SStefano Zampini ierr = ISDestroy(&is_numbering);CHKERRQ(ierr); 4060a929c220SStefano Zampini ierr = MatPartitioningDestroy(&mat_part);CHKERRQ(ierr); 4061a929c220SStefano Zampini ierr = PetscFree(old_ranks);CHKERRQ(ierr); 4062a929c220SStefano Zampini ierr = PetscFree(new_ranks);CHKERRQ(ierr); 4063a929c220SStefano Zampini ierr = MPI_Comm_free(&test_coarse_comm);CHKERRQ(ierr); 4064a929c220SStefano Zampini } 4065a929c220SStefano Zampini #endif 4066a929c220SStefano Zampini 40674fad6a16SStefano Zampini /* build CSR graph of subdomains' connectivity */ 40680c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&array_int);CHKERRQ(ierr); 40693828260eSStefano Zampini ierr = PetscMemzero(array_int,pcis->n*sizeof(PetscInt));CHKERRQ(ierr); 40700c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++) {/* i=1 so I don't count myself -> faces nodes counts to 1 */ 40710c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++) { 40720c7d97c5SJed Brown array_int[ pcis->shared[i][j] ]+=1; 40730c7d97c5SJed Brown } 40740c7d97c5SJed Brown } 40750c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++) { 40760c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++) { 40777cf533a6SStefano Zampini if (array_int[ pcis->shared[i][j] ] > 0) { 40780c7d97c5SJed Brown my_faces++; 40790c7d97c5SJed Brown break; 40800c7d97c5SJed Brown } 40810c7d97c5SJed Brown } 40820c7d97c5SJed Brown } 40830c7d97c5SJed Brown 408453cdbc3dSStefano Zampini ierr = MPI_Reduce(&my_faces,&total_faces,1,MPIU_INT,MPI_SUM,master_proc,prec_comm);CHKERRQ(ierr); 40850c7d97c5SJed Brown ierr = PetscMalloc (my_faces*sizeof(PetscInt),&my_faces_connectivity);CHKERRQ(ierr); 40860c7d97c5SJed Brown my_faces=0; 40870c7d97c5SJed Brown for (i=1;i<pcis->n_neigh;i++) { 40880c7d97c5SJed Brown for (j=0;j<pcis->n_shared[i];j++) { 40897cf533a6SStefano Zampini if (array_int[ pcis->shared[i][j] ] > 0) { 40900c7d97c5SJed Brown my_faces_connectivity[my_faces]=pcis->neigh[i]; 40910c7d97c5SJed Brown my_faces++; 40920c7d97c5SJed Brown break; 40930c7d97c5SJed Brown } 40940c7d97c5SJed Brown } 40950c7d97c5SJed Brown } 40960c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 40970c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(PetscMPIInt),&petsc_faces_adjncy);CHKERRQ(ierr); 40980c7d97c5SJed Brown ierr = PetscMalloc (size_prec_comm*sizeof(PetscMPIInt),&number_of_faces);CHKERRQ(ierr); 40990c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(MetisInt),&faces_adjncy);CHKERRQ(ierr); 41000c7d97c5SJed Brown ierr = PetscMalloc ((n_subdomains+1)*sizeof(MetisInt),&faces_xadj);CHKERRQ(ierr); 41010c7d97c5SJed Brown ierr = PetscMalloc ((size_prec_comm+1)*sizeof(PetscMPIInt),&faces_displacements);CHKERRQ(ierr); 41020c7d97c5SJed Brown } 410353cdbc3dSStefano Zampini ierr = MPI_Gather(&my_faces,1,MPIU_INT,&number_of_faces[0],1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 41040c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 41050c7d97c5SJed Brown faces_xadj[0]=0; 41060c7d97c5SJed Brown faces_displacements[0]=0; 41070c7d97c5SJed Brown j=0; 41080c7d97c5SJed Brown for (i=1;i<size_prec_comm+1;i++) { 41090c7d97c5SJed Brown faces_displacements[i]=faces_displacements[i-1]+number_of_faces[i-1]; 41100c7d97c5SJed Brown if (number_of_faces[i-1]) { 41110c7d97c5SJed Brown j++; 41120c7d97c5SJed Brown faces_xadj[j]=faces_xadj[j-1]+number_of_faces[i-1]; 41130c7d97c5SJed Brown } 41140c7d97c5SJed Brown } 41150c7d97c5SJed Brown } 411653cdbc3dSStefano 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); 41170c7d97c5SJed Brown ierr = PetscFree(my_faces_connectivity);CHKERRQ(ierr); 41180c7d97c5SJed Brown ierr = PetscFree(array_int);CHKERRQ(ierr); 41190c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 41203828260eSStefano Zampini for (i=0;i<total_faces;i++) faces_adjncy[i]=(MetisInt)(petsc_faces_adjncy[i]/ranks_stretching_ratio); /* cast to MetisInt */ 41210c7d97c5SJed Brown ierr = PetscFree(faces_displacements);CHKERRQ(ierr); 41220c7d97c5SJed Brown ierr = PetscFree(number_of_faces);CHKERRQ(ierr); 41230c7d97c5SJed Brown ierr = PetscFree(petsc_faces_adjncy);CHKERRQ(ierr); 41240c7d97c5SJed Brown } 41250c7d97c5SJed Brown 41260c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 41273828260eSStefano Zampini PetscInt heuristic_for_metis=3; 41280c7d97c5SJed Brown ncon=1; 41290c7d97c5SJed Brown faces_nvtxs=n_subdomains; 41300c7d97c5SJed Brown /* partition graoh induced by face connectivity */ 41310c7d97c5SJed Brown ierr = PetscMalloc (n_subdomains*sizeof(MetisInt),&metis_coarse_subdivision);CHKERRQ(ierr); 41320c7d97c5SJed Brown ierr = METIS_SetDefaultOptions(options); 41330c7d97c5SJed Brown /* we need a contiguous partition of the coarse mesh */ 41340c7d97c5SJed Brown options[METIS_OPTION_CONTIG]=1; 41350c7d97c5SJed Brown options[METIS_OPTION_NITER]=30; 41364fad6a16SStefano Zampini if (pcbddc->coarsening_ratio > 1) { 41373828260eSStefano Zampini if (n_subdomains>n_parts*heuristic_for_metis) { 41383828260eSStefano Zampini options[METIS_OPTION_IPTYPE]=METIS_IPTYPE_EDGE; 41393828260eSStefano Zampini options[METIS_OPTION_OBJTYPE]=METIS_OBJTYPE_CUT; 41400c7d97c5SJed Brown ierr = METIS_PartGraphKway(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 4141142dfd88SStefano 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); 41423828260eSStefano Zampini } else { 41433828260eSStefano Zampini ierr = METIS_PartGraphRecursive(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 4144142dfd88SStefano 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); 41453828260eSStefano Zampini } 41464fad6a16SStefano Zampini } else { 41474fad6a16SStefano Zampini for (i=0;i<n_subdomains;i++) { 41484fad6a16SStefano Zampini metis_coarse_subdivision[i]=i; 41494fad6a16SStefano Zampini } 41504fad6a16SStefano Zampini } 41510c7d97c5SJed Brown ierr = PetscFree(faces_xadj);CHKERRQ(ierr); 41520c7d97c5SJed Brown ierr = PetscFree(faces_adjncy);CHKERRQ(ierr); 41530bdf917eSStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&coarse_subdivision);CHKERRQ(ierr); 41540c7d97c5SJed Brown /* copy/cast values avoiding possible type conflicts between PETSc, MPI and METIS */ 41550bdf917eSStefano Zampini for (i=0;i<size_prec_comm;i++) { coarse_subdivision[i]=MPI_PROC_NULL; } 41560bdf917eSStefano Zampini for (i=0;i<n_subdomains;i++) { coarse_subdivision[ranks_stretching_ratio*i]=(PetscInt)(metis_coarse_subdivision[i]); } 41570c7d97c5SJed Brown ierr = PetscFree(metis_coarse_subdivision);CHKERRQ(ierr); 41580c7d97c5SJed Brown } 41590c7d97c5SJed Brown 41600c7d97c5SJed Brown /* Create new communicator for coarse problem splitting the old one */ 41610c7d97c5SJed Brown if (!(rank_prec_comm%procs_jumps_coarse_comm) && rank_prec_comm < procs_jumps_coarse_comm*n_parts) { 4162da1bb401SStefano Zampini coarse_color=0; /* for communicator splitting */ 4163da1bb401SStefano Zampini active_rank=rank_prec_comm; /* for insertion of matrix values */ 41640c7d97c5SJed Brown } 4165da1bb401SStefano Zampini /* procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 4166da1bb401SStefano Zampini key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator */ 416753cdbc3dSStefano Zampini ierr = MPI_Comm_split(prec_comm,coarse_color,rank_prec_comm,&coarse_comm);CHKERRQ(ierr); 41680c7d97c5SJed Brown 41690c7d97c5SJed Brown if (coarse_color == 0) { 417053cdbc3dSStefano Zampini ierr = MPI_Comm_size(coarse_comm,&size_coarse_comm);CHKERRQ(ierr); 417153cdbc3dSStefano Zampini ierr = MPI_Comm_rank(coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 41720c7d97c5SJed Brown } else { 41730c7d97c5SJed Brown rank_coarse_comm = MPI_PROC_NULL; 41740c7d97c5SJed Brown } 41750c7d97c5SJed Brown 41767cf533a6SStefano Zampini /* master proc take care of arranging and distributing coarse information */ 41770c7d97c5SJed Brown if (rank_coarse_comm == master_proc) { 41780c7d97c5SJed Brown ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&displacements_recv);CHKERRQ(ierr); 41790bdf917eSStefano Zampini ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&total_count_recv);CHKERRQ(ierr); 41800bdf917eSStefano Zampini ierr = PetscMalloc (n_subdomains*sizeof(PetscMPIInt),&total_ranks_recv);CHKERRQ(ierr); 41810c7d97c5SJed Brown /* some initializations */ 41820c7d97c5SJed Brown displacements_recv[0]=0; 41830bdf917eSStefano Zampini ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 41840c7d97c5SJed Brown /* count from how many processes the j-th process of the coarse decomposition will receive data */ 41850bdf917eSStefano Zampini for (j=0;j<size_coarse_comm;j++) { 41860bdf917eSStefano Zampini for (i=0;i<size_prec_comm;i++) { 41870bdf917eSStefano Zampini if (coarse_subdivision[i]==j) { 41880c7d97c5SJed Brown total_count_recv[j]++; 41890bdf917eSStefano Zampini } 41900bdf917eSStefano Zampini } 41910bdf917eSStefano Zampini } 41920c7d97c5SJed Brown /* displacements needed for scatterv of total_ranks_recv */ 41930bdf917eSStefano Zampini for (i=1;i<size_coarse_comm;i++) { displacements_recv[i]=displacements_recv[i-1]+total_count_recv[i-1]; } 41940c7d97c5SJed Brown /* Now fill properly total_ranks_recv -> each coarse process will receive the ranks (in prec_comm communicator) of its friend (sending) processes */ 41950c7d97c5SJed Brown ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 41960c7d97c5SJed Brown for (j=0;j<size_coarse_comm;j++) { 41973828260eSStefano Zampini for (i=0;i<size_prec_comm;i++) { 41980c7d97c5SJed Brown if (coarse_subdivision[i]==j) { 41990c7d97c5SJed Brown total_ranks_recv[displacements_recv[j]+total_count_recv[j]]=i; 42003828260eSStefano Zampini total_count_recv[j]+=1; 42010c7d97c5SJed Brown } 42020c7d97c5SJed Brown } 42030c7d97c5SJed Brown } 4204da1bb401SStefano Zampini /* for (j=0;j<size_coarse_comm;j++) { 42053828260eSStefano Zampini printf("process %d in new rank will receive from %d processes (original ranks follows)\n",j,total_count_recv[j]); 42063828260eSStefano Zampini for (i=0;i<total_count_recv[j];i++) { 42073828260eSStefano Zampini printf("%d ",total_ranks_recv[displacements_recv[j]+i]); 42083828260eSStefano Zampini } 42093828260eSStefano Zampini printf("\n"); 4210da1bb401SStefano Zampini } */ 42110c7d97c5SJed Brown 42120c7d97c5SJed Brown /* identify new decomposition in terms of ranks in the old communicator */ 42130bdf917eSStefano Zampini for (i=0;i<n_subdomains;i++) { 42140bdf917eSStefano Zampini coarse_subdivision[ranks_stretching_ratio*i]=coarse_subdivision[ranks_stretching_ratio*i]*procs_jumps_coarse_comm; 42150bdf917eSStefano Zampini } 4216da1bb401SStefano Zampini /* printf("coarse_subdivision in old end new ranks\n"); 42170c7d97c5SJed Brown for (i=0;i<size_prec_comm;i++) 42183828260eSStefano Zampini if (coarse_subdivision[i]!=MPI_PROC_NULL) { 42193828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]/procs_jumps_coarse_comm); 42203828260eSStefano Zampini } else { 42213828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]); 42223828260eSStefano Zampini } 4223da1bb401SStefano Zampini printf("\n"); */ 42240c7d97c5SJed Brown } 42250c7d97c5SJed Brown 42260c7d97c5SJed Brown /* Scatter new decomposition for send details */ 422753cdbc3dSStefano Zampini ierr = MPI_Scatter(&coarse_subdivision[0],1,MPIU_INT,&rank_coarse_proc_send_to,1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 42280c7d97c5SJed Brown /* Scatter receiving details to members of coarse decomposition */ 42290c7d97c5SJed Brown if (coarse_color == 0) { 423053cdbc3dSStefano Zampini ierr = MPI_Scatter(&total_count_recv[0],1,MPIU_INT,&count_recv,1,MPIU_INT,master_proc,coarse_comm);CHKERRQ(ierr); 42310c7d97c5SJed Brown ierr = PetscMalloc (count_recv*sizeof(PetscMPIInt),&ranks_recv);CHKERRQ(ierr); 423253cdbc3dSStefano 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); 42330c7d97c5SJed Brown } 42340c7d97c5SJed Brown 4235da1bb401SStefano Zampini /* printf("I will send my matrix data to proc %d\n",rank_coarse_proc_send_to); 4236da1bb401SStefano Zampini if (coarse_color == 0) { 4237da1bb401SStefano Zampini printf("I will receive some matrix data from %d processes (ranks follows)\n",count_recv); 4238da1bb401SStefano Zampini for (i=0;i<count_recv;i++) 4239da1bb401SStefano Zampini printf("%d ",ranks_recv[i]); 4240da1bb401SStefano Zampini printf("\n"); 4241da1bb401SStefano Zampini } */ 42420c7d97c5SJed Brown 42430c7d97c5SJed Brown if (rank_prec_comm == master_proc) { 42440bdf917eSStefano Zampini ierr = PetscFree(coarse_subdivision);CHKERRQ(ierr); 4245da1bb401SStefano Zampini ierr = PetscFree(total_count_recv);CHKERRQ(ierr); 42460bdf917eSStefano Zampini ierr = PetscFree(total_ranks_recv);CHKERRQ(ierr); 42470c7d97c5SJed Brown ierr = PetscFree(displacements_recv);CHKERRQ(ierr); 42480c7d97c5SJed Brown } 42490c7d97c5SJed Brown break; 42500c7d97c5SJed Brown } 42510c7d97c5SJed Brown 42520c7d97c5SJed Brown case(REPLICATED_BDDC): 42530c7d97c5SJed Brown 42540c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 42550c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 42560c7d97c5SJed Brown coarse_pc_type = PCLU; 425753cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 42580c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 42590c7d97c5SJed Brown active_rank = rank_prec_comm; 42600c7d97c5SJed Brown break; 42610c7d97c5SJed Brown 42620c7d97c5SJed Brown case(PARALLEL_BDDC): 42630c7d97c5SJed Brown 42640c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 42650c7d97c5SJed Brown coarse_mat_type = MATMPIAIJ; 42660c7d97c5SJed Brown coarse_pc_type = PCREDUNDANT; 426753cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 42680c7d97c5SJed Brown coarse_comm = prec_comm; 42690c7d97c5SJed Brown active_rank = rank_prec_comm; 42700c7d97c5SJed Brown break; 42710c7d97c5SJed Brown 42720c7d97c5SJed Brown case(SEQUENTIAL_BDDC): 42730c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 42740c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 42750c7d97c5SJed Brown coarse_pc_type = PCLU; 427653cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 42770c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 42780c7d97c5SJed Brown active_rank = master_proc; 42790c7d97c5SJed Brown break; 42800c7d97c5SJed Brown } 42810c7d97c5SJed Brown 42820c7d97c5SJed Brown switch (pcbddc->coarse_communications_type) { 42830c7d97c5SJed Brown 42840c7d97c5SJed Brown case(SCATTERS_BDDC): 42850c7d97c5SJed Brown { 42860c7d97c5SJed Brown if (pcbddc->coarse_problem_type==MULTILEVEL_BDDC) { 42870c7d97c5SJed Brown 42882e8d2280SStefano Zampini IS coarse_IS; 42892e8d2280SStefano Zampini 4290523858cfSStefano Zampini if (pcbddc->coarsening_ratio == 1) { 4291523858cfSStefano Zampini ins_local_primal_size = pcbddc->local_primal_size; 4292523858cfSStefano Zampini ins_local_primal_indices = pcbddc->local_primal_indices; 4293523858cfSStefano Zampini if (coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 4294523858cfSStefano Zampini /* nonzeros */ 4295523858cfSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&dnz);CHKERRQ(ierr); 4296523858cfSStefano Zampini ierr = PetscMemzero(dnz,ins_local_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 4297523858cfSStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 4298523858cfSStefano Zampini dnz[i] = ins_local_primal_size; 4299523858cfSStefano Zampini } 4300523858cfSStefano Zampini } else { 43010c7d97c5SJed Brown PetscMPIInt send_size; 4302ef028eecSStefano Zampini PetscMPIInt *send_buffer; 43030c7d97c5SJed Brown PetscInt *aux_ins_indices; 43040c7d97c5SJed Brown PetscInt ii,jj; 43050c7d97c5SJed Brown MPI_Request *requests; 4306ef028eecSStefano Zampini 4307523858cfSStefano Zampini ierr = PetscMalloc(count_recv*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 4308523858cfSStefano Zampini /* reusing pcbddc->local_primal_displacements and pcbddc->replicated_primal_size */ 4309523858cfSStefano Zampini ierr = PetscFree(pcbddc->local_primal_displacements);CHKERRQ(ierr); 4310523858cfSStefano Zampini ierr = PetscMalloc((count_recv+1)*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 4311523858cfSStefano Zampini pcbddc->replicated_primal_size = count_recv; 4312523858cfSStefano Zampini j = 0; 4313523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 4314523858cfSStefano Zampini pcbddc->local_primal_displacements[i] = j; 4315523858cfSStefano Zampini j += pcbddc->local_primal_sizes[ranks_recv[i]]; 4316523858cfSStefano Zampini } 4317523858cfSStefano Zampini pcbddc->local_primal_displacements[count_recv] = j; 4318523858cfSStefano Zampini ierr = PetscMalloc(j*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 43190c7d97c5SJed Brown /* allocate auxiliary space */ 4320523858cfSStefano Zampini ierr = PetscMalloc(count_recv*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 43210c7d97c5SJed Brown ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscInt),&aux_ins_indices);CHKERRQ(ierr); 43220c7d97c5SJed Brown ierr = PetscMemzero(aux_ins_indices,pcbddc->coarse_size*sizeof(PetscInt));CHKERRQ(ierr); 43230c7d97c5SJed Brown /* allocate stuffs for message massing */ 43240c7d97c5SJed Brown ierr = PetscMalloc((count_recv+1)*sizeof(MPI_Request),&requests);CHKERRQ(ierr); 4325523858cfSStefano Zampini for (i=0;i<count_recv+1;i++) { requests[i]=MPI_REQUEST_NULL; } 4326523858cfSStefano Zampini /* send indices to be inserted */ 4327523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 4328523858cfSStefano Zampini send_size = pcbddc->local_primal_sizes[ranks_recv[i]]; 4329523858cfSStefano 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); 4330523858cfSStefano Zampini } 4331523858cfSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL) { 4332523858cfSStefano Zampini send_size = pcbddc->local_primal_size; 4333ef028eecSStefano Zampini ierr = PetscMalloc(send_size*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 4334ef028eecSStefano Zampini for (i=0;i<send_size;i++) { 4335ef028eecSStefano Zampini send_buffer[i]=(PetscMPIInt)pcbddc->local_primal_indices[i]; 4336ef028eecSStefano Zampini } 4337ef028eecSStefano Zampini ierr = MPI_Isend(send_buffer,send_size,MPIU_INT,rank_coarse_proc_send_to,999,prec_comm,&requests[count_recv]);CHKERRQ(ierr); 4338523858cfSStefano Zampini } 4339523858cfSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4340ef028eecSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL) { 4341ef028eecSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 4342ef028eecSStefano Zampini } 43430c7d97c5SJed Brown j = 0; 43440c7d97c5SJed Brown for (i=0;i<count_recv;i++) { 43452e8d2280SStefano Zampini ii = pcbddc->local_primal_displacements[i+1]-pcbddc->local_primal_displacements[i]; 43462e8d2280SStefano Zampini localsizes2[i] = ii*ii; 43470c7d97c5SJed Brown localdispl2[i] = j; 43480c7d97c5SJed Brown j += localsizes2[i]; 4349523858cfSStefano Zampini jj = pcbddc->local_primal_displacements[i]; 43504fad6a16SStefano Zampini /* it counts the coarse subdomains sharing the coarse node */ 43512e8d2280SStefano Zampini for (k=0;k<ii;k++) { 43524fad6a16SStefano Zampini aux_ins_indices[pcbddc->replicated_local_primal_indices[jj+k]] += 1; 43530c7d97c5SJed Brown } 43544fad6a16SStefano Zampini } 4355523858cfSStefano Zampini /* temp_coarse_mat_vals used to store matrix values to be received */ 43560c7d97c5SJed Brown ierr = PetscMalloc(j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 43570c7d97c5SJed Brown /* evaluate how many values I will insert in coarse mat */ 43580c7d97c5SJed Brown ins_local_primal_size = 0; 4359ea7e1babSStefano Zampini for (i=0;i<pcbddc->coarse_size;i++) { 4360ea7e1babSStefano Zampini if (aux_ins_indices[i]) { 43610c7d97c5SJed Brown ins_local_primal_size++; 4362ea7e1babSStefano Zampini } 4363ea7e1babSStefano Zampini } 43640c7d97c5SJed Brown /* evaluate indices I will insert in coarse mat */ 43650c7d97c5SJed Brown ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 43660c7d97c5SJed Brown j = 0; 4367ea7e1babSStefano Zampini for (i=0;i<pcbddc->coarse_size;i++) { 4368ea7e1babSStefano Zampini if (aux_ins_indices[i]) { 43692e8d2280SStefano Zampini ins_local_primal_indices[j] = i; 43702e8d2280SStefano Zampini j++; 4371ea7e1babSStefano Zampini } 4372ea7e1babSStefano Zampini } 4373523858cfSStefano Zampini /* processes partecipating in coarse problem receive matrix data from their friends */ 4374523858cfSStefano Zampini for (i=0;i<count_recv;i++) { 4375523858cfSStefano Zampini ierr = MPI_Irecv(&temp_coarse_mat_vals[localdispl2[i]],localsizes2[i],MPIU_SCALAR,ranks_recv[i],666,prec_comm,&requests[i]);CHKERRQ(ierr); 4376523858cfSStefano Zampini } 4377523858cfSStefano Zampini if (rank_coarse_proc_send_to != MPI_PROC_NULL) { 4378523858cfSStefano Zampini send_size = pcbddc->local_primal_size*pcbddc->local_primal_size; 4379523858cfSStefano 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); 4380523858cfSStefano Zampini } 4381523858cfSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4382523858cfSStefano Zampini /* nonzeros */ 4383523858cfSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&dnz);CHKERRQ(ierr); 4384523858cfSStefano Zampini ierr = PetscMemzero(dnz,ins_local_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 43850c7d97c5SJed Brown /* use aux_ins_indices to realize a global to local mapping */ 43860c7d97c5SJed Brown j=0; 43870c7d97c5SJed Brown for (i=0;i<pcbddc->coarse_size;i++) { 43880c7d97c5SJed Brown if (aux_ins_indices[i]==0) { 43890c7d97c5SJed Brown aux_ins_indices[i]=-1; 43900c7d97c5SJed Brown } else { 43910c7d97c5SJed Brown aux_ins_indices[i]=j; 43920c7d97c5SJed Brown j++; 43930c7d97c5SJed Brown } 43940c7d97c5SJed Brown } 43954fad6a16SStefano Zampini for (i=0;i<count_recv;i++) { 4396523858cfSStefano Zampini j = pcbddc->local_primal_sizes[ranks_recv[i]]; 4397523858cfSStefano Zampini for (k=0;k<j;k++) { 4398523858cfSStefano Zampini dnz[aux_ins_indices[pcbddc->replicated_local_primal_indices[pcbddc->local_primal_displacements[i]+k]]] += j; 43990c7d97c5SJed Brown } 44000c7d97c5SJed Brown } 4401523858cfSStefano Zampini /* check */ 4402523858cfSStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 4403523858cfSStefano Zampini if (dnz[i] > ins_local_primal_size) { 4404523858cfSStefano Zampini dnz[i] = ins_local_primal_size; 44050c7d97c5SJed Brown } 44060c7d97c5SJed Brown } 44070c7d97c5SJed Brown ierr = PetscFree(requests);CHKERRQ(ierr); 44080c7d97c5SJed Brown ierr = PetscFree(aux_ins_indices);CHKERRQ(ierr); 44090c7d97c5SJed Brown if (coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 44104fad6a16SStefano Zampini } 44110c7d97c5SJed Brown /* create local to global mapping needed by coarse MATIS */ 4412142dfd88SStefano Zampini if (coarse_comm != MPI_COMM_NULL) {ierr = MPI_Comm_free(&coarse_comm);CHKERRQ(ierr);} 44130c7d97c5SJed Brown coarse_comm = prec_comm; 44140c7d97c5SJed Brown active_rank = rank_prec_comm; 44150c7d97c5SJed Brown ierr = ISCreateGeneral(coarse_comm,ins_local_primal_size,ins_local_primal_indices,PETSC_COPY_VALUES,&coarse_IS);CHKERRQ(ierr); 44160c7d97c5SJed Brown ierr = ISLocalToGlobalMappingCreateIS(coarse_IS,&coarse_ISLG);CHKERRQ(ierr); 44170c7d97c5SJed Brown ierr = ISDestroy(&coarse_IS);CHKERRQ(ierr); 44182e8d2280SStefano Zampini } else if (pcbddc->coarse_problem_type==PARALLEL_BDDC) { 44190c7d97c5SJed Brown /* arrays for values insertion */ 44200c7d97c5SJed Brown ins_local_primal_size = pcbddc->local_primal_size; 44212e8d2280SStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 44220c7d97c5SJed Brown ierr = PetscMalloc(ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 44230c7d97c5SJed Brown for (j=0;j<ins_local_primal_size;j++) { 44240c7d97c5SJed Brown ins_local_primal_indices[j]=pcbddc->local_primal_indices[j]; 44254fad6a16SStefano Zampini for (i=0;i<ins_local_primal_size;i++) { 44264fad6a16SStefano Zampini ins_coarse_mat_vals[j*ins_local_primal_size+i]=coarse_submat_vals[j*ins_local_primal_size+i]; 44274fad6a16SStefano Zampini } 44280c7d97c5SJed Brown } 44290c7d97c5SJed Brown } 44300c7d97c5SJed Brown break; 44310c7d97c5SJed Brown 44320c7d97c5SJed Brown } 44330c7d97c5SJed Brown 44340c7d97c5SJed Brown case(GATHERS_BDDC): 44350c7d97c5SJed Brown { 44360c7d97c5SJed Brown 44370c7d97c5SJed Brown PetscMPIInt mysize,mysize2; 4438ef028eecSStefano Zampini PetscMPIInt *send_buffer; 44390c7d97c5SJed Brown 44400c7d97c5SJed Brown if (rank_prec_comm==active_rank) { 44410c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 44420bdf917eSStefano Zampini ierr = PetscMalloc (pcbddc->replicated_primal_size*sizeof(PetscScalar),&pcbddc->replicated_local_primal_values);CHKERRQ(ierr); 44430c7d97c5SJed Brown ierr = PetscMalloc (size_prec_comm*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 44440c7d97c5SJed Brown ierr = PetscMalloc (size_prec_comm*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 44450c7d97c5SJed Brown /* arrays for values insertion */ 44464fad6a16SStefano Zampini for (i=0;i<size_prec_comm;i++) { localsizes2[i]=pcbddc->local_primal_sizes[i]*pcbddc->local_primal_sizes[i]; } 44470c7d97c5SJed Brown localdispl2[0]=0; 44484fad6a16SStefano Zampini for (i=1;i<size_prec_comm;i++) { localdispl2[i]=localsizes2[i-1]+localdispl2[i-1]; } 44490c7d97c5SJed Brown j=0; 44504fad6a16SStefano Zampini for (i=0;i<size_prec_comm;i++) { j+=localsizes2[i]; } 44510c7d97c5SJed Brown ierr = PetscMalloc (j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 44520c7d97c5SJed Brown } 44530c7d97c5SJed Brown 44540c7d97c5SJed Brown mysize=pcbddc->local_primal_size; 44550c7d97c5SJed Brown mysize2=pcbddc->local_primal_size*pcbddc->local_primal_size; 4456ef028eecSStefano Zampini ierr = PetscMalloc(mysize*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 4457ef028eecSStefano Zampini for (i=0;i<mysize;i++) { 4458ef028eecSStefano Zampini send_buffer[i]=(PetscMPIInt)pcbddc->local_primal_indices[i]; 4459ef028eecSStefano Zampini } 44600c7d97c5SJed Brown if (pcbddc->coarse_problem_type == SEQUENTIAL_BDDC) { 4461ef028eecSStefano 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); 446253cdbc3dSStefano 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); 44630c7d97c5SJed Brown } else { 4464ef028eecSStefano 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); 446553cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,prec_comm);CHKERRQ(ierr); 44660c7d97c5SJed Brown } 4467ef028eecSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 44680c7d97c5SJed Brown break; 4469da1bb401SStefano Zampini }/* switch on coarse problem and communications associated with finished */ 44700c7d97c5SJed Brown } 44710c7d97c5SJed Brown 44720c7d97c5SJed Brown /* Now create and fill up coarse matrix */ 44730c7d97c5SJed Brown if (rank_prec_comm == active_rank) { 4474142dfd88SStefano Zampini 4475142dfd88SStefano Zampini Mat matis_coarse_local_mat; 4476142dfd88SStefano Zampini 44770c7d97c5SJed Brown if (pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 44780c7d97c5SJed Brown ierr = MatCreate(coarse_comm,&pcbddc->coarse_mat);CHKERRQ(ierr); 44790c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_mat,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size);CHKERRQ(ierr); 44800c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_mat,coarse_mat_type);CHKERRQ(ierr); 44813b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 4482da1bb401SStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 44833b03a366Sstefano_zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 44840c7d97c5SJed Brown } else { 44854fad6a16SStefano Zampini ierr = MatCreateIS(coarse_comm,1,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_ISLG,&pcbddc->coarse_mat);CHKERRQ(ierr); 44863b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 44870c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 44883b03a366Sstefano_zampini ierr = MatSetUp(matis_coarse_local_mat);CHKERRQ(ierr); 4489da1bb401SStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 4490a0ba757dSStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 44910c7d97c5SJed Brown } 4492142dfd88SStefano Zampini /* preallocation */ 4493142dfd88SStefano Zampini if (pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 4494ef028eecSStefano Zampini 4495142dfd88SStefano Zampini PetscInt lrows,lcols; 4496ef028eecSStefano Zampini 4497142dfd88SStefano Zampini ierr = MatGetLocalSize(pcbddc->coarse_mat,&lrows,&lcols);CHKERRQ(ierr); 4498142dfd88SStefano Zampini ierr = MatPreallocateInitialize(coarse_comm,lrows,lcols,dnz,onz);CHKERRQ(ierr); 4499ef028eecSStefano Zampini 4500142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == PARALLEL_BDDC) { 4501ef028eecSStefano Zampini 4502ef028eecSStefano Zampini Vec vec_dnz,vec_onz; 4503ef028eecSStefano Zampini PetscScalar *my_dnz,*my_onz,*array; 4504ef028eecSStefano Zampini PetscInt *mat_ranges,*row_ownership; 4505ef028eecSStefano Zampini PetscInt coarse_index_row,coarse_index_col,owner; 4506ef028eecSStefano Zampini 4507ef028eecSStefano Zampini ierr = VecCreate(prec_comm,&vec_dnz);CHKERRQ(ierr); 4508ef028eecSStefano Zampini ierr = VecSetSizes(vec_dnz,PETSC_DECIDE,pcbddc->coarse_size);CHKERRQ(ierr); 4509ef028eecSStefano Zampini ierr = VecSetType(vec_dnz,VECMPI);CHKERRQ(ierr); 4510ef028eecSStefano Zampini ierr = VecDuplicate(vec_dnz,&vec_onz);CHKERRQ(ierr); 4511ef028eecSStefano Zampini 4512ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscScalar),&my_dnz);CHKERRQ(ierr); 4513ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscScalar),&my_onz);CHKERRQ(ierr); 4514ef028eecSStefano Zampini ierr = PetscMemzero(my_dnz,pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 4515ef028eecSStefano Zampini ierr = PetscMemzero(my_onz,pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 4516ef028eecSStefano Zampini 4517ef028eecSStefano Zampini ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscInt),&row_ownership);CHKERRQ(ierr); 4518ef028eecSStefano Zampini ierr = MatGetOwnershipRanges(pcbddc->coarse_mat,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 4519142dfd88SStefano Zampini for (i=0;i<size_prec_comm;i++) { 4520ef028eecSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 4521ef028eecSStefano Zampini row_ownership[j]=i; 4522142dfd88SStefano Zampini } 4523142dfd88SStefano Zampini } 4524ef028eecSStefano Zampini 4525ef028eecSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 4526ef028eecSStefano Zampini coarse_index_row = pcbddc->local_primal_indices[i]; 4527ef028eecSStefano Zampini owner = row_ownership[coarse_index_row]; 4528ef028eecSStefano Zampini for (j=i;j<pcbddc->local_primal_size;j++) { 4529ef028eecSStefano Zampini owner = row_ownership[coarse_index_row]; 4530ef028eecSStefano Zampini coarse_index_col = pcbddc->local_primal_indices[j]; 4531ef028eecSStefano Zampini if (coarse_index_col > mat_ranges[owner]-1 && coarse_index_col < mat_ranges[owner+1]) { 4532ef028eecSStefano Zampini my_dnz[i] += 1.0; 4533142dfd88SStefano Zampini } else { 4534ef028eecSStefano Zampini my_onz[i] += 1.0; 4535142dfd88SStefano Zampini } 4536ef028eecSStefano Zampini if (i != j) { 4537ef028eecSStefano Zampini owner = row_ownership[coarse_index_col]; 4538ef028eecSStefano Zampini if (coarse_index_row > mat_ranges[owner]-1 && coarse_index_row < mat_ranges[owner+1]) { 4539ef028eecSStefano Zampini my_dnz[j] += 1.0; 4540142dfd88SStefano Zampini } else { 4541ef028eecSStefano Zampini my_onz[j] += 1.0; 4542142dfd88SStefano Zampini } 4543142dfd88SStefano Zampini } 4544142dfd88SStefano Zampini } 4545142dfd88SStefano Zampini } 4546ef028eecSStefano Zampini ierr = VecSet(vec_dnz,0.0);CHKERRQ(ierr); 4547ef028eecSStefano Zampini ierr = VecSet(vec_onz,0.0);CHKERRQ(ierr); 4548a929c220SStefano Zampini if (pcbddc->local_primal_size) { 4549ef028eecSStefano Zampini ierr = VecSetValues(vec_dnz,pcbddc->local_primal_size,pcbddc->local_primal_indices,my_dnz,ADD_VALUES);CHKERRQ(ierr); 4550ef028eecSStefano Zampini ierr = VecSetValues(vec_onz,pcbddc->local_primal_size,pcbddc->local_primal_indices,my_onz,ADD_VALUES);CHKERRQ(ierr); 4551a929c220SStefano Zampini } 4552ef028eecSStefano Zampini ierr = VecAssemblyBegin(vec_dnz);CHKERRQ(ierr); 4553ef028eecSStefano Zampini ierr = VecAssemblyBegin(vec_onz);CHKERRQ(ierr); 4554ef028eecSStefano Zampini ierr = VecAssemblyEnd(vec_dnz);CHKERRQ(ierr); 4555ef028eecSStefano Zampini ierr = VecAssemblyEnd(vec_onz);CHKERRQ(ierr); 4556ef028eecSStefano Zampini j = mat_ranges[rank_prec_comm+1]-mat_ranges[rank_prec_comm]; 4557ef028eecSStefano Zampini ierr = VecGetArray(vec_dnz,&array);CHKERRQ(ierr); 4558ef028eecSStefano Zampini for (i=0;i<j;i++) { 4559ef028eecSStefano Zampini dnz[i] = (PetscInt)array[i]; 4560142dfd88SStefano Zampini } 4561ef028eecSStefano Zampini ierr = VecRestoreArray(vec_dnz,&array);CHKERRQ(ierr); 4562ef028eecSStefano Zampini ierr = VecGetArray(vec_onz,&array);CHKERRQ(ierr); 4563ef028eecSStefano Zampini for (i=0;i<j;i++) { 4564ef028eecSStefano Zampini onz[i] = (PetscInt)array[i]; 4565142dfd88SStefano Zampini } 4566ef028eecSStefano Zampini ierr = VecRestoreArray(vec_onz,&array);CHKERRQ(ierr); 4567ef028eecSStefano Zampini ierr = PetscFree(my_dnz);CHKERRQ(ierr); 4568ef028eecSStefano Zampini ierr = PetscFree(my_onz);CHKERRQ(ierr); 4569ef028eecSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 4570ef028eecSStefano Zampini ierr = VecDestroy(&vec_dnz);CHKERRQ(ierr); 4571ef028eecSStefano Zampini ierr = VecDestroy(&vec_onz);CHKERRQ(ierr); 4572142dfd88SStefano Zampini } else { 4573142dfd88SStefano Zampini for (k=0;k<size_prec_comm;k++) { 4574142dfd88SStefano Zampini offset=pcbddc->local_primal_displacements[k]; 4575142dfd88SStefano Zampini offset2=localdispl2[k]; 4576142dfd88SStefano Zampini ins_local_primal_size = pcbddc->local_primal_sizes[k]; 4577ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 4578ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++) { 4579ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 4580ef028eecSStefano Zampini } 4581142dfd88SStefano Zampini for (j=0;j<ins_local_primal_size;j++) { 4582142dfd88SStefano Zampini ierr = MatPreallocateSet(ins_local_primal_indices[j],ins_local_primal_size,ins_local_primal_indices,dnz,onz);CHKERRQ(ierr); 4583142dfd88SStefano Zampini } 4584ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 4585142dfd88SStefano Zampini } 4586142dfd88SStefano Zampini } 4587142dfd88SStefano Zampini /* check */ 4588142dfd88SStefano Zampini for (i=0;i<lrows;i++) { 4589142dfd88SStefano Zampini if (dnz[i]>lcols) { 4590142dfd88SStefano Zampini dnz[i]=lcols; 4591142dfd88SStefano Zampini } 4592142dfd88SStefano Zampini if (onz[i]>pcbddc->coarse_size-lcols) { 4593142dfd88SStefano Zampini onz[i]=pcbddc->coarse_size-lcols; 4594142dfd88SStefano Zampini } 4595142dfd88SStefano Zampini } 4596142dfd88SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->coarse_mat,PETSC_NULL,dnz);CHKERRQ(ierr); 4597142dfd88SStefano Zampini ierr = MatMPIAIJSetPreallocation(pcbddc->coarse_mat,PETSC_NULL,dnz,PETSC_NULL,onz);CHKERRQ(ierr); 4598142dfd88SStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 4599142dfd88SStefano Zampini } else { 4600523858cfSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis_coarse_local_mat,0,dnz);CHKERRQ(ierr); 4601523858cfSStefano Zampini ierr = PetscFree(dnz);CHKERRQ(ierr); 4602142dfd88SStefano Zampini } 4603142dfd88SStefano Zampini /* insert values */ 4604523858cfSStefano Zampini if (pcbddc->coarse_problem_type == PARALLEL_BDDC) { 46050c7d97c5SJed 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); 4606523858cfSStefano Zampini } else if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 4607523858cfSStefano Zampini if (pcbddc->coarsening_ratio == 1) { 4608523858cfSStefano Zampini ins_coarse_mat_vals = coarse_submat_vals; 4609523858cfSStefano 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); 4610523858cfSStefano Zampini } else { 4611523858cfSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 4612523858cfSStefano Zampini for (k=0;k<pcbddc->replicated_primal_size;k++) { 4613523858cfSStefano Zampini offset = pcbddc->local_primal_displacements[k]; 4614523858cfSStefano Zampini offset2 = localdispl2[k]; 4615523858cfSStefano Zampini ins_local_primal_size = pcbddc->local_primal_displacements[k+1]-pcbddc->local_primal_displacements[k]; 4616ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 4617ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++) { 4618ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 4619ef028eecSStefano Zampini } 4620523858cfSStefano Zampini ins_coarse_mat_vals = &temp_coarse_mat_vals[offset2]; 4621523858cfSStefano 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); 4622ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 4623523858cfSStefano Zampini } 4624523858cfSStefano Zampini } 4625523858cfSStefano Zampini ins_local_primal_indices = 0; 4626523858cfSStefano Zampini ins_coarse_mat_vals = 0; 4627ea7e1babSStefano Zampini } else { 4628ea7e1babSStefano Zampini for (k=0;k<size_prec_comm;k++) { 4629ea7e1babSStefano Zampini offset=pcbddc->local_primal_displacements[k]; 4630ea7e1babSStefano Zampini offset2=localdispl2[k]; 4631ea7e1babSStefano Zampini ins_local_primal_size = pcbddc->local_primal_sizes[k]; 4632ef028eecSStefano Zampini ierr = PetscMalloc(ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 4633ef028eecSStefano Zampini for (j=0;j<ins_local_primal_size;j++) { 4634ef028eecSStefano Zampini ins_local_primal_indices[j]=(PetscInt)pcbddc->replicated_local_primal_indices[offset+j]; 4635ef028eecSStefano Zampini } 4636ea7e1babSStefano Zampini ins_coarse_mat_vals = &temp_coarse_mat_vals[offset2]; 4637ea7e1babSStefano 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); 4638ef028eecSStefano Zampini ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); 4639ea7e1babSStefano Zampini } 4640ea7e1babSStefano Zampini ins_local_primal_indices = 0; 4641ea7e1babSStefano Zampini ins_coarse_mat_vals = 0; 4642ea7e1babSStefano Zampini } 46430c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 46440c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4645142dfd88SStefano Zampini /* symmetry of coarse matrix */ 4646142dfd88SStefano Zampini if (issym) { 4647142dfd88SStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 4648142dfd88SStefano Zampini } 46490c7d97c5SJed Brown ierr = MatGetVecs(pcbddc->coarse_mat,&pcbddc->coarse_vec,&pcbddc->coarse_rhs);CHKERRQ(ierr); 46500bdf917eSStefano Zampini } 46510bdf917eSStefano Zampini 46520bdf917eSStefano Zampini /* create loc to glob scatters if needed */ 46530bdf917eSStefano Zampini if (pcbddc->coarse_communications_type == SCATTERS_BDDC) { 46540bdf917eSStefano Zampini IS local_IS,global_IS; 46550bdf917eSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&local_IS);CHKERRQ(ierr); 46560bdf917eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_indices,PETSC_COPY_VALUES,&global_IS);CHKERRQ(ierr); 46570bdf917eSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,local_IS,pcbddc->coarse_vec,global_IS,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 46580bdf917eSStefano Zampini ierr = ISDestroy(&local_IS);CHKERRQ(ierr); 46590bdf917eSStefano Zampini ierr = ISDestroy(&global_IS);CHKERRQ(ierr); 46600bdf917eSStefano Zampini } 46610bdf917eSStefano Zampini 4662a929c220SStefano Zampini /* free memory no longer needed */ 4663a929c220SStefano Zampini if (coarse_ISLG) { ierr = ISLocalToGlobalMappingDestroy(&coarse_ISLG);CHKERRQ(ierr); } 4664a929c220SStefano Zampini if (ins_local_primal_indices) { ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); } 4665a929c220SStefano Zampini if (ins_coarse_mat_vals) { ierr = PetscFree(ins_coarse_mat_vals);CHKERRQ(ierr); } 4666a929c220SStefano Zampini if (localsizes2) { ierr = PetscFree(localsizes2);CHKERRQ(ierr); } 4667a929c220SStefano Zampini if (localdispl2) { ierr = PetscFree(localdispl2);CHKERRQ(ierr); } 4668a929c220SStefano Zampini if (temp_coarse_mat_vals) { ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr); } 4669a929c220SStefano Zampini 46700bdf917eSStefano Zampini /* Eval coarse null space */ 46710bdf917eSStefano Zampini if (pcbddc->NullSpace) { 46720bdf917eSStefano Zampini const Vec *nsp_vecs; 46730bdf917eSStefano Zampini PetscInt nsp_size,coarse_nsp_size; 46740bdf917eSStefano Zampini PetscBool nsp_has_cnst; 46750bdf917eSStefano Zampini PetscReal test_null; 46760bdf917eSStefano Zampini Vec *coarse_nsp_vecs; 46770bdf917eSStefano Zampini 46780bdf917eSStefano Zampini coarse_nsp_size = 0; 46790bdf917eSStefano Zampini coarse_nsp_vecs = 0; 46800bdf917eSStefano Zampini ierr = MatNullSpaceGetVecs(pcbddc->NullSpace,&nsp_has_cnst,&nsp_size,&nsp_vecs);CHKERRQ(ierr); 46810bdf917eSStefano Zampini if (rank_prec_comm == active_rank) { 46820bdf917eSStefano Zampini ierr = PetscMalloc((nsp_size+1)*sizeof(Vec),&coarse_nsp_vecs);CHKERRQ(ierr); 46830bdf917eSStefano Zampini for (i=0;i<nsp_size+1;i++) { 46840bdf917eSStefano Zampini ierr = VecDuplicate(pcbddc->coarse_vec,&coarse_nsp_vecs[i]);CHKERRQ(ierr); 46850bdf917eSStefano Zampini } 46860bdf917eSStefano Zampini } 46870bdf917eSStefano Zampini if (nsp_has_cnst) { 46880bdf917eSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 46890bdf917eSStefano Zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 46900bdf917eSStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 46910bdf917eSStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 46920bdf917eSStefano Zampini if (rank_prec_comm == active_rank) { 46930bdf917eSStefano Zampini ierr = MatMult(pcbddc->coarse_mat,pcbddc->coarse_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 46940bdf917eSStefano Zampini ierr = VecNorm(pcbddc->coarse_rhs,NORM_INFINITY,&test_null);CHKERRQ(ierr); 46950bdf917eSStefano Zampini if (test_null > 1.0e-12 && pcbddc->dbg_flag) { 46960bdf917eSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Constant coarse null space error % 1.14e\n",test_null);CHKERRQ(ierr); 46970bdf917eSStefano Zampini } 46980bdf917eSStefano Zampini ierr = VecCopy(pcbddc->coarse_vec,coarse_nsp_vecs[coarse_nsp_size]);CHKERRQ(ierr); 46990bdf917eSStefano Zampini coarse_nsp_size++; 47000bdf917eSStefano Zampini } 47010bdf917eSStefano Zampini } 47020bdf917eSStefano Zampini for (i=0;i<nsp_size;i++) { 47030bdf917eSStefano Zampini ierr = VecScatterBegin(matis->ctx,nsp_vecs[i],pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 47040bdf917eSStefano Zampini ierr = VecScatterEnd (matis->ctx,nsp_vecs[i],pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 47050bdf917eSStefano Zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 47060bdf917eSStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 47070bdf917eSStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 47080bdf917eSStefano Zampini if (rank_prec_comm == active_rank) { 47090bdf917eSStefano Zampini ierr = MatMult(pcbddc->coarse_mat,pcbddc->coarse_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 47100bdf917eSStefano Zampini ierr = VecNorm(pcbddc->coarse_rhs,NORM_2,&test_null);CHKERRQ(ierr); 47110bdf917eSStefano Zampini if (test_null > 1.0e-12 && pcbddc->dbg_flag) { 47120bdf917eSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Vec %d coarse null space error % 1.14e\n",i,test_null);CHKERRQ(ierr); 47130bdf917eSStefano Zampini } 47140bdf917eSStefano Zampini ierr = VecCopy(pcbddc->coarse_vec,coarse_nsp_vecs[coarse_nsp_size]);CHKERRQ(ierr); 47150bdf917eSStefano Zampini coarse_nsp_size++; 47160bdf917eSStefano Zampini } 47170bdf917eSStefano Zampini } 47180bdf917eSStefano Zampini if (coarse_nsp_size > 0) { 47190bdf917eSStefano Zampini /* TODO orthonormalize vecs */ 47200bdf917eSStefano Zampini ierr = VecNormalize(coarse_nsp_vecs[0],PETSC_NULL);CHKERRQ(ierr); 47210bdf917eSStefano Zampini ierr = MatNullSpaceCreate(coarse_comm,PETSC_FALSE,coarse_nsp_size,coarse_nsp_vecs,&pcbddc->CoarseNullSpace);CHKERRQ(ierr); 47220bdf917eSStefano Zampini for (i=0;i<nsp_size+1;i++) { 47230bdf917eSStefano Zampini ierr = VecDestroy(&coarse_nsp_vecs[i]);CHKERRQ(ierr); 47240bdf917eSStefano Zampini } 47250bdf917eSStefano Zampini } 47260bdf917eSStefano Zampini ierr = PetscFree(coarse_nsp_vecs);CHKERRQ(ierr); 47270bdf917eSStefano Zampini } 47280bdf917eSStefano Zampini 47290bdf917eSStefano Zampini /* KSP for coarse problem */ 47300bdf917eSStefano Zampini if (rank_prec_comm == active_rank) { 47312e8d2280SStefano Zampini PetscBool isbddc=PETSC_FALSE; 47320bdf917eSStefano Zampini 473353cdbc3dSStefano Zampini ierr = KSPCreate(coarse_comm,&pcbddc->coarse_ksp);CHKERRQ(ierr); 473453cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 473553cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 47363b03a366Sstefano_zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,max_it_coarse_ksp);CHKERRQ(ierr); 473753cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 473853cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 473953cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 47400c7d97c5SJed Brown /* Allow user's customization */ 4741da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,"coarse_");CHKERRQ(ierr); 47420c7d97c5SJed Brown /* Set Up PC for coarse problem BDDC */ 474353cdbc3dSStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 47444fad6a16SStefano Zampini i = pcbddc->current_level+1; 47454fad6a16SStefano Zampini ierr = PCBDDCSetLevel(pc_temp,i);CHKERRQ(ierr); 47464fad6a16SStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 47474fad6a16SStefano Zampini ierr = PCBDDCSetMaxLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 474853cdbc3dSStefano Zampini ierr = PCBDDCSetCoarseProblemType(pc_temp,MULTILEVEL_BDDC);CHKERRQ(ierr); 47490bdf917eSStefano Zampini if (pcbddc->CoarseNullSpace) { ierr = PCBDDCSetNullSpace(pc_temp,pcbddc->CoarseNullSpace);CHKERRQ(ierr); } 47504fad6a16SStefano Zampini if (dbg_flag) { 47514fad6a16SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------Level %d: Setting up level %d---------------\n",pcbddc->current_level,i);CHKERRQ(ierr); 47524fad6a16SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 475353cdbc3dSStefano Zampini } 47544fad6a16SStefano Zampini } 47554fad6a16SStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 475653cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 4757142dfd88SStefano Zampini 47582e8d2280SStefano Zampini ierr = KSPGetTolerances(pcbddc->coarse_ksp,PETSC_NULL,PETSC_NULL,PETSC_NULL,&j);CHKERRQ(ierr); 47592e8d2280SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 47602e8d2280SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 47612e8d2280SStefano Zampini if (j == 1) { 47622e8d2280SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 47632e8d2280SStefano Zampini if (isbddc) { 47642e8d2280SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc_temp,PETSC_FALSE);CHKERRQ(ierr); 47655619798eSStefano Zampini } 47665619798eSStefano Zampini } 47670c7d97c5SJed Brown } 4768a929c220SStefano Zampini /* Check coarse problem if requested */ 4769142dfd88SStefano Zampini if (dbg_flag && rank_prec_comm == active_rank) { 4770142dfd88SStefano Zampini KSP check_ksp; 4771142dfd88SStefano Zampini PC check_pc; 4772142dfd88SStefano Zampini Vec check_vec; 4773142dfd88SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min,lambda_max; 477419fd82e9SBarry Smith KSPType check_ksp_type; 47750c7d97c5SJed Brown 4776142dfd88SStefano Zampini /* Create ksp object suitable for extreme eigenvalues' estimation */ 4777142dfd88SStefano Zampini ierr = KSPCreate(coarse_comm,&check_ksp);CHKERRQ(ierr); 4778142dfd88SStefano Zampini ierr = KSPSetOperators(check_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 47790bdf917eSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 4780142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 4781142dfd88SStefano Zampini if (issym) { 4782142dfd88SStefano Zampini check_ksp_type = KSPCG; 4783142dfd88SStefano Zampini } else { 4784142dfd88SStefano Zampini check_ksp_type = KSPGMRES; 4785142dfd88SStefano Zampini } 4786142dfd88SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,PETSC_TRUE);CHKERRQ(ierr); 4787142dfd88SStefano Zampini } else { 4788142dfd88SStefano Zampini check_ksp_type = KSPPREONLY; 4789142dfd88SStefano Zampini } 4790142dfd88SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 4791142dfd88SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 4792142dfd88SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 4793142dfd88SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 4794142dfd88SStefano Zampini /* create random vec */ 4795142dfd88SStefano Zampini ierr = VecDuplicate(pcbddc->coarse_vec,&check_vec);CHKERRQ(ierr); 4796142dfd88SStefano Zampini ierr = VecSetRandom(check_vec,PETSC_NULL);CHKERRQ(ierr); 47970bdf917eSStefano Zampini if (pcbddc->CoarseNullSpace) { ierr = MatNullSpaceRemove(pcbddc->CoarseNullSpace,check_vec,PETSC_NULL);CHKERRQ(ierr); } 4798142dfd88SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,check_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 4799142dfd88SStefano Zampini /* solve coarse problem */ 4800142dfd88SStefano Zampini ierr = KSPSolve(check_ksp,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 48010bdf917eSStefano Zampini if (pcbddc->CoarseNullSpace) { ierr = MatNullSpaceRemove(pcbddc->CoarseNullSpace,pcbddc->coarse_vec,PETSC_NULL);CHKERRQ(ierr); } 4802142dfd88SStefano Zampini /* check coarse problem residual error */ 4803142dfd88SStefano Zampini ierr = VecAXPY(check_vec,-1.0,pcbddc->coarse_vec);CHKERRQ(ierr); 4804142dfd88SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 4805142dfd88SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,check_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 4806142dfd88SStefano Zampini ierr = VecNorm(pcbddc->coarse_rhs,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 4807142dfd88SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 4808142dfd88SStefano Zampini /* get eigenvalue estimation if inexact */ 4809142dfd88SStefano Zampini if (pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 4810142dfd88SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); 4811142dfd88SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&k);CHKERRQ(ierr); 4812142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues estimated with %d iterations of %s.\n",k,check_ksp_type);CHKERRQ(ierr); 4813e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues: % 1.14e %1.14e\n",lambda_min,lambda_max);CHKERRQ(ierr); 48143b03a366Sstefano_zampini } 4815142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem exact infty_error : %1.14e\n",infty_error);CHKERRQ(ierr); 4816142dfd88SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem residual infty_error: %1.14e\n",abs_infty_error);CHKERRQ(ierr); 4817142dfd88SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 481853cdbc3dSStefano Zampini } 4819142dfd88SStefano Zampini if (dbg_flag) { ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); } 48200c7d97c5SJed Brown 48210c7d97c5SJed Brown PetscFunctionReturn(0); 48220c7d97c5SJed Brown } 48230c7d97c5SJed Brown 48240c7d97c5SJed Brown #undef __FUNCT__ 48250c7d97c5SJed Brown #define __FUNCT__ "PCBDDCManageLocalBoundaries" 482653cdbc3dSStefano Zampini static PetscErrorCode PCBDDCManageLocalBoundaries(PC pc) 48270c7d97c5SJed Brown { 48280c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 48290c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 48300c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 4831da1bb401SStefano Zampini PCBDDCGraph mat_graph=pcbddc->mat_graph; 48327cf533a6SStefano Zampini PetscInt *is_indices,*auxis; 48333b03a366Sstefano_zampini PetscInt bs,ierr,i,j,s,k,iindex,neumann_bsize,dirichlet_bsize; 4834da1bb401SStefano Zampini PetscInt total_counts,nodes_touched,where_values=1,vertex_size; 4835534831adSStefano Zampini PetscMPIInt adapt_interface=0,adapt_interface_reduced=0,NEUMANNCNT=0; 4836da1bb401SStefano Zampini PetscBool same_set; 4837a0ba757dSStefano Zampini MPI_Comm interface_comm=((PetscObject)pc)->comm; 48383b03a366Sstefano_zampini PetscBool use_faces=PETSC_FALSE,use_edges=PETSC_FALSE; 48393b03a366Sstefano_zampini const PetscInt *neumann_nodes; 48403b03a366Sstefano_zampini const PetscInt *dirichlet_nodes; 4841a81d60d8SStefano Zampini IS used_IS,*custom_ISForDofs; 4842da1bb401SStefano Zampini PetscScalar *array; 4843da1bb401SStefano Zampini PetscScalar *array2; 4844da1bb401SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 4845a929c220SStefano Zampini PetscInt *queue_in_global_numbering; 48460c7d97c5SJed Brown 48470c7d97c5SJed Brown PetscFunctionBegin; 4848da1bb401SStefano Zampini /* Setup local adjacency graph */ 4849da1bb401SStefano Zampini mat_graph->nvtxs=pcis->n; 4850534831adSStefano Zampini if (!mat_graph->xadj) { NEUMANNCNT = 1; } 4851da1bb401SStefano Zampini ierr = PCBDDCSetupLocalAdjacencyGraph(pc);CHKERRQ(ierr); 4852a0ba757dSStefano Zampini i = mat_graph->nvtxs; 4853a0ba757dSStefano Zampini ierr = PetscMalloc4(i,PetscInt,&mat_graph->where,i,PetscInt,&mat_graph->count,i+1,PetscInt,&mat_graph->cptr,i,PetscInt,&mat_graph->queue);CHKERRQ(ierr); 48543972b0daSStefano Zampini ierr = PetscMalloc2(i,PetscInt,&mat_graph->which_dof,i,PetscBool,&mat_graph->touched);CHKERRQ(ierr); 4855a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->where,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 4856a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->count,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 4857a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->which_dof,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 4858a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->queue,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 48593828260eSStefano Zampini ierr = PetscMemzero(mat_graph->cptr,(mat_graph->nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 4860a0ba757dSStefano Zampini 4861a81d60d8SStefano Zampini /* Setting dofs splitting in mat_graph->which_dof 4862a81d60d8SStefano Zampini Get information about dofs' splitting if provided by the user 4863a81d60d8SStefano Zampini Otherwise it assumes a constant block size */ 4864a81d60d8SStefano Zampini vertex_size=0; 4865a81d60d8SStefano Zampini if (!pcbddc->n_ISForDofs) { 4866a81d60d8SStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 4867a81d60d8SStefano Zampini ierr = PetscMalloc(bs*sizeof(IS),&custom_ISForDofs);CHKERRQ(ierr); 4868a81d60d8SStefano Zampini for (i=0;i<bs;i++) { 4869a81d60d8SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcis->n/bs,i,bs,&custom_ISForDofs[i]);CHKERRQ(ierr); 4870a81d60d8SStefano Zampini } 4871a81d60d8SStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,bs,custom_ISForDofs);CHKERRQ(ierr); 4872a81d60d8SStefano Zampini vertex_size=1; 4873a81d60d8SStefano Zampini /* remove my references to IS objects */ 4874a81d60d8SStefano Zampini for (i=0;i<bs;i++) { 4875a81d60d8SStefano Zampini ierr = ISDestroy(&custom_ISForDofs[i]);CHKERRQ(ierr); 4876a81d60d8SStefano Zampini } 4877a81d60d8SStefano Zampini ierr = PetscFree(custom_ISForDofs);CHKERRQ(ierr); 4878a81d60d8SStefano Zampini } 48799c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 4880a81d60d8SStefano Zampini ierr = ISGetSize(pcbddc->ISForDofs[i],&k);CHKERRQ(ierr); 48819c0446d6SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofs[i],(const PetscInt**)&is_indices);CHKERRQ(ierr); 4882a81d60d8SStefano Zampini for (j=0;j<k;j++) { 48839c0446d6SStefano Zampini mat_graph->which_dof[is_indices[j]]=i; 48849c0446d6SStefano Zampini } 48859c0446d6SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofs[i],(const PetscInt**)&is_indices);CHKERRQ(ierr); 48869c0446d6SStefano Zampini } 4887a81d60d8SStefano Zampini /* use mat block size as vertex size if it has not yet set */ 4888a81d60d8SStefano Zampini if (!vertex_size) { 48893b03a366Sstefano_zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 48900c7d97c5SJed Brown } 4891a81d60d8SStefano Zampini 48923b03a366Sstefano_zampini /* count number of neigh per node */ 48930c7d97c5SJed Brown total_counts=0; 48943b03a366Sstefano_zampini for (i=1;i<pcis->n_neigh;i++) { 48950c7d97c5SJed Brown s=pcis->n_shared[i]; 48960c7d97c5SJed Brown total_counts+=s; 489753cdbc3dSStefano Zampini for (j=0;j<s;j++) { 48980c7d97c5SJed Brown mat_graph->count[pcis->shared[i][j]] += 1; 48990c7d97c5SJed Brown } 49000c7d97c5SJed Brown } 4901534831adSStefano Zampini /* Take into account Neumann data -> it increments number of sharing subdomains for nodes lying on the interface */ 490236e030ebSStefano Zampini ierr = PCBDDCGetNeumannBoundaries(pc,&used_IS);CHKERRQ(ierr); 4903da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 4904da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 490536e030ebSStefano Zampini if (used_IS) { 490636e030ebSStefano Zampini ierr = ISGetSize(used_IS,&neumann_bsize);CHKERRQ(ierr); 490736e030ebSStefano Zampini ierr = ISGetIndices(used_IS,&neumann_nodes);CHKERRQ(ierr); 490853cdbc3dSStefano Zampini for (i=0;i<neumann_bsize;i++) { 490953cdbc3dSStefano Zampini iindex = neumann_nodes[i]; 4910534831adSStefano Zampini if (mat_graph->count[iindex] > NEUMANNCNT && array[iindex]==0.0) { 491153cdbc3dSStefano Zampini mat_graph->count[iindex]+=1; 49120c7d97c5SJed Brown total_counts++; 4913da1bb401SStefano Zampini array[iindex]=array[iindex]+1.0; 4914f23aa3ddSBarry Smith } else if (array[iindex]>0.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Error for neumann nodes provided to BDDC! They must be uniquely listed! Found duplicate node %d\n",iindex); 49150c7d97c5SJed Brown } 49160c7d97c5SJed Brown } 4917da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 4918da1bb401SStefano Zampini /* allocate space for storing the set of neighbours for each node */ 4919da1bb401SStefano Zampini ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt*),&mat_graph->neighbours_set);CHKERRQ(ierr); 4920da1bb401SStefano Zampini if (mat_graph->nvtxs) { ierr = PetscMalloc(total_counts*sizeof(PetscInt),&mat_graph->neighbours_set[0]);CHKERRQ(ierr); } 4921da1bb401SStefano Zampini for (i=1;i<mat_graph->nvtxs;i++) mat_graph->neighbours_set[i]=mat_graph->neighbours_set[i-1]+mat_graph->count[i-1]; 4922a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->count,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 49233b03a366Sstefano_zampini for (i=1;i<pcis->n_neigh;i++) { 49240c7d97c5SJed Brown s=pcis->n_shared[i]; 49250c7d97c5SJed Brown for (j=0;j<s;j++) { 49260c7d97c5SJed Brown k=pcis->shared[i][j]; 4927da1bb401SStefano Zampini mat_graph->neighbours_set[k][mat_graph->count[k]] = pcis->neigh[i]; 49280c7d97c5SJed Brown mat_graph->count[k]+=1; 49290c7d97c5SJed Brown } 49300c7d97c5SJed Brown } 4931da1bb401SStefano Zampini /* Check consistency of Neumann nodes */ 4932da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4933da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4934da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4935da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4936da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4937da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 49383b03a366Sstefano_zampini /* set -1 fake neighbour to mimic Neumann boundary */ 493936e030ebSStefano Zampini if (used_IS) { 494053cdbc3dSStefano Zampini for (i=0;i<neumann_bsize;i++) { 494153cdbc3dSStefano Zampini iindex = neumann_nodes[i]; 4942534831adSStefano Zampini if (mat_graph->count[iindex] > NEUMANNCNT) { 4943da1bb401SStefano Zampini if (mat_graph->count[iindex]+1 != (PetscInt)array[iindex]) { 4944da1bb401SStefano Zampini SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Neumann nodes provided to BDDC must be consistent among neighbours!\nNode %d: number of sharing subdomains %d != number of subdomains for which it is a neumann node %d\n",iindex,mat_graph->count[iindex]+1,(PetscInt)array[iindex]); 4945da1bb401SStefano Zampini } 4946da1bb401SStefano Zampini mat_graph->neighbours_set[iindex][mat_graph->count[iindex]] = -1; 494753cdbc3dSStefano Zampini mat_graph->count[iindex]+=1; 49480c7d97c5SJed Brown } 49490c7d97c5SJed Brown } 495036e030ebSStefano Zampini ierr = ISRestoreIndices(used_IS,&neumann_nodes);CHKERRQ(ierr); 49510c7d97c5SJed Brown } 4952da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 4953da1bb401SStefano Zampini /* sort set of sharing subdomains */ 4954da1bb401SStefano Zampini for (i=0;i<mat_graph->nvtxs;i++) { ierr = PetscSortInt(mat_graph->count[i],mat_graph->neighbours_set[i]);CHKERRQ(ierr); } 49553b03a366Sstefano_zampini /* remove interior nodes and dirichlet boundary nodes from the next search into the graph */ 4956da1bb401SStefano Zampini for (i=0;i<mat_graph->nvtxs;i++) {mat_graph->touched[i]=PETSC_FALSE;} 4957da1bb401SStefano Zampini nodes_touched=0; 495836e030ebSStefano Zampini ierr = PCBDDCGetDirichletBoundaries(pc,&used_IS);CHKERRQ(ierr); 4959da1bb401SStefano Zampini ierr = VecSet(pcis->vec2_N,0.0);CHKERRQ(ierr); 4960da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 4961da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 4962da1bb401SStefano Zampini if (used_IS) { 4963da1bb401SStefano Zampini ierr = ISGetSize(used_IS,&dirichlet_bsize);CHKERRQ(ierr); 4964f23aa3ddSBarry Smith if (dirichlet_bsize && matis->pure_neumann) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Dirichlet boundaries are intended to be used with matrices with zeroed rows!\n"); 4965da1bb401SStefano Zampini ierr = ISGetIndices(used_IS,&dirichlet_nodes);CHKERRQ(ierr); 4966da1bb401SStefano Zampini for (i=0;i<dirichlet_bsize;i++) { 4967da1bb401SStefano Zampini iindex=dirichlet_nodes[i]; 4968da1bb401SStefano Zampini if (mat_graph->count[iindex] && !mat_graph->touched[iindex]) { 4969f23aa3ddSBarry Smith if (array[iindex]>0.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"BDDC cannot have nodes which are marked as Neumann and Dirichlet at the same time! Wrong node %d\n",iindex); 4970da1bb401SStefano Zampini mat_graph->touched[iindex]=PETSC_TRUE; 4971da1bb401SStefano Zampini mat_graph->where[iindex]=0; 4972da1bb401SStefano Zampini nodes_touched++; 4973da1bb401SStefano Zampini array2[iindex]=array2[iindex]+1.0; 4974da1bb401SStefano Zampini } 4975da1bb401SStefano Zampini } 4976da1bb401SStefano Zampini ierr = ISRestoreIndices(used_IS,&dirichlet_nodes);CHKERRQ(ierr); 4977da1bb401SStefano Zampini } 4978da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 4979da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 4980da1bb401SStefano Zampini /* Check consistency of Dirichlet nodes */ 4981da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 4982da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4983da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4984da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4985da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4986da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4987da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4988da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec2_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4989da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec2_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4990da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4991da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4992da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 4993da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 499436e030ebSStefano Zampini if (used_IS) { 499536e030ebSStefano Zampini ierr = ISGetSize(used_IS,&dirichlet_bsize);CHKERRQ(ierr); 499636e030ebSStefano Zampini ierr = ISGetIndices(used_IS,&dirichlet_nodes);CHKERRQ(ierr); 49973b03a366Sstefano_zampini for (i=0;i<dirichlet_bsize;i++) { 4998da1bb401SStefano Zampini iindex=dirichlet_nodes[i]; 4999da1bb401SStefano Zampini if (array[iindex]>1.0 && array[iindex]!=array2[iindex]) { 5000da1bb401SStefano Zampini SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Dirichlet nodes provided to BDDC must be consistent among neighbours!\nNode %d: number of sharing subdomains %d != number of subdomains for which it is a neumann node %d\n",iindex,(PetscInt)array[iindex],(PetscInt)array2[iindex]); 5001da1bb401SStefano Zampini } 50023b03a366Sstefano_zampini } 500336e030ebSStefano Zampini ierr = ISRestoreIndices(used_IS,&dirichlet_nodes);CHKERRQ(ierr); 50043b03a366Sstefano_zampini } 5005da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5006da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5007da1bb401SStefano Zampini 50080c7d97c5SJed Brown for (i=0;i<mat_graph->nvtxs;i++) { 50093b03a366Sstefano_zampini if (!mat_graph->count[i]) { /* interior nodes */ 50100c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 50110c7d97c5SJed Brown mat_graph->where[i]=0; 50120c7d97c5SJed Brown nodes_touched++; 50130c7d97c5SJed Brown } 50140c7d97c5SJed Brown } 50150c7d97c5SJed Brown mat_graph->ncmps = 0; 5016da1bb401SStefano Zampini i=0; 50170c7d97c5SJed Brown while (nodes_touched<mat_graph->nvtxs) { 5018a0ba757dSStefano Zampini /* find first untouched node in local ordering */ 50190c7d97c5SJed Brown while (mat_graph->touched[i]) i++; 50200c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 5021a0ba757dSStefano Zampini mat_graph->where[i]=where_values; 50220c7d97c5SJed Brown nodes_touched++; 5023a0ba757dSStefano Zampini /* now find all other nodes having the same set of sharing subdomains */ 50240c7d97c5SJed Brown for (j=i+1;j<mat_graph->nvtxs;j++) { 5025a0ba757dSStefano Zampini /* check for same number of sharing subdomains and dof number */ 5026da1bb401SStefano Zampini if (!mat_graph->touched[j] && mat_graph->count[i]==mat_graph->count[j] && mat_graph->which_dof[i] == mat_graph->which_dof[j]) { 5027a0ba757dSStefano Zampini /* check for same set of sharing subdomains */ 50280c7d97c5SJed Brown same_set=PETSC_TRUE; 50290c7d97c5SJed Brown for (k=0;k<mat_graph->count[j];k++) { 5030da1bb401SStefano Zampini if (mat_graph->neighbours_set[i][k]!=mat_graph->neighbours_set[j][k]) { 50310c7d97c5SJed Brown same_set=PETSC_FALSE; 50320c7d97c5SJed Brown } 50330c7d97c5SJed Brown } 5034a0ba757dSStefano Zampini /* I found a friend of mine */ 50350c7d97c5SJed Brown if (same_set) { 5036a0ba757dSStefano Zampini mat_graph->where[j]=where_values; 50370c7d97c5SJed Brown mat_graph->touched[j]=PETSC_TRUE; 50380c7d97c5SJed Brown nodes_touched++; 50390c7d97c5SJed Brown } 50400c7d97c5SJed Brown } 50410c7d97c5SJed Brown } 5042a0ba757dSStefano Zampini where_values++; 50430c7d97c5SJed Brown } 5044a0ba757dSStefano Zampini where_values--; if (where_values<0) where_values=0; 5045a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscMPIInt),&mat_graph->where_ncmps);CHKERRQ(ierr); 5046a0ba757dSStefano Zampini /* Find connected components defined on the shared interface */ 5047a0ba757dSStefano Zampini if (where_values) { 5048a0ba757dSStefano Zampini ierr = PCBDDCFindConnectedComponents(mat_graph, where_values); 5049a0ba757dSStefano Zampini } 5050a929c220SStefano Zampini ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt),&queue_in_global_numbering);CHKERRQ(ierr); 5051a0ba757dSStefano Zampini /* check consistency of connected components among neighbouring subdomains -> it adapt them in case it is needed */ 5052a0ba757dSStefano Zampini for (i=0;i<where_values;i++) { 50537cf533a6SStefano Zampini /* We are not sure that on a given subset of the local interface, 50547cf533a6SStefano Zampini two connected components will be the same among sharing subdomains */ 50553b03a366Sstefano_zampini if (mat_graph->where_ncmps[i]>1) { 5056a0ba757dSStefano Zampini adapt_interface=1; 5057a0ba757dSStefano Zampini break; 5058a0ba757dSStefano Zampini } 5059a0ba757dSStefano Zampini } 5060a0ba757dSStefano Zampini ierr = MPI_Allreduce(&adapt_interface,&adapt_interface_reduced,1,MPIU_INT,MPI_LOR,interface_comm);CHKERRQ(ierr); 5061da1bb401SStefano Zampini if (pcbddc->dbg_flag && adapt_interface_reduced) { 5062d8923723SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Adapting interface\n");CHKERRQ(ierr); 5063da1bb401SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 5064da1bb401SStefano Zampini } 5065a0ba757dSStefano Zampini if (where_values && adapt_interface_reduced) { 5066a0ba757dSStefano Zampini PetscInt sum_requests=0,my_rank; 5067a0ba757dSStefano Zampini PetscInt buffer_size,start_of_recv,size_of_recv,start_of_send; 5068a0ba757dSStefano Zampini PetscInt temp_buffer_size,ins_val,global_where_counter; 5069a0ba757dSStefano Zampini PetscInt *cum_recv_counts; 5070a0ba757dSStefano Zampini PetscInt *where_to_nodes_indices; 5071a0ba757dSStefano Zampini PetscInt *petsc_buffer; 5072a0ba757dSStefano Zampini PetscMPIInt *recv_buffer; 5073a0ba757dSStefano Zampini PetscMPIInt *recv_buffer_where; 5074a0ba757dSStefano Zampini PetscMPIInt *send_buffer; 5075a0ba757dSStefano Zampini PetscMPIInt size_of_send; 5076a0ba757dSStefano Zampini PetscInt *sizes_of_sends; 5077a0ba757dSStefano Zampini MPI_Request *send_requests; 5078a0ba757dSStefano Zampini MPI_Request *recv_requests; 5079a0ba757dSStefano Zampini PetscInt *where_cc_adapt; 5080a0ba757dSStefano Zampini PetscInt **temp_buffer; 5081a0ba757dSStefano Zampini PetscInt *nodes_to_temp_buffer_indices; 5082a0ba757dSStefano Zampini PetscInt *add_to_where; 50837cf533a6SStefano Zampini PetscInt *aux_new_xadj,*new_xadj,*new_adjncy; 5084a0ba757dSStefano Zampini 50857cf533a6SStefano Zampini /* Retrict adjacency graph using information from connected components */ 50867cf533a6SStefano Zampini ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt),&aux_new_xadj);CHKERRQ(ierr); 50877cf533a6SStefano Zampini for (i=0;i<mat_graph->nvtxs;i++) { 50887cf533a6SStefano Zampini aux_new_xadj[i]=1; 50897cf533a6SStefano Zampini } 50907cf533a6SStefano Zampini for (i=0;i<mat_graph->ncmps;i++) { 50917cf533a6SStefano Zampini k = mat_graph->cptr[i+1]-mat_graph->cptr[i]; 50927cf533a6SStefano Zampini for (j=0;j<k;j++) { 50937cf533a6SStefano Zampini aux_new_xadj[mat_graph->queue[mat_graph->cptr[i]+j]]=k; 50947cf533a6SStefano Zampini } 50957cf533a6SStefano Zampini } 50967cf533a6SStefano Zampini j = 0; 50977cf533a6SStefano Zampini for (i=0;i<mat_graph->nvtxs;i++) { 50987cf533a6SStefano Zampini j += aux_new_xadj[i]; 50997cf533a6SStefano Zampini } 51007cf533a6SStefano Zampini ierr = PetscMalloc((mat_graph->nvtxs+1)*sizeof(PetscInt),&new_xadj);CHKERRQ(ierr); 51017cf533a6SStefano Zampini ierr = PetscMalloc(j*sizeof(PetscInt),&new_adjncy);CHKERRQ(ierr); 51027cf533a6SStefano Zampini new_xadj[0]=0; 51037cf533a6SStefano Zampini for (i=0;i<mat_graph->nvtxs;i++) { 51047cf533a6SStefano Zampini new_xadj[i+1]=new_xadj[i]+aux_new_xadj[i]; 51057cf533a6SStefano Zampini if (aux_new_xadj[i]==1) { 51067cf533a6SStefano Zampini new_adjncy[new_xadj[i]]=i; 51077cf533a6SStefano Zampini } 51087cf533a6SStefano Zampini } 5109354b9337SStefano Zampini ierr = PetscFree(aux_new_xadj);CHKERRQ(ierr); 51107cf533a6SStefano Zampini for (i=0;i<mat_graph->ncmps;i++) { 51117cf533a6SStefano Zampini k = mat_graph->cptr[i+1]-mat_graph->cptr[i]; 51127cf533a6SStefano Zampini for (j=0;j<k;j++) { 51137cf533a6SStefano Zampini ierr = PetscMemcpy(&new_adjncy[new_xadj[mat_graph->queue[mat_graph->cptr[i]+j]]],&mat_graph->queue[mat_graph->cptr[i]],k*sizeof(PetscInt));CHKERRQ(ierr); 51147cf533a6SStefano Zampini } 51157cf533a6SStefano Zampini } 51167cf533a6SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,mat_graph->nvtxs,new_xadj,new_adjncy,PETSC_OWN_POINTER);CHKERRQ(ierr); 51177cf533a6SStefano Zampini /* For consistency among neughbouring procs, I need to sort (by global ordering) each connected component */ 51187cf533a6SStefano Zampini for (i=0;i<mat_graph->ncmps;i++) { 51197cf533a6SStefano Zampini k = mat_graph->cptr[i+1]-mat_graph->cptr[i]; 51207cf533a6SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,k,&mat_graph->queue[mat_graph->cptr[i]],&queue_in_global_numbering[mat_graph->cptr[i]]);CHKERRQ(ierr); 51217cf533a6SStefano Zampini ierr = PetscSortIntWithArray(k,&queue_in_global_numbering[mat_graph->cptr[i]],&mat_graph->queue[mat_graph->cptr[i]]);CHKERRQ(ierr); 51227cf533a6SStefano Zampini } 51237cf533a6SStefano Zampini /* allocate some space */ 5124a0ba757dSStefano Zampini ierr = MPI_Comm_rank(interface_comm,&my_rank);CHKERRQ(ierr); 5125a0ba757dSStefano Zampini ierr = PetscMalloc((where_values+1)*sizeof(PetscInt),&cum_recv_counts);CHKERRQ(ierr); 5126a0ba757dSStefano Zampini ierr = PetscMemzero(cum_recv_counts,(where_values+1)*sizeof(PetscInt));CHKERRQ(ierr); 5127a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&where_to_nodes_indices);CHKERRQ(ierr); 5128a0ba757dSStefano Zampini /* first count how many neighbours per connected component I will receive from */ 5129a0ba757dSStefano Zampini cum_recv_counts[0]=0; 5130a0ba757dSStefano Zampini for (i=1;i<where_values+1;i++) { 5131a0ba757dSStefano Zampini j=0; 5132d8923723SStefano Zampini while (mat_graph->where[j] != i) { j++; } 5133a0ba757dSStefano Zampini where_to_nodes_indices[i-1]=j; 5134da1bb401SStefano Zampini if (mat_graph->neighbours_set[j][0]!=-1) { cum_recv_counts[i]=cum_recv_counts[i-1]+mat_graph->count[j]; } /* We don't want sends/recvs_to/from_self -> here I don't count myself */ 51353b03a366Sstefano_zampini else { cum_recv_counts[i]=cum_recv_counts[i-1]+mat_graph->count[j]-1; } 5136a0ba757dSStefano Zampini } 5137a0ba757dSStefano Zampini ierr = PetscMalloc(2*cum_recv_counts[where_values]*sizeof(PetscMPIInt),&recv_buffer_where);CHKERRQ(ierr); 5138a0ba757dSStefano Zampini ierr = PetscMalloc(cum_recv_counts[where_values]*sizeof(MPI_Request),&send_requests);CHKERRQ(ierr); 5139a0ba757dSStefano Zampini ierr = PetscMalloc(cum_recv_counts[where_values]*sizeof(MPI_Request),&recv_requests);CHKERRQ(ierr); 5140a0ba757dSStefano Zampini for (i=0;i<cum_recv_counts[where_values];i++) { 5141a0ba757dSStefano Zampini send_requests[i]=MPI_REQUEST_NULL; 5142a0ba757dSStefano Zampini recv_requests[i]=MPI_REQUEST_NULL; 5143a0ba757dSStefano Zampini } 5144a0ba757dSStefano Zampini /* exchange with my neighbours the number of my connected components on the shared interface */ 5145a0ba757dSStefano Zampini for (i=0;i<where_values;i++) { 5146a0ba757dSStefano Zampini j=where_to_nodes_indices[i]; 5147da1bb401SStefano Zampini k = (mat_graph->neighbours_set[j][0] == -1 ? 1 : 0); 5148a0ba757dSStefano Zampini for (;k<mat_graph->count[j];k++) { 5149da1bb401SStefano Zampini ierr = MPI_Isend(&mat_graph->where_ncmps[i],1,MPIU_INT,mat_graph->neighbours_set[j][k],(my_rank+1)*mat_graph->count[j],interface_comm,&send_requests[sum_requests]);CHKERRQ(ierr); 5150da1bb401SStefano Zampini ierr = MPI_Irecv(&recv_buffer_where[sum_requests],1,MPIU_INT,mat_graph->neighbours_set[j][k],(mat_graph->neighbours_set[j][k]+1)*mat_graph->count[j],interface_comm,&recv_requests[sum_requests]);CHKERRQ(ierr); 5151a0ba757dSStefano Zampini sum_requests++; 5152a0ba757dSStefano Zampini } 5153a0ba757dSStefano Zampini } 5154a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5155a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5156a0ba757dSStefano Zampini /* determine the connected component I need to adapt */ 5157a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&where_cc_adapt);CHKERRQ(ierr); 5158a0ba757dSStefano Zampini ierr = PetscMemzero(where_cc_adapt,where_values*sizeof(PetscInt));CHKERRQ(ierr); 5159a0ba757dSStefano Zampini for (i=0;i<where_values;i++) { 5160a0ba757dSStefano Zampini for (j=cum_recv_counts[i];j<cum_recv_counts[i+1];j++) { 51613b03a366Sstefano_zampini /* The first condition is natural (i.e someone has a different number of cc than me), the second one is just to be safe */ 51623b03a366Sstefano_zampini if (mat_graph->where_ncmps[i]!=recv_buffer_where[j] || mat_graph->where_ncmps[i] > 1) { 5163a0ba757dSStefano Zampini where_cc_adapt[i]=PETSC_TRUE; 5164a0ba757dSStefano Zampini break; 5165a0ba757dSStefano Zampini } 5166a0ba757dSStefano Zampini } 5167a0ba757dSStefano Zampini } 5168d8923723SStefano Zampini buffer_size = 0; 5169d8923723SStefano Zampini for (i=0;i<where_values;i++) { 5170d8923723SStefano Zampini if (where_cc_adapt[i]) { 5171d8923723SStefano Zampini for (j=i;j<mat_graph->ncmps;j++) { 5172d8923723SStefano Zampini if (mat_graph->where[mat_graph->queue[mat_graph->cptr[j]]] == i+1) { /* WARNING -> where values goes from 1 to where_values included */ 5173d8923723SStefano Zampini buffer_size += 1 + mat_graph->cptr[j+1]-mat_graph->cptr[j]; 5174d8923723SStefano Zampini } 5175d8923723SStefano Zampini } 5176d8923723SStefano Zampini } 5177d8923723SStefano Zampini } 5178d8923723SStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 5179a0ba757dSStefano Zampini /* now get from neighbours their ccs (in global numbering) and adapt them (in case it is needed) */ 5180a0ba757dSStefano Zampini /* first determine how much data to send (size of each queue plus the global indices) and communicate it to neighbours */ 5181a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&sizes_of_sends);CHKERRQ(ierr); 5182a0ba757dSStefano Zampini ierr = PetscMemzero(sizes_of_sends,where_values*sizeof(PetscInt));CHKERRQ(ierr); 5183a0ba757dSStefano Zampini sum_requests=0; 5184a0ba757dSStefano Zampini start_of_send=0; 5185a0ba757dSStefano Zampini start_of_recv=cum_recv_counts[where_values]; 5186a0ba757dSStefano Zampini for (i=0;i<where_values;i++) { 5187a0ba757dSStefano Zampini if (where_cc_adapt[i]) { 5188a0ba757dSStefano Zampini size_of_send=0; 5189a0ba757dSStefano Zampini for (j=i;j<mat_graph->ncmps;j++) { 5190a0ba757dSStefano Zampini if (mat_graph->where[mat_graph->queue[mat_graph->cptr[j]]] == i+1) { /* WARNING -> where values goes from 1 to where_values included */ 5191a0ba757dSStefano Zampini send_buffer[start_of_send+size_of_send]=mat_graph->cptr[j+1]-mat_graph->cptr[j]; 5192a0ba757dSStefano Zampini size_of_send+=1; 5193a0ba757dSStefano Zampini for (k=0;k<mat_graph->cptr[j+1]-mat_graph->cptr[j];k++) { 5194a0ba757dSStefano Zampini send_buffer[start_of_send+size_of_send+k]=queue_in_global_numbering[mat_graph->cptr[j]+k]; 5195a0ba757dSStefano Zampini } 5196a0ba757dSStefano Zampini size_of_send=size_of_send+mat_graph->cptr[j+1]-mat_graph->cptr[j]; 5197a0ba757dSStefano Zampini } 5198a0ba757dSStefano Zampini } 5199a0ba757dSStefano Zampini j = where_to_nodes_indices[i]; 5200da1bb401SStefano Zampini k = (mat_graph->neighbours_set[j][0] == -1 ? 1 : 0); 520111d8f4c2SStefano Zampini sizes_of_sends[i]=size_of_send; 5202a0ba757dSStefano Zampini for (;k<mat_graph->count[j];k++) { 520311d8f4c2SStefano Zampini ierr = MPI_Isend(&sizes_of_sends[i],1,MPIU_INT,mat_graph->neighbours_set[j][k],(my_rank+1)*mat_graph->count[j],interface_comm,&send_requests[sum_requests]);CHKERRQ(ierr); 5204da1bb401SStefano Zampini ierr = MPI_Irecv(&recv_buffer_where[sum_requests+start_of_recv],1,MPIU_INT,mat_graph->neighbours_set[j][k],(mat_graph->neighbours_set[j][k]+1)*mat_graph->count[j],interface_comm,&recv_requests[sum_requests]);CHKERRQ(ierr); 5205a0ba757dSStefano Zampini sum_requests++; 5206a0ba757dSStefano Zampini } 5207a0ba757dSStefano Zampini start_of_send+=size_of_send; 5208a0ba757dSStefano Zampini } 5209a0ba757dSStefano Zampini } 5210a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5211a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5212a0ba757dSStefano Zampini buffer_size=0; 5213a0ba757dSStefano Zampini for (k=0;k<sum_requests;k++) { buffer_size+=recv_buffer_where[start_of_recv+k]; } 5214a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscMPIInt),&recv_buffer);CHKERRQ(ierr); 5215a0ba757dSStefano Zampini /* now exchange the data */ 5216a0ba757dSStefano Zampini start_of_recv=0; 5217a0ba757dSStefano Zampini start_of_send=0; 5218a0ba757dSStefano Zampini sum_requests=0; 5219a0ba757dSStefano Zampini for (i=0;i<where_values;i++) { 5220a0ba757dSStefano Zampini if (where_cc_adapt[i]) { 5221a0ba757dSStefano Zampini size_of_send = sizes_of_sends[i]; 5222a0ba757dSStefano Zampini j = where_to_nodes_indices[i]; 5223da1bb401SStefano Zampini k = (mat_graph->neighbours_set[j][0] == -1 ? 1 : 0); 5224a0ba757dSStefano Zampini for (;k<mat_graph->count[j];k++) { 5225da1bb401SStefano Zampini ierr = MPI_Isend(&send_buffer[start_of_send],size_of_send,MPIU_INT,mat_graph->neighbours_set[j][k],(my_rank+1)*mat_graph->count[j],interface_comm,&send_requests[sum_requests]);CHKERRQ(ierr); 5226a0ba757dSStefano Zampini size_of_recv=recv_buffer_where[cum_recv_counts[where_values]+sum_requests]; 5227da1bb401SStefano Zampini ierr = MPI_Irecv(&recv_buffer[start_of_recv],size_of_recv,MPIU_INT,mat_graph->neighbours_set[j][k],(mat_graph->neighbours_set[j][k]+1)*mat_graph->count[j],interface_comm,&recv_requests[sum_requests]);CHKERRQ(ierr); 5228a0ba757dSStefano Zampini start_of_recv+=size_of_recv; 5229a0ba757dSStefano Zampini sum_requests++; 5230a0ba757dSStefano Zampini } 5231a0ba757dSStefano Zampini start_of_send+=size_of_send; 5232a0ba757dSStefano Zampini } 5233a0ba757dSStefano Zampini } 5234a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5235a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5236a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscInt),&petsc_buffer);CHKERRQ(ierr); 5237a0ba757dSStefano Zampini for (k=0;k<start_of_recv;k++) { petsc_buffer[k]=(PetscInt)recv_buffer[k]; } 5238a0ba757dSStefano Zampini for (j=0;j<buffer_size;) { 5239a0ba757dSStefano Zampini ierr = ISGlobalToLocalMappingApply(matis->mapping,IS_GTOLM_MASK,petsc_buffer[j],&petsc_buffer[j+1],&petsc_buffer[j],&petsc_buffer[j+1]);CHKERRQ(ierr); 5240a0ba757dSStefano Zampini k=petsc_buffer[j]+1; 5241a0ba757dSStefano Zampini j+=k; 5242a0ba757dSStefano Zampini } 5243a0ba757dSStefano Zampini sum_requests=cum_recv_counts[where_values]; 5244a0ba757dSStefano Zampini start_of_recv=0; 5245a0ba757dSStefano Zampini ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt),&nodes_to_temp_buffer_indices);CHKERRQ(ierr); 5246a0ba757dSStefano Zampini global_where_counter=0; 5247a0ba757dSStefano Zampini for (i=0;i<where_values;i++) { 5248a0ba757dSStefano Zampini if (where_cc_adapt[i]) { 5249a0ba757dSStefano Zampini temp_buffer_size=0; 5250a0ba757dSStefano Zampini /* find nodes on the shared interface we need to adapt */ 5251a0ba757dSStefano Zampini for (j=0;j<mat_graph->nvtxs;j++) { 5252a0ba757dSStefano Zampini if (mat_graph->where[j]==i+1) { 5253a0ba757dSStefano Zampini nodes_to_temp_buffer_indices[j]=temp_buffer_size; 5254a0ba757dSStefano Zampini temp_buffer_size++; 5255a0ba757dSStefano Zampini } else { 5256a0ba757dSStefano Zampini nodes_to_temp_buffer_indices[j]=-1; 5257a0ba757dSStefano Zampini } 5258a0ba757dSStefano Zampini } 5259a0ba757dSStefano Zampini /* allocate some temporary space */ 5260a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*sizeof(PetscInt*),&temp_buffer);CHKERRQ(ierr); 5261a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*(cum_recv_counts[i+1]-cum_recv_counts[i])*sizeof(PetscInt),&temp_buffer[0]);CHKERRQ(ierr); 5262a0ba757dSStefano Zampini ierr = PetscMemzero(temp_buffer[0],temp_buffer_size*(cum_recv_counts[i+1]-cum_recv_counts[i])*sizeof(PetscInt));CHKERRQ(ierr); 5263a0ba757dSStefano Zampini for (j=1;j<temp_buffer_size;j++) { 5264a0ba757dSStefano Zampini temp_buffer[j]=temp_buffer[j-1]+cum_recv_counts[i+1]-cum_recv_counts[i]; 5265a0ba757dSStefano Zampini } 5266a0ba757dSStefano Zampini /* analyze contributions from neighbouring subdomains for i-th conn comp 5267a0ba757dSStefano Zampini temp buffer structure: 5268a0ba757dSStefano Zampini supposing part of the interface has dimension 5 (global nodes 0,1,2,3,4) 5269a0ba757dSStefano Zampini 3 neighs procs with structured connected components: 5270a0ba757dSStefano Zampini neigh 0: [0 1 4], [2 3]; (2 connected components) 5271a0ba757dSStefano Zampini neigh 1: [0 1], [2 3 4]; (2 connected components) 5272a0ba757dSStefano Zampini neigh 2: [0 4], [1], [2 3]; (3 connected components) 5273a0ba757dSStefano Zampini tempbuffer (row-oriented) should be filled as: 5274a0ba757dSStefano Zampini [ 0, 0, 0; 5275a0ba757dSStefano Zampini 0, 0, 1; 5276a0ba757dSStefano Zampini 1, 1, 2; 5277a0ba757dSStefano Zampini 1, 1, 2; 5278a0ba757dSStefano Zampini 0, 1, 0; ]; 5279a0ba757dSStefano Zampini This way we can simply recover the resulting structure account for possible intersections of ccs among neighs. 5280a0ba757dSStefano Zampini The mat_graph->where array will be modified to reproduce the following 4 connected components [0], [1], [2 3], [4]; 5281a0ba757dSStefano Zampini */ 5282a0ba757dSStefano Zampini for (j=0;j<cum_recv_counts[i+1]-cum_recv_counts[i];j++) { 5283a0ba757dSStefano Zampini ins_val=0; 5284a0ba757dSStefano Zampini size_of_recv=recv_buffer_where[sum_requests]; /* total size of recv from neighs */ 5285a0ba757dSStefano Zampini for (buffer_size=0;buffer_size<size_of_recv;) { /* loop until all data from neighs has been taken into account */ 5286a0ba757dSStefano Zampini for (k=1;k<petsc_buffer[buffer_size+start_of_recv]+1;k++) { /* filling properly temp_buffer using data from a single recv */ 5287a0ba757dSStefano Zampini temp_buffer[ nodes_to_temp_buffer_indices[ petsc_buffer[ start_of_recv+buffer_size+k ] ] ][j]=ins_val; 5288a0ba757dSStefano Zampini } 5289a0ba757dSStefano Zampini buffer_size+=k; 5290a0ba757dSStefano Zampini ins_val++; 5291a0ba757dSStefano Zampini } 5292a0ba757dSStefano Zampini start_of_recv+=size_of_recv; 5293a0ba757dSStefano Zampini sum_requests++; 5294a0ba757dSStefano Zampini } 5295a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*sizeof(PetscInt),&add_to_where);CHKERRQ(ierr); 5296a0ba757dSStefano Zampini ierr = PetscMemzero(add_to_where,temp_buffer_size*sizeof(PetscInt));CHKERRQ(ierr); 5297a0ba757dSStefano Zampini for (j=0;j<temp_buffer_size;j++) { 5298a0ba757dSStefano Zampini if (!add_to_where[j]) { /* found a new cc */ 5299a0ba757dSStefano Zampini global_where_counter++; 5300a0ba757dSStefano Zampini add_to_where[j]=global_where_counter; 5301a0ba757dSStefano Zampini for (k=j+1;k<temp_buffer_size;k++) { /* check for other nodes in new cc */ 5302a0ba757dSStefano Zampini same_set=PETSC_TRUE; 5303a0ba757dSStefano Zampini for (s=0;s<cum_recv_counts[i+1]-cum_recv_counts[i];s++) { 5304a0ba757dSStefano Zampini if (temp_buffer[j][s]!=temp_buffer[k][s]) { 5305a0ba757dSStefano Zampini same_set=PETSC_FALSE; 5306a0ba757dSStefano Zampini break; 5307a0ba757dSStefano Zampini } 5308a0ba757dSStefano Zampini } 53092e8d2280SStefano Zampini if (same_set) { add_to_where[k]=global_where_counter; } 5310a0ba757dSStefano Zampini } 5311a0ba757dSStefano Zampini } 5312a0ba757dSStefano Zampini } 5313a0ba757dSStefano Zampini /* insert new data in where array */ 5314a0ba757dSStefano Zampini temp_buffer_size=0; 5315a0ba757dSStefano Zampini for (j=0;j<mat_graph->nvtxs;j++) { 5316a0ba757dSStefano Zampini if (mat_graph->where[j]==i+1) { 5317a0ba757dSStefano Zampini mat_graph->where[j]=where_values+add_to_where[temp_buffer_size]; 5318a0ba757dSStefano Zampini temp_buffer_size++; 5319a0ba757dSStefano Zampini } 5320a0ba757dSStefano Zampini } 5321a0ba757dSStefano Zampini ierr = PetscFree(temp_buffer[0]);CHKERRQ(ierr); 5322a0ba757dSStefano Zampini ierr = PetscFree(temp_buffer);CHKERRQ(ierr); 5323a0ba757dSStefano Zampini ierr = PetscFree(add_to_where);CHKERRQ(ierr); 5324a0ba757dSStefano Zampini } 5325a0ba757dSStefano Zampini } 5326a0ba757dSStefano Zampini ierr = PetscFree(nodes_to_temp_buffer_indices);CHKERRQ(ierr); 5327a0ba757dSStefano Zampini ierr = PetscFree(sizes_of_sends);CHKERRQ(ierr); 5328a0ba757dSStefano Zampini ierr = PetscFree(send_requests);CHKERRQ(ierr); 5329a0ba757dSStefano Zampini ierr = PetscFree(recv_requests);CHKERRQ(ierr); 5330a0ba757dSStefano Zampini ierr = PetscFree(petsc_buffer);CHKERRQ(ierr); 5331a0ba757dSStefano Zampini ierr = PetscFree(recv_buffer);CHKERRQ(ierr); 5332a0ba757dSStefano Zampini ierr = PetscFree(recv_buffer_where);CHKERRQ(ierr); 5333a0ba757dSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 5334a0ba757dSStefano Zampini ierr = PetscFree(cum_recv_counts);CHKERRQ(ierr); 5335a0ba757dSStefano Zampini ierr = PetscFree(where_to_nodes_indices);CHKERRQ(ierr); 533623d4d1a5SStefano Zampini ierr = PetscFree(where_cc_adapt);CHKERRQ(ierr); 5337a0ba757dSStefano Zampini /* We are ready to evaluate consistent connected components on each part of the shared interface */ 5338a0ba757dSStefano Zampini if (global_where_counter) { 5339a0ba757dSStefano Zampini for (i=0;i<mat_graph->nvtxs;i++) { mat_graph->touched[i]=PETSC_FALSE; } 5340a0ba757dSStefano Zampini global_where_counter=0; 5341a0ba757dSStefano Zampini for (i=0;i<mat_graph->nvtxs;i++) { 5342a0ba757dSStefano Zampini if (mat_graph->where[i] && !mat_graph->touched[i]) { 5343a0ba757dSStefano Zampini global_where_counter++; 5344a0ba757dSStefano Zampini for (j=i+1;j<mat_graph->nvtxs;j++) { 5345a0ba757dSStefano Zampini if (!mat_graph->touched[j] && mat_graph->where[j]==mat_graph->where[i]) { 5346a0ba757dSStefano Zampini mat_graph->where[j]=global_where_counter; 5347a0ba757dSStefano Zampini mat_graph->touched[j]=PETSC_TRUE; 5348a0ba757dSStefano Zampini } 5349a0ba757dSStefano Zampini } 5350a0ba757dSStefano Zampini mat_graph->where[i]=global_where_counter; 5351a0ba757dSStefano Zampini mat_graph->touched[i]=PETSC_TRUE; 5352a0ba757dSStefano Zampini } 5353a0ba757dSStefano Zampini } 5354a0ba757dSStefano Zampini where_values=global_where_counter; 5355a0ba757dSStefano Zampini } 5356a0ba757dSStefano Zampini if (global_where_counter) { 5357a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->cptr,(mat_graph->nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 5358a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->queue,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 5359a0ba757dSStefano Zampini ierr = PetscFree(mat_graph->where_ncmps);CHKERRQ(ierr); 5360a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscMPIInt),&mat_graph->where_ncmps);CHKERRQ(ierr); 5361a0ba757dSStefano Zampini ierr = PCBDDCFindConnectedComponents(mat_graph, where_values); 5362a0ba757dSStefano Zampini } 53633b03a366Sstefano_zampini } /* Finished adapting interface */ 5364a929c220SStefano Zampini /* For consistency among neughbouring procs, I need to sort (by global ordering) each connected component */ 5365a929c220SStefano Zampini for (i=0;i<mat_graph->ncmps;i++) { 5366a929c220SStefano Zampini k = mat_graph->cptr[i+1]-mat_graph->cptr[i]; 5367a929c220SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,k,&mat_graph->queue[mat_graph->cptr[i]],&queue_in_global_numbering[mat_graph->cptr[i]]);CHKERRQ(ierr); 5368a929c220SStefano Zampini ierr = PetscSortIntWithArray(k,&queue_in_global_numbering[mat_graph->cptr[i]],&mat_graph->queue[mat_graph->cptr[i]]);CHKERRQ(ierr); 5369a929c220SStefano Zampini } 5370a929c220SStefano Zampini 53710c7d97c5SJed Brown PetscInt nfc=0; 53720c7d97c5SJed Brown PetscInt nec=0; 53730c7d97c5SJed Brown PetscInt nvc=0; 53743b03a366Sstefano_zampini PetscBool twodim_flag=PETSC_FALSE; 53750c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 53763b03a366Sstefano_zampini if (mat_graph->cptr[i+1]-mat_graph->cptr[i] > vertex_size) { 5377534831adSStefano Zampini if (mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]==1) { /* 1 neigh Neumann fake included */ 53780c7d97c5SJed Brown nfc++; 53793b03a366Sstefano_zampini } else { /* note that nec will be zero in 2d */ 53803b03a366Sstefano_zampini nec++; 53813b03a366Sstefano_zampini } 53820c7d97c5SJed Brown } else { 53833b03a366Sstefano_zampini nvc+=mat_graph->cptr[i+1]-mat_graph->cptr[i]; 53843b03a366Sstefano_zampini } 53853b03a366Sstefano_zampini } 53863b03a366Sstefano_zampini if (!nec) { /* we are in a 2d case -> no faces, only edges */ 53873b03a366Sstefano_zampini nec = nfc; 53883b03a366Sstefano_zampini nfc = 0; 53893b03a366Sstefano_zampini twodim_flag = PETSC_TRUE; 53903b03a366Sstefano_zampini } 53913972b0daSStefano Zampini /* allocate IS arrays for faces, edges. Vertices need a single index set. */ 53923972b0daSStefano Zampini k=0; 53933972b0daSStefano Zampini for (i=0; i<mat_graph->ncmps; i++) { 53943972b0daSStefano Zampini j=mat_graph->cptr[i+1]-mat_graph->cptr[i]; 53953972b0daSStefano Zampini if (j > k) { 53963972b0daSStefano Zampini k=j; 53973972b0daSStefano Zampini } 5398ba1573a8SStefano Zampini if (j<=vertex_size) { 5399ba1573a8SStefano Zampini k+=vertex_size; 5400ba1573a8SStefano Zampini } 54013972b0daSStefano Zampini } 54023972b0daSStefano Zampini ierr = PetscMalloc(k*sizeof(PetscInt),&auxis);CHKERRQ(ierr); 54033b03a366Sstefano_zampini if (!pcbddc->vertices_flag && !pcbddc->edges_flag) { 54043b03a366Sstefano_zampini ierr = PetscMalloc(nfc*sizeof(IS),&pcbddc->ISForFaces);CHKERRQ(ierr); 54053b03a366Sstefano_zampini use_faces=PETSC_TRUE; 54063b03a366Sstefano_zampini } 54073b03a366Sstefano_zampini if (!pcbddc->vertices_flag && !pcbddc->faces_flag) { 54083b03a366Sstefano_zampini ierr = PetscMalloc(nec*sizeof(IS),&pcbddc->ISForEdges);CHKERRQ(ierr); 54093b03a366Sstefano_zampini use_edges=PETSC_TRUE; 54103b03a366Sstefano_zampini } 54113b03a366Sstefano_zampini nfc=0; 54123b03a366Sstefano_zampini nec=0; 54133b03a366Sstefano_zampini for (i=0; i<mat_graph->ncmps; i++) { 54143b03a366Sstefano_zampini if (mat_graph->cptr[i+1]-mat_graph->cptr[i] > vertex_size) { 54153b03a366Sstefano_zampini for (j=0;j<mat_graph->cptr[i+1]-mat_graph->cptr[i];j++) { 54163972b0daSStefano Zampini auxis[j]=mat_graph->queue[mat_graph->cptr[i]+j]; 54173b03a366Sstefano_zampini } 54183b03a366Sstefano_zampini if (mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]==1) { 54193b03a366Sstefano_zampini if (twodim_flag) { 54203b03a366Sstefano_zampini if (use_edges) { 54213972b0daSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,auxis,PETSC_COPY_VALUES,&pcbddc->ISForEdges[nec]);CHKERRQ(ierr); 54223b03a366Sstefano_zampini nec++; 54233b03a366Sstefano_zampini } 54243b03a366Sstefano_zampini } else { 54253b03a366Sstefano_zampini if (use_faces) { 54263972b0daSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,auxis,PETSC_COPY_VALUES,&pcbddc->ISForFaces[nfc]);CHKERRQ(ierr); 54273b03a366Sstefano_zampini nfc++; 54283b03a366Sstefano_zampini } 54293b03a366Sstefano_zampini } 54303b03a366Sstefano_zampini } else { 54313b03a366Sstefano_zampini if (use_edges) { 54323972b0daSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,auxis,PETSC_COPY_VALUES,&pcbddc->ISForEdges[nec]);CHKERRQ(ierr); 54330c7d97c5SJed Brown nec++; 54340c7d97c5SJed Brown } 54350c7d97c5SJed Brown } 54360c7d97c5SJed Brown } 54373b03a366Sstefano_zampini } 54383b03a366Sstefano_zampini pcbddc->n_ISForFaces=nfc; 54393b03a366Sstefano_zampini pcbddc->n_ISForEdges=nec; 54403b03a366Sstefano_zampini nvc=0; 54410c7d97c5SJed Brown if (!pcbddc->constraints_flag) { 54423b03a366Sstefano_zampini for (i=0; i<mat_graph->ncmps; i++) { 54433b03a366Sstefano_zampini if (mat_graph->cptr[i+1]-mat_graph->cptr[i] <= vertex_size) { 54443b03a366Sstefano_zampini for (j=mat_graph->cptr[i];j<mat_graph->cptr[i+1];j++) { 54453972b0daSStefano Zampini auxis[nvc]=mat_graph->queue[j]; 54460c7d97c5SJed Brown nvc++; 54470c7d97c5SJed Brown } 54480c7d97c5SJed Brown } 54490c7d97c5SJed Brown } 54500c7d97c5SJed Brown } 5451a0ba757dSStefano Zampini /* sort vertex set (by local ordering) */ 54523972b0daSStefano Zampini ierr = PetscSortInt(nvc,auxis);CHKERRQ(ierr); 54533972b0daSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nvc,auxis,PETSC_COPY_VALUES,&pcbddc->ISForVertices);CHKERRQ(ierr); 5454e269702eSStefano Zampini if (pcbddc->dbg_flag) { 5455d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 5456d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Details from PCBDDCManageLocalBoundaries for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5457d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Matrix graph has %d connected components", mat_graph->ncmps);CHKERRQ(ierr); 54580c7d97c5SJed Brown for (i=0;i<mat_graph->ncmps;i++) { 54593b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\nDetails for connected component number %02d: size %04d, count %01d. Nodes follow.\n", 54603b03a366Sstefano_zampini i,mat_graph->cptr[i+1]-mat_graph->cptr[i],mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]);CHKERRQ(ierr); 5461da1bb401SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"subdomains: "); 5462da1bb401SStefano Zampini for (j=0;j<mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]; j++) { 5463da1bb401SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d ",mat_graph->neighbours_set[mat_graph->queue[mat_graph->cptr[i]]][j]); 5464da1bb401SStefano Zampini } 5465da1bb401SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n"); 54660c7d97c5SJed Brown for (j=mat_graph->cptr[i]; j<mat_graph->cptr[i+1]; j++) { 5467a929c220SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d (%d), ",mat_graph->queue[j],queue_in_global_numbering[j]);CHKERRQ(ierr); 54680c7d97c5SJed Brown } 54690c7d97c5SJed Brown } 5470da1bb401SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n--------------------------------------------------------------\n");CHKERRQ(ierr); 54713b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local vertices\n",PetscGlobalRank,nvc);CHKERRQ(ierr); 54723b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local faces\n",PetscGlobalRank,nfc);CHKERRQ(ierr); 54733b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local edges\n",PetscGlobalRank,nec);CHKERRQ(ierr); 5474d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 54750c7d97c5SJed Brown } 54763972b0daSStefano Zampini ierr = PetscFree(auxis);CHKERRQ(ierr); 5477a929c220SStefano Zampini ierr = PetscFree(queue_in_global_numbering);CHKERRQ(ierr); 54780c7d97c5SJed Brown PetscFunctionReturn(0); 54790c7d97c5SJed Brown } 54800c7d97c5SJed Brown 54810c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 54820c7d97c5SJed Brown 54830c7d97c5SJed Brown /* The following code has been adapted from function IsConnectedSubdomain contained 5484da1bb401SStefano Zampini in source file contig.c of METIS library (version 5.0.1) 5485da1bb401SStefano Zampini It finds connected components of each partition labeled from 1 to n_dist */ 54860c7d97c5SJed Brown 54870c7d97c5SJed Brown #undef __FUNCT__ 54880c7d97c5SJed Brown #define __FUNCT__ "PCBDDCFindConnectedComponents" 54899c0446d6SStefano Zampini static PetscErrorCode PCBDDCFindConnectedComponents(PCBDDCGraph graph, PetscInt n_dist) 54900c7d97c5SJed Brown { 54910c7d97c5SJed Brown PetscInt i, j, k, nvtxs, first, last, nleft, ncmps,pid,cum_queue,n,ncmps_pid; 54920c7d97c5SJed Brown PetscInt *xadj, *adjncy, *where, *queue; 54930c7d97c5SJed Brown PetscInt *cptr; 54940c7d97c5SJed Brown PetscBool *touched; 54950c7d97c5SJed Brown 54960c7d97c5SJed Brown PetscFunctionBegin; 54970c7d97c5SJed Brown nvtxs = graph->nvtxs; 54980c7d97c5SJed Brown xadj = graph->xadj; 54990c7d97c5SJed Brown adjncy = graph->adjncy; 55000c7d97c5SJed Brown where = graph->where; 55010c7d97c5SJed Brown touched = graph->touched; 55020c7d97c5SJed Brown queue = graph->queue; 55030c7d97c5SJed Brown cptr = graph->cptr; 55040c7d97c5SJed Brown 55052e8d2280SStefano Zampini for (i=0; i<nvtxs; i++) { 55060c7d97c5SJed Brown touched[i] = PETSC_FALSE; 55072e8d2280SStefano Zampini } 55080c7d97c5SJed Brown 55090c7d97c5SJed Brown cum_queue=0; 55100c7d97c5SJed Brown ncmps=0; 55110c7d97c5SJed Brown 55120c7d97c5SJed Brown for (n=0; n<n_dist; n++) { 5513da1bb401SStefano Zampini pid = n+1; /* partition labeled by 0 is discarded */ 55140c7d97c5SJed Brown nleft = 0; 55150c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 55160c7d97c5SJed Brown if (where[i] == pid) 55170c7d97c5SJed Brown nleft++; 55180c7d97c5SJed Brown } 55190c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 55200c7d97c5SJed Brown if (where[i] == pid) 55210c7d97c5SJed Brown break; 55220c7d97c5SJed Brown } 55230c7d97c5SJed Brown touched[i] = PETSC_TRUE; 55240c7d97c5SJed Brown queue[cum_queue] = i; 55250c7d97c5SJed Brown first = 0; last = 1; 55260c7d97c5SJed Brown cptr[ncmps] = cum_queue; /* This actually points to queue */ 55270c7d97c5SJed Brown ncmps_pid = 0; 55280c7d97c5SJed Brown while (first != nleft) { 55290c7d97c5SJed Brown if (first == last) { /* Find another starting vertex */ 55300c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 55310c7d97c5SJed Brown ncmps_pid++; 55320c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 55330c7d97c5SJed Brown if (where[i] == pid && !touched[i]) 55340c7d97c5SJed Brown break; 55350c7d97c5SJed Brown } 55360c7d97c5SJed Brown queue[cum_queue+last] = i; 55370c7d97c5SJed Brown last++; 55380c7d97c5SJed Brown touched[i] = PETSC_TRUE; 55390c7d97c5SJed Brown } 55400c7d97c5SJed Brown i = queue[cum_queue+first]; 55410c7d97c5SJed Brown first++; 55420c7d97c5SJed Brown for (j=xadj[i]; j<xadj[i+1]; j++) { 55430c7d97c5SJed Brown k = adjncy[j]; 55440c7d97c5SJed Brown if (where[k] == pid && !touched[k]) { 55450c7d97c5SJed Brown queue[cum_queue+last] = k; 55460c7d97c5SJed Brown last++; 55470c7d97c5SJed Brown touched[k] = PETSC_TRUE; 55480c7d97c5SJed Brown } 55490c7d97c5SJed Brown } 55500c7d97c5SJed Brown } 55510c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 55520c7d97c5SJed Brown ncmps_pid++; 55530c7d97c5SJed Brown cum_queue=cptr[ncmps]; 5554a0ba757dSStefano Zampini graph->where_ncmps[n] = ncmps_pid; 55550c7d97c5SJed Brown } 55560c7d97c5SJed Brown graph->ncmps = ncmps; 55570c7d97c5SJed Brown 55580c7d97c5SJed Brown PetscFunctionReturn(0); 55590c7d97c5SJed Brown } 5560