153cdbc3dSStefano Zampini /* TODOLIST 2*3b03a366Sstefano_zampini Exact solvers: Solve local saddle point directly for very hard problems 3*3b03a366Sstefano_zampini Inexact solvers: global preconditioner application is ready, ask to developers (Jed?) on how to best implement Dohrmann's approach (PCSHELL?) 4a0ba757dSStefano Zampini change how to deal with the coarse problem (PCBDDCSetCoarseEnvironment): 5a0ba757dSStefano Zampini - mind the problem with coarsening_factor 6a0ba757dSStefano Zampini - simplify coarse problem structure -> PCBDDC or PCREDUDANT, nothing else -> same comm for all levels? 7a0ba757dSStefano Zampini - remove coarse enums and allow use of PCBDDCGetCoarseKSP 8a0ba757dSStefano Zampini - remove metis dependency -> use MatPartitioning for multilevel -> Assemble serial adjacency in ManageLocalBoundaries? 9*3b03a366Sstefano_zampini - Add levels' slot to bddc data structure and associated Set/Get functions 10a0ba757dSStefano Zampini code refactoring: 11a0ba757dSStefano Zampini - pick up better names for static functions 12*3b03a366Sstefano_zampini check log_summary for leaking (actually: 1 Vector per level ) 13a0ba757dSStefano Zampini change options structure: 14a0ba757dSStefano Zampini - insert BDDC into MG framework? 15a0ba757dSStefano Zampini provide other ops? Ask to developers 16a0ba757dSStefano Zampini remove all unused printf 17a0ba757dSStefano Zampini remove // commments and adhere to PETSc code requirements 18a0ba757dSStefano Zampini man pages 1953cdbc3dSStefano Zampini */ 200c7d97c5SJed Brown 2153cdbc3dSStefano Zampini /* ---------------------------------------------------------------------------------------------------------------------------------------------- 220c7d97c5SJed Brown Implementation of BDDC preconditioner based on: 230c7d97c5SJed Brown C. Dohrmann "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 2453cdbc3dSStefano Zampini ---------------------------------------------------------------------------------------------------------------------------------------------- */ 2553cdbc3dSStefano Zampini 2653cdbc3dSStefano Zampini #include "bddc.h" /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 27*3b03a366Sstefano_zampini #include <petscblaslapack.h> 280c7d97c5SJed Brown 290c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 300c7d97c5SJed Brown #undef __FUNCT__ 310c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC" 320c7d97c5SJed Brown PetscErrorCode PCSetFromOptions_BDDC(PC pc) 330c7d97c5SJed Brown { 340c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 350c7d97c5SJed Brown PetscErrorCode ierr; 360c7d97c5SJed Brown 370c7d97c5SJed Brown PetscFunctionBegin; 380c7d97c5SJed Brown ierr = PetscOptionsHead("BDDC options");CHKERRQ(ierr); 390c7d97c5SJed Brown /* Verbose debugging of main data structures */ 40e269702eSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_check_all" ,"Verbose (debugging) output for PCBDDC" ,"none",pcbddc->dbg_flag ,&pcbddc->dbg_flag ,PETSC_NULL);CHKERRQ(ierr); 410c7d97c5SJed Brown /* Some customization for default primal space */ 420c7d97c5SJed Brown ierr = PetscOptionsBool("-pc_bddc_vertices_only" ,"Use vertices only in coarse space (i.e. discard constraints)","none",pcbddc->vertices_flag ,&pcbddc->vertices_flag ,PETSC_NULL);CHKERRQ(ierr); 430c7d97c5SJed Brown ierr = PetscOptionsBool("-pc_bddc_constraints_only","Use constraints only in coarse space (i.e. discard vertices)","none",pcbddc->constraints_flag,&pcbddc->constraints_flag,PETSC_NULL);CHKERRQ(ierr); 440c7d97c5SJed Brown ierr = PetscOptionsBool("-pc_bddc_faces_only" ,"Use faces only in coarse space (i.e. discard edges)" ,"none",pcbddc->faces_flag ,&pcbddc->faces_flag ,PETSC_NULL);CHKERRQ(ierr); 450c7d97c5SJed Brown ierr = PetscOptionsBool("-pc_bddc_edges_only" ,"Use edges only in coarse space (i.e. discard faces)" ,"none",pcbddc->edges_flag ,&pcbddc->edges_flag ,PETSC_NULL);CHKERRQ(ierr); 460c7d97c5SJed Brown /* Coarse solver context */ 470c7d97c5SJed Brown static const char *avail_coarse_problems[] = {"sequential","replicated","parallel","multilevel",""}; //order of choiches depends on ENUM defined in bddc.h 480c7d97c5SJed 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); 490c7d97c5SJed Brown /* Two different application of BDDC to the whole set of dofs, internal and interface */ 500c7d97c5SJed Brown ierr = PetscOptionsBool("-pc_bddc_switch_preconditioning_type","Switch between M_2 (default) and M_3 preconditioners (as defined by Dohrmann)","none",pcbddc->prec_type,&pcbddc->prec_type,PETSC_NULL);CHKERRQ(ierr); 510c7d97c5SJed 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); 520c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 530c7d97c5SJed Brown PetscFunctionReturn(0); 540c7d97c5SJed Brown } 550c7d97c5SJed Brown 560c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 570c7d97c5SJed Brown EXTERN_C_BEGIN 580c7d97c5SJed Brown #undef __FUNCT__ 590c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType_BDDC" 6053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetCoarseProblemType_BDDC(PC pc, CoarseProblemType CPT) 610c7d97c5SJed Brown { 620c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 630c7d97c5SJed Brown 640c7d97c5SJed Brown PetscFunctionBegin; 650c7d97c5SJed Brown pcbddc->coarse_problem_type = CPT; 660c7d97c5SJed Brown PetscFunctionReturn(0); 670c7d97c5SJed Brown } 680c7d97c5SJed Brown EXTERN_C_END 690c7d97c5SJed Brown 700c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 710c7d97c5SJed Brown #undef __FUNCT__ 720c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType" 7353cdbc3dSStefano Zampini /*@ 749c0446d6SStefano Zampini PCBDDCSetCoarseProblemType - Set coarse problem type in PCBDDC. 7553cdbc3dSStefano Zampini 769c0446d6SStefano Zampini Not collective 7753cdbc3dSStefano Zampini 7853cdbc3dSStefano Zampini Input Parameters: 7953cdbc3dSStefano Zampini + pc - the preconditioning context 8053cdbc3dSStefano Zampini - CoarseProblemType - pick a better name and explain what this is 8153cdbc3dSStefano Zampini 8253cdbc3dSStefano Zampini Level: intermediate 8353cdbc3dSStefano Zampini 8453cdbc3dSStefano Zampini Notes: 859c0446d6SStefano Zampini Not collective but all procs must call this. 8653cdbc3dSStefano Zampini 8753cdbc3dSStefano Zampini .seealso: PCBDDC 8853cdbc3dSStefano Zampini @*/ 890c7d97c5SJed Brown PetscErrorCode PCBDDCSetCoarseProblemType(PC pc, CoarseProblemType CPT) 900c7d97c5SJed Brown { 910c7d97c5SJed Brown PetscErrorCode ierr; 920c7d97c5SJed Brown 930c7d97c5SJed Brown PetscFunctionBegin; 940c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 950c7d97c5SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetCoarseProblemType_C",(PC,CoarseProblemType),(pc,CPT));CHKERRQ(ierr); 960c7d97c5SJed Brown PetscFunctionReturn(0); 970c7d97c5SJed Brown } 980c7d97c5SJed Brown 990c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1000c7d97c5SJed Brown EXTERN_C_BEGIN 1010c7d97c5SJed Brown #undef __FUNCT__ 102*3b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC" 103*3b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 104*3b03a366Sstefano_zampini { 105*3b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 106*3b03a366Sstefano_zampini PetscErrorCode ierr; 107*3b03a366Sstefano_zampini 108*3b03a366Sstefano_zampini PetscFunctionBegin; 109*3b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 110*3b03a366Sstefano_zampini ierr = ISDuplicate(DirichletBoundaries,&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 111*3b03a366Sstefano_zampini ierr = ISCopy(DirichletBoundaries,pcbddc->DirichletBoundaries);CHKERRQ(ierr); 112*3b03a366Sstefano_zampini PetscFunctionReturn(0); 113*3b03a366Sstefano_zampini } 114*3b03a366Sstefano_zampini EXTERN_C_END 115*3b03a366Sstefano_zampini 116*3b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 117*3b03a366Sstefano_zampini #undef __FUNCT__ 118*3b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries" 119*3b03a366Sstefano_zampini /*@ 120*3b03a366Sstefano_zampini PCBDDCSetDirichletBoundaries - Set index set defining subdomain part of 121*3b03a366Sstefano_zampini Dirichlet boundaries for the global problem. 122*3b03a366Sstefano_zampini 123*3b03a366Sstefano_zampini Not collective 124*3b03a366Sstefano_zampini 125*3b03a366Sstefano_zampini Input Parameters: 126*3b03a366Sstefano_zampini + pc - the preconditioning context 127*3b03a366Sstefano_zampini - DirichletBoundaries - sequential index set defining the subdomain part of Dirichlet boundaries (can be PETSC_NULL) 128*3b03a366Sstefano_zampini 129*3b03a366Sstefano_zampini Level: intermediate 130*3b03a366Sstefano_zampini 131*3b03a366Sstefano_zampini Notes: 132*3b03a366Sstefano_zampini The sequential IS is copied; the user must destroy the IS object passed in. 133*3b03a366Sstefano_zampini 134*3b03a366Sstefano_zampini .seealso: PCBDDC 135*3b03a366Sstefano_zampini @*/ 136*3b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 137*3b03a366Sstefano_zampini { 138*3b03a366Sstefano_zampini PetscErrorCode ierr; 139*3b03a366Sstefano_zampini 140*3b03a366Sstefano_zampini PetscFunctionBegin; 141*3b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 142*3b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 143*3b03a366Sstefano_zampini PetscFunctionReturn(0); 144*3b03a366Sstefano_zampini } 145*3b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 146*3b03a366Sstefano_zampini EXTERN_C_BEGIN 147*3b03a366Sstefano_zampini #undef __FUNCT__ 1480c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 14953cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 1500c7d97c5SJed Brown { 1510c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15253cdbc3dSStefano Zampini PetscErrorCode ierr; 1530c7d97c5SJed Brown 1540c7d97c5SJed Brown PetscFunctionBegin; 15553cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 15653cdbc3dSStefano Zampini ierr = ISDuplicate(NeumannBoundaries,&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 15753cdbc3dSStefano Zampini ierr = ISCopy(NeumannBoundaries,pcbddc->NeumannBoundaries);CHKERRQ(ierr); 1580c7d97c5SJed Brown PetscFunctionReturn(0); 1590c7d97c5SJed Brown } 1600c7d97c5SJed Brown EXTERN_C_END 1610c7d97c5SJed Brown 1620c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1630c7d97c5SJed Brown #undef __FUNCT__ 1640c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 16557527edcSJed Brown /*@ 16653cdbc3dSStefano Zampini PCBDDCSetNeumannBoundaries - Set index set defining subdomain part of 16753cdbc3dSStefano Zampini Neumann boundaries for the global problem. 16857527edcSJed Brown 1699c0446d6SStefano Zampini Not collective 17057527edcSJed Brown 17157527edcSJed Brown Input Parameters: 17257527edcSJed Brown + pc - the preconditioning context 1739c0446d6SStefano Zampini - NeumannBoundaries - sequential index set defining the subdomain part of Neumann boundaries (can be PETSC_NULL) 17457527edcSJed Brown 17557527edcSJed Brown Level: intermediate 17657527edcSJed Brown 17757527edcSJed Brown Notes: 1789c0446d6SStefano Zampini The sequential IS is copied; the user must destroy the IS object passed in. 17957527edcSJed Brown 18057527edcSJed Brown .seealso: PCBDDC 18157527edcSJed Brown @*/ 18253cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 1830c7d97c5SJed Brown { 1840c7d97c5SJed Brown PetscErrorCode ierr; 1850c7d97c5SJed Brown 1860c7d97c5SJed Brown PetscFunctionBegin; 1870c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 18853cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 18953cdbc3dSStefano Zampini PetscFunctionReturn(0); 19053cdbc3dSStefano Zampini } 19153cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 19253cdbc3dSStefano Zampini EXTERN_C_BEGIN 19353cdbc3dSStefano Zampini #undef __FUNCT__ 19453cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 19553cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 19653cdbc3dSStefano Zampini { 19753cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 19853cdbc3dSStefano Zampini 19953cdbc3dSStefano Zampini PetscFunctionBegin; 20053cdbc3dSStefano Zampini if(pcbddc->NeumannBoundaries) { 20153cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 20253cdbc3dSStefano Zampini } else { 2039c0446d6SStefano Zampini *NeumannBoundaries = PETSC_NULL; 2049c0446d6SStefano Zampini //SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Error in %s: Neumann boundaries not set!.\n",__FUNCT__); 20553cdbc3dSStefano Zampini } 20653cdbc3dSStefano Zampini PetscFunctionReturn(0); 20753cdbc3dSStefano Zampini } 20853cdbc3dSStefano Zampini EXTERN_C_END 20953cdbc3dSStefano Zampini 21053cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 21153cdbc3dSStefano Zampini #undef __FUNCT__ 21253cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 21353cdbc3dSStefano Zampini /*@ 21453cdbc3dSStefano Zampini PCBDDCGetNeumannBoundaries - Get index set defining subdomain part of 21553cdbc3dSStefano Zampini Neumann boundaries for the global problem. 21653cdbc3dSStefano Zampini 2179c0446d6SStefano Zampini Not collective 21853cdbc3dSStefano Zampini 21953cdbc3dSStefano Zampini Input Parameters: 22053cdbc3dSStefano Zampini + pc - the preconditioning context 22153cdbc3dSStefano Zampini 22253cdbc3dSStefano Zampini Output Parameters: 22353cdbc3dSStefano Zampini + NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 22453cdbc3dSStefano Zampini 22553cdbc3dSStefano Zampini Level: intermediate 22653cdbc3dSStefano Zampini 22753cdbc3dSStefano Zampini Notes: 2289c0446d6SStefano Zampini If the user has not yet provided such information, PETSC_NULL is returned. 22953cdbc3dSStefano Zampini 23053cdbc3dSStefano Zampini .seealso: PCBDDC 23153cdbc3dSStefano Zampini @*/ 23253cdbc3dSStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 23353cdbc3dSStefano Zampini { 23453cdbc3dSStefano Zampini PetscErrorCode ierr; 23553cdbc3dSStefano Zampini 23653cdbc3dSStefano Zampini PetscFunctionBegin; 23753cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 23853cdbc3dSStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 2390c7d97c5SJed Brown PetscFunctionReturn(0); 2400c7d97c5SJed Brown } 2410c7d97c5SJed Brown 2429c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 2439c0446d6SStefano Zampini EXTERN_C_BEGIN 2449c0446d6SStefano Zampini #undef __FUNCT__ 2459c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 2469c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 2479c0446d6SStefano Zampini { 2489c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2499c0446d6SStefano Zampini PetscInt i; 2509c0446d6SStefano Zampini PetscErrorCode ierr; 2519c0446d6SStefano Zampini 2529c0446d6SStefano Zampini PetscFunctionBegin; 2539c0446d6SStefano Zampini /* Destroy IS if already set */ 2549c0446d6SStefano Zampini for(i=0;i<pcbddc->n_ISForDofs;i++) { 2559c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 2569c0446d6SStefano Zampini ierr = ISDuplicate(ISForDofs[i],&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 2579c0446d6SStefano Zampini ierr = ISCopy(ISForDofs[i],pcbddc->ISForDofs[i]);CHKERRQ(ierr); 2589c0446d6SStefano Zampini } 2599c0446d6SStefano Zampini /* allocate space then copy ISs */ 2609c0446d6SStefano Zampini ierr = PetscMalloc(n_is*sizeof(IS),&pcbddc->ISForDofs);CHKERRQ(ierr); 2619c0446d6SStefano Zampini for(i=0;i<n_is;i++) { 2629c0446d6SStefano Zampini ierr = ISDuplicate(ISForDofs[i],&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 2639c0446d6SStefano Zampini ierr = ISCopy(ISForDofs[i],pcbddc->ISForDofs[i]);CHKERRQ(ierr); 2649c0446d6SStefano Zampini } 2659c0446d6SStefano Zampini pcbddc->n_ISForDofs=n_is; 2669c0446d6SStefano Zampini PetscFunctionReturn(0); 2679c0446d6SStefano Zampini } 2689c0446d6SStefano Zampini EXTERN_C_END 2699c0446d6SStefano Zampini 2709c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 2719c0446d6SStefano Zampini #undef __FUNCT__ 2729c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 2739c0446d6SStefano Zampini /*@ 2749c0446d6SStefano Zampini PCBDDCSetDofsSplitting - Set index set defining how dofs are splitted. 2759c0446d6SStefano Zampini 2769c0446d6SStefano Zampini Not collective 2779c0446d6SStefano Zampini 2789c0446d6SStefano Zampini Input Parameters: 2799c0446d6SStefano Zampini + pc - the preconditioning context 2809c0446d6SStefano Zampini - n - number of index sets defining dofs spltting 2819c0446d6SStefano Zampini - IS[] - array of IS describing dofs splitting 2829c0446d6SStefano Zampini 2839c0446d6SStefano Zampini Level: intermediate 2849c0446d6SStefano Zampini 2859c0446d6SStefano Zampini Notes: 2869c0446d6SStefano Zampini Sequential ISs are copied, the user must destroy the array of IS passed in. 2879c0446d6SStefano Zampini 2889c0446d6SStefano Zampini .seealso: PCBDDC 2899c0446d6SStefano Zampini @*/ 2909c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 2919c0446d6SStefano Zampini { 2929c0446d6SStefano Zampini PetscErrorCode ierr; 2939c0446d6SStefano Zampini 2949c0446d6SStefano Zampini PetscFunctionBegin; 2959c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2969c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 2979c0446d6SStefano Zampini PetscFunctionReturn(0); 2989c0446d6SStefano Zampini } 2999c0446d6SStefano Zampini 30053cdbc3dSStefano Zampini #undef __FUNCT__ 30153cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 3020c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 3030c7d97c5SJed Brown /* 3040c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 3050c7d97c5SJed Brown by setting data structures and options. 3060c7d97c5SJed Brown 3070c7d97c5SJed Brown Input Parameter: 30853cdbc3dSStefano Zampini + pc - the preconditioner context 3090c7d97c5SJed Brown 3100c7d97c5SJed Brown Application Interface Routine: PCSetUp() 3110c7d97c5SJed Brown 3120c7d97c5SJed Brown Notes: 3130c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 3140c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 3150c7d97c5SJed Brown */ 31653cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 3170c7d97c5SJed Brown { 3180c7d97c5SJed Brown PetscErrorCode ierr; 3190c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3200c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 3210c7d97c5SJed Brown 3220c7d97c5SJed Brown PetscFunctionBegin; 3230c7d97c5SJed Brown if (!pc->setupcalled) { 324*3b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 3259c0446d6SStefano Zampini So, we set to pcnone the Neumann problem of pcis in order to avoid unneeded computation 3260c7d97c5SJed Brown Also, we decide to directly build the (same) Dirichlet problem */ 3270c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localN_pc_type","none");CHKERRQ(ierr); 3280c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localD_pc_type","none");CHKERRQ(ierr); 3290c7d97c5SJed Brown /* Set up all the "iterative substructuring" common block */ 3300c7d97c5SJed Brown ierr = PCISSetUp(pc);CHKERRQ(ierr); 331*3b03a366Sstefano_zampini /* Get stdout for dbg */ 332e269702eSStefano Zampini if(pcbddc->dbg_flag) { 333e269702eSStefano Zampini ierr = PetscViewerASCIIGetStdout(((PetscObject)pc)->comm,&pcbddc->dbg_viewer);CHKERRQ(ierr); 334e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 335e269702eSStefano Zampini } 336*3b03a366Sstefano_zampini /* TODO MOVE CODE FRAGMENT */ 3370c7d97c5SJed Brown PetscInt im_active=0; 3380c7d97c5SJed Brown if(pcis->n) im_active = 1; 33953cdbc3dSStefano Zampini ierr = MPI_Allreduce(&im_active,&pcbddc->active_procs,1,MPIU_INT,MPI_SUM,((PetscObject)pc)->comm);CHKERRQ(ierr); 340*3b03a366Sstefano_zampini /* Analyze local interface */ 3410c7d97c5SJed Brown ierr = PCBDDCManageLocalBoundaries(pc);CHKERRQ(ierr); 342*3b03a366Sstefano_zampini /* Set up local constraint matrix */ 343*3b03a366Sstefano_zampini ierr = PCBDDCCreateConstraintMatrix(pc);CHKERRQ(ierr); 3440c7d97c5SJed Brown /* Create coarse and local stuffs used for evaluating action of preconditioner */ 3450c7d97c5SJed Brown ierr = PCBDDCCoarseSetUp(pc);CHKERRQ(ierr); 346*3b03a366Sstefano_zampini /* Processes fakely involved in multilevel should not call ISLocalToGlobalMappingRestoreInfo */ 347*3b03a366Sstefano_zampini if ( !pcis->n_neigh ) pcis->ISLocalToGlobalMappingGetInfoWasCalled=PETSC_FALSE; 3480c7d97c5SJed Brown } 3490c7d97c5SJed Brown PetscFunctionReturn(0); 3500c7d97c5SJed Brown } 3510c7d97c5SJed Brown 3520c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 3530c7d97c5SJed Brown /* 3540c7d97c5SJed Brown PCApply_BDDC - Applies the BDDC preconditioner to a vector. 3550c7d97c5SJed Brown 3560c7d97c5SJed Brown Input Parameters: 3570c7d97c5SJed Brown . pc - the preconditioner context 3580c7d97c5SJed Brown . r - input vector (global) 3590c7d97c5SJed Brown 3600c7d97c5SJed Brown Output Parameter: 3610c7d97c5SJed Brown . z - output vector (global) 3620c7d97c5SJed Brown 3630c7d97c5SJed Brown Application Interface Routine: PCApply() 3640c7d97c5SJed Brown */ 3650c7d97c5SJed Brown #undef __FUNCT__ 3660c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 36753cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 3680c7d97c5SJed Brown { 3690c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 3700c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 3710c7d97c5SJed Brown PetscErrorCode ierr; 372*3b03a366Sstefano_zampini const PetscScalar one = 1.0; 373*3b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 3740c7d97c5SJed Brown 3750c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 3760c7d97c5SJed Brown NN interface preconditioner changed to BDDC 3770c7d97c5SJed Brown Added support for M_3 preconditioenr in the reference article (code is active if pcbddc->prec_type = PETSC_TRUE) */ 3780c7d97c5SJed Brown 3790c7d97c5SJed Brown PetscFunctionBegin; 3800c7d97c5SJed Brown /* First Dirichlet solve */ 3810c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3820c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 38353cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 3840c7d97c5SJed Brown /* 3850c7d97c5SJed Brown Assembling right hand side for BDDC operator 3860c7d97c5SJed Brown - vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE) 3870c7d97c5SJed Brown - the interface part of the global vector z 3880c7d97c5SJed Brown */ 3890c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 3900c7d97c5SJed Brown ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 3910c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3920c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 3930c7d97c5SJed Brown ierr = VecCopy(r,z);CHKERRQ(ierr); 3940c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3950c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3960c7d97c5SJed Brown 3970c7d97c5SJed Brown /* 3980c7d97c5SJed Brown Apply interface preconditioner 3990c7d97c5SJed Brown Results are stored in: 4000c7d97c5SJed Brown - vec1_D (if needed, i.e. with prec_type = PETSC_TRUE) 4010c7d97c5SJed Brown - the interface part of the global vector z 4020c7d97c5SJed Brown */ 4030c7d97c5SJed Brown ierr = PCBDDCApplyInterfacePreconditioner(pc,z);CHKERRQ(ierr); 4040c7d97c5SJed Brown 405*3b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 4060c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4070c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4080c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 4090c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 41053cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr); 4110c7d97c5SJed Brown ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr); 4120c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); } 4130c7d97c5SJed Brown ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr); 4140c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4150c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4160c7d97c5SJed Brown 4170c7d97c5SJed Brown PetscFunctionReturn(0); 4180c7d97c5SJed Brown 4190c7d97c5SJed Brown } 4200c7d97c5SJed Brown 4210c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 4220c7d97c5SJed Brown /* 4230c7d97c5SJed Brown PCBDDCApplyInterfacePreconditioner - Apply the BDDC preconditioner at the interface. 4240c7d97c5SJed Brown 4250c7d97c5SJed Brown */ 4260c7d97c5SJed Brown #undef __FUNCT__ 4270c7d97c5SJed Brown #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 42853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, Vec z) 4290c7d97c5SJed Brown { 4300c7d97c5SJed Brown PetscErrorCode ierr; 4310c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4320c7d97c5SJed Brown PC_IS* pcis = (PC_IS*) (pc->data); 433*3b03a366Sstefano_zampini const PetscScalar zero = 0.0; 4340c7d97c5SJed Brown 4350c7d97c5SJed Brown PetscFunctionBegin; 4360c7d97c5SJed Brown /* Get Local boundary and apply partition of unity */ 4370c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4380c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4390c7d97c5SJed Brown ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 4400c7d97c5SJed Brown 4410c7d97c5SJed Brown /* Application of PHI^T */ 4420c7d97c5SJed Brown ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 4430c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 4440c7d97c5SJed Brown 4450c7d97c5SJed Brown /* Scatter data of coarse_rhs */ 4460c7d97c5SJed Brown if(pcbddc->coarse_rhs) ierr = VecSet(pcbddc->coarse_rhs,zero);CHKERRQ(ierr); 4470c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4480c7d97c5SJed Brown 4490c7d97c5SJed Brown /* Local solution on R nodes */ 4500c7d97c5SJed Brown ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 4510c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4520c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4530c7d97c5SJed Brown if(pcbddc->prec_type) { 4540c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4550c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4560c7d97c5SJed Brown } 4570c7d97c5SJed Brown ierr = PCBDDCSolveSaddlePoint(pc);CHKERRQ(ierr); 4580c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 4590c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4600c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4610c7d97c5SJed Brown if(pcbddc->prec_type) { 4620c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4630c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4640c7d97c5SJed Brown } 4650c7d97c5SJed Brown 4660c7d97c5SJed Brown /* Coarse solution */ 4670c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 46853cdbc3dSStefano Zampini if(pcbddc->coarse_rhs) ierr = KSPSolve(pcbddc->coarse_ksp,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 4690c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4700c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd (pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4710c7d97c5SJed Brown 4720c7d97c5SJed Brown /* Sum contributions from two levels */ 4730c7d97c5SJed Brown /* Apply partition of unity and sum boundary values */ 4740c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 4750c7d97c5SJed Brown ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 4760c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 4770c7d97c5SJed Brown ierr = VecSet(z,zero);CHKERRQ(ierr); 4780c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4790c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4800c7d97c5SJed Brown 4810c7d97c5SJed Brown PetscFunctionReturn(0); 4820c7d97c5SJed Brown } 4830c7d97c5SJed Brown 4840c7d97c5SJed Brown 4850c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 4860c7d97c5SJed Brown /* 4870c7d97c5SJed Brown PCBDDCSolveSaddlePoint 4880c7d97c5SJed Brown 4890c7d97c5SJed Brown */ 4900c7d97c5SJed Brown #undef __FUNCT__ 4910c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSolveSaddlePoint" 49253cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSolveSaddlePoint(PC pc) 4930c7d97c5SJed Brown { 4940c7d97c5SJed Brown PetscErrorCode ierr; 4950c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4960c7d97c5SJed Brown 4970c7d97c5SJed Brown PetscFunctionBegin; 4980c7d97c5SJed Brown 49953cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 5000c7d97c5SJed Brown if(pcbddc->n_constraints) { 5010c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec2_R,pcbddc->vec1_C);CHKERRQ(ierr); 5020c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 5030c7d97c5SJed Brown } 5040c7d97c5SJed Brown 5050c7d97c5SJed Brown PetscFunctionReturn(0); 5060c7d97c5SJed Brown } 5070c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 5080c7d97c5SJed Brown /* 5090c7d97c5SJed Brown PCBDDCScatterCoarseDataBegin 5100c7d97c5SJed Brown 5110c7d97c5SJed Brown */ 5120c7d97c5SJed Brown #undef __FUNCT__ 5130c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 51453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,Vec vec_from, Vec vec_to, InsertMode imode, ScatterMode smode) 5150c7d97c5SJed Brown { 5160c7d97c5SJed Brown PetscErrorCode ierr; 5170c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5180c7d97c5SJed Brown 5190c7d97c5SJed Brown PetscFunctionBegin; 5200c7d97c5SJed Brown 5210c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 5220c7d97c5SJed Brown case SCATTERS_BDDC: 5230c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 5240c7d97c5SJed Brown break; 5250c7d97c5SJed Brown case GATHERS_BDDC: 5260c7d97c5SJed Brown break; 5270c7d97c5SJed Brown } 5280c7d97c5SJed Brown PetscFunctionReturn(0); 5290c7d97c5SJed Brown 5300c7d97c5SJed Brown } 5310c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 5320c7d97c5SJed Brown /* 5330c7d97c5SJed Brown PCBDDCScatterCoarseDataEnd 5340c7d97c5SJed Brown 5350c7d97c5SJed Brown */ 5360c7d97c5SJed Brown #undef __FUNCT__ 5370c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 53853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc,Vec vec_from, Vec vec_to, InsertMode imode, ScatterMode smode) 5390c7d97c5SJed Brown { 5400c7d97c5SJed Brown PetscErrorCode ierr; 5410c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5420c7d97c5SJed Brown PetscScalar* array_to; 5430c7d97c5SJed Brown PetscScalar* array_from; 5440c7d97c5SJed Brown MPI_Comm comm=((PetscObject)pc)->comm; 5450c7d97c5SJed Brown PetscInt i; 5460c7d97c5SJed Brown 5470c7d97c5SJed Brown PetscFunctionBegin; 5480c7d97c5SJed Brown 5490c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 5500c7d97c5SJed Brown case SCATTERS_BDDC: 5510c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 5520c7d97c5SJed Brown break; 5530c7d97c5SJed Brown case GATHERS_BDDC: 5540c7d97c5SJed Brown if(vec_from) VecGetArray(vec_from,&array_from); 5550c7d97c5SJed Brown if(vec_to) VecGetArray(vec_to,&array_to); 5560c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 5570c7d97c5SJed Brown case SEQUENTIAL_BDDC: 5580c7d97c5SJed Brown if(smode == SCATTER_FORWARD) { 55953cdbc3dSStefano 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); 5600c7d97c5SJed Brown if(vec_to) { 5610c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 5620c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 5630c7d97c5SJed Brown } 5640c7d97c5SJed Brown } else { 5650c7d97c5SJed Brown if(vec_from) 5660c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 5670c7d97c5SJed Brown pcbddc->replicated_local_primal_values[i]=array_from[pcbddc->replicated_local_primal_indices[i]]; 56853cdbc3dSStefano 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); 5690c7d97c5SJed Brown } 5700c7d97c5SJed Brown break; 5710c7d97c5SJed Brown case REPLICATED_BDDC: 5720c7d97c5SJed Brown if(smode == SCATTER_FORWARD) { 57353cdbc3dSStefano 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); 5740c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 5750c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 5760c7d97c5SJed Brown } else { /* no communications needed for SCATTER_REVERSE since needed data is already present */ 5770c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_size;i++) 5780c7d97c5SJed Brown array_to[i]=array_from[pcbddc->local_primal_indices[i]]; 5790c7d97c5SJed Brown } 5800c7d97c5SJed Brown break; 58153cdbc3dSStefano Zampini case MULTILEVEL_BDDC: 58253cdbc3dSStefano Zampini break; 58353cdbc3dSStefano Zampini case PARALLEL_BDDC: 58453cdbc3dSStefano Zampini break; 5850c7d97c5SJed Brown } 5860c7d97c5SJed Brown if(vec_from) VecRestoreArray(vec_from,&array_from); 5870c7d97c5SJed Brown if(vec_to) VecRestoreArray(vec_to,&array_to); 5880c7d97c5SJed Brown break; 5890c7d97c5SJed Brown } 5900c7d97c5SJed Brown PetscFunctionReturn(0); 5910c7d97c5SJed Brown 5920c7d97c5SJed Brown } 5930c7d97c5SJed Brown 5940c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 5950c7d97c5SJed Brown /* 5960c7d97c5SJed Brown PCDestroy_BDDC - Destroys the private context for the NN preconditioner 5970c7d97c5SJed Brown that was created with PCCreate_BDDC(). 5980c7d97c5SJed Brown 5990c7d97c5SJed Brown Input Parameter: 6000c7d97c5SJed Brown . pc - the preconditioner context 6010c7d97c5SJed Brown 6020c7d97c5SJed Brown Application Interface Routine: PCDestroy() 6030c7d97c5SJed Brown */ 6040c7d97c5SJed Brown #undef __FUNCT__ 6050c7d97c5SJed Brown #define __FUNCT__ "PCDestroy_BDDC" 60653cdbc3dSStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 6070c7d97c5SJed Brown { 6080c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6090c7d97c5SJed Brown PetscErrorCode ierr; 6100c7d97c5SJed Brown 6110c7d97c5SJed Brown PetscFunctionBegin; 6120c7d97c5SJed Brown /* free data created by PCIS */ 6130c7d97c5SJed Brown ierr = PCISDestroy(pc);CHKERRQ(ierr); 6140c7d97c5SJed Brown /* free BDDC data */ 61553cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 61653cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->coarse_rhs);CHKERRQ(ierr); 61753cdbc3dSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 61853cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_mat);CHKERRQ(ierr); 61953cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 62053cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 62153cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 62253cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 62353cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 62453cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 62553cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 62653cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 62753cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec4_D);CHKERRQ(ierr); 62853cdbc3dSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 62953cdbc3dSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 63053cdbc3dSStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 63153cdbc3dSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 63253cdbc3dSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 63353cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 634*3b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 635*3b03a366Sstefano_zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 63653cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->local_primal_indices);CHKERRQ(ierr); 63753cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 6380c7d97c5SJed Brown if (pcbddc->replicated_local_primal_values) { free(pcbddc->replicated_local_primal_values); } 63953cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->local_primal_displacements);CHKERRQ(ierr); 64053cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->local_primal_sizes);CHKERRQ(ierr); 6419c0446d6SStefano Zampini PetscInt i; 642*3b03a366Sstefano_zampini for(i=0;i<pcbddc->n_ISForDofs;i++) { ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); } 643*3b03a366Sstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 644*3b03a366Sstefano_zampini for(i=0;i<pcbddc->n_ISForFaces;i++) { ierr = ISDestroy(&pcbddc->ISForFaces[i]);CHKERRQ(ierr); } 645*3b03a366Sstefano_zampini ierr = PetscFree(pcbddc->ISForFaces);CHKERRQ(ierr); 646*3b03a366Sstefano_zampini for(i=0;i<pcbddc->n_ISForEdges;i++) { ierr = ISDestroy(&pcbddc->ISForEdges[i]);CHKERRQ(ierr); } 647*3b03a366Sstefano_zampini ierr = PetscFree(pcbddc->ISForEdges);CHKERRQ(ierr); 648*3b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->ISForVertices);CHKERRQ(ierr); 6490c7d97c5SJed Brown /* Free the private data structure that was hanging off the PC */ 6500c7d97c5SJed Brown ierr = PetscFree(pcbddc);CHKERRQ(ierr); 6510c7d97c5SJed Brown PetscFunctionReturn(0); 6520c7d97c5SJed Brown } 6530c7d97c5SJed Brown 6540c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 6550c7d97c5SJed Brown /*MC 6560c7d97c5SJed Brown PCBDDC - Balancing Domain Decomposition by Constraints. 6570c7d97c5SJed Brown 6580c7d97c5SJed Brown Options Database Keys: 659a0ba757dSStefano Zampini . -pcbddc ??? - 6600c7d97c5SJed Brown 6610c7d97c5SJed Brown Level: intermediate 6620c7d97c5SJed Brown 6630c7d97c5SJed Brown Notes: The matrix used with this preconditioner must be of type MATIS 6640c7d97c5SJed Brown 6650c7d97c5SJed Brown Unlike more 'conventional' interface preconditioners, this iterates over ALL the 6660c7d97c5SJed Brown degrees of freedom, NOT just those on the interface (this allows the use of approximate solvers 6670c7d97c5SJed Brown on the subdomains). 6680c7d97c5SJed Brown 669a0ba757dSStefano Zampini Options for the coarse grid preconditioner can be set with - 670a0ba757dSStefano Zampini Options for the Dirichlet subproblem can be set with - 671a0ba757dSStefano Zampini Options for the Neumann subproblem can be set with - 6720c7d97c5SJed Brown 6730c7d97c5SJed Brown Contributed by Stefano Zampini 6740c7d97c5SJed Brown 6750c7d97c5SJed Brown .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 6760c7d97c5SJed Brown M*/ 6770c7d97c5SJed Brown EXTERN_C_BEGIN 6780c7d97c5SJed Brown #undef __FUNCT__ 6790c7d97c5SJed Brown #define __FUNCT__ "PCCreate_BDDC" 6800c7d97c5SJed Brown PetscErrorCode PCCreate_BDDC(PC pc) 6810c7d97c5SJed Brown { 6820c7d97c5SJed Brown PetscErrorCode ierr; 6830c7d97c5SJed Brown PC_BDDC *pcbddc; 6840c7d97c5SJed Brown 6850c7d97c5SJed Brown PetscFunctionBegin; 6860c7d97c5SJed Brown /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 6870c7d97c5SJed Brown ierr = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr); 6880c7d97c5SJed Brown pc->data = (void*)pcbddc; 6890c7d97c5SJed Brown /* create PCIS data structure */ 6900c7d97c5SJed Brown ierr = PCISCreate(pc);CHKERRQ(ierr); 6910c7d97c5SJed Brown /* BDDC specific */ 6920c7d97c5SJed Brown pcbddc->coarse_vec = 0; 6930c7d97c5SJed Brown pcbddc->coarse_rhs = 0; 69453cdbc3dSStefano Zampini pcbddc->coarse_ksp = 0; 6950c7d97c5SJed Brown pcbddc->coarse_phi_B = 0; 6960c7d97c5SJed Brown pcbddc->coarse_phi_D = 0; 6970c7d97c5SJed Brown pcbddc->vec1_P = 0; 6980c7d97c5SJed Brown pcbddc->vec1_R = 0; 6990c7d97c5SJed Brown pcbddc->vec2_R = 0; 7000c7d97c5SJed Brown pcbddc->local_auxmat1 = 0; 7010c7d97c5SJed Brown pcbddc->local_auxmat2 = 0; 7020c7d97c5SJed Brown pcbddc->R_to_B = 0; 7030c7d97c5SJed Brown pcbddc->R_to_D = 0; 70453cdbc3dSStefano Zampini pcbddc->ksp_D = 0; 70553cdbc3dSStefano Zampini pcbddc->ksp_R = 0; 7060c7d97c5SJed Brown pcbddc->local_primal_indices = 0; 7070c7d97c5SJed Brown pcbddc->prec_type = PETSC_FALSE; 70853cdbc3dSStefano Zampini pcbddc->NeumannBoundaries = 0; 709*3b03a366Sstefano_zampini pcbddc->ISForDofs = 0; 710*3b03a366Sstefano_zampini pcbddc->ISForVertices = 0; 711*3b03a366Sstefano_zampini pcbddc->n_ISForFaces = 0; 712*3b03a366Sstefano_zampini pcbddc->n_ISForEdges = 0; 713*3b03a366Sstefano_zampini pcbddc->ConstraintMatrix = 0; 714*3b03a366Sstefano_zampini pcbddc->use_nnsp_true = PETSC_FALSE; 7150c7d97c5SJed Brown pcbddc->local_primal_sizes = 0; 7160c7d97c5SJed Brown pcbddc->local_primal_displacements = 0; 7170c7d97c5SJed Brown pcbddc->replicated_local_primal_indices = 0; 7180c7d97c5SJed Brown pcbddc->replicated_local_primal_values = 0; 7190c7d97c5SJed Brown pcbddc->coarse_loc_to_glob = 0; 720e269702eSStefano Zampini pcbddc->dbg_flag = PETSC_FALSE; 7210c7d97c5SJed Brown pcbddc->coarsening_ratio = 8; 7220c7d97c5SJed Brown /* function pointers */ 7230c7d97c5SJed Brown pc->ops->apply = PCApply_BDDC; 7240c7d97c5SJed Brown pc->ops->applytranspose = 0; 7250c7d97c5SJed Brown pc->ops->setup = PCSetUp_BDDC; 7260c7d97c5SJed Brown pc->ops->destroy = PCDestroy_BDDC; 7270c7d97c5SJed Brown pc->ops->setfromoptions = PCSetFromOptions_BDDC; 7280c7d97c5SJed Brown pc->ops->view = 0; 7290c7d97c5SJed Brown pc->ops->applyrichardson = 0; 7300c7d97c5SJed Brown pc->ops->applysymmetricleft = 0; 7310c7d97c5SJed Brown pc->ops->applysymmetricright = 0; 7320c7d97c5SJed Brown /* composing function */ 733*3b03a366Sstefano_zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C","PCBDDCSetDirichletBoundaries_BDDC", 734*3b03a366Sstefano_zampini PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 7350c7d97c5SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C","PCBDDCSetNeumannBoundaries_BDDC", 7360c7d97c5SJed Brown PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 73753cdbc3dSStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C","PCBDDCGetNeumannBoundaries_BDDC", 73853cdbc3dSStefano Zampini PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 7390c7d97c5SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetCoarseProblemType_C","PCBDDCSetCoarseProblemType_BDDC", 7400c7d97c5SJed Brown PCBDDCSetCoarseProblemType_BDDC);CHKERRQ(ierr); 7419c0446d6SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetDofsSplitting_C","PCBDDCSetDofsSplitting_BDDC", 7429c0446d6SStefano Zampini PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 7430c7d97c5SJed Brown PetscFunctionReturn(0); 7440c7d97c5SJed Brown } 7450c7d97c5SJed Brown EXTERN_C_END 7460c7d97c5SJed Brown 7470c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 7480c7d97c5SJed Brown /* 749*3b03a366Sstefano_zampini Create C matrix [I 0; 0 const] 750*3b03a366Sstefano_zampini */ 751*3b03a366Sstefano_zampini /* for testing only */ 752*3b03a366Sstefano_zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 753*3b03a366Sstefano_zampini #define BDDC_USE_POD 754*3b03a366Sstefano_zampini #define PETSC_MISSING_LAPACK_GESVD 1 755*3b03a366Sstefano_zampini #endif 756*3b03a366Sstefano_zampini 757*3b03a366Sstefano_zampini #undef __FUNCT__ 758*3b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCCreateConstraintMatrix" 759*3b03a366Sstefano_zampini static PetscErrorCode PCBDDCCreateConstraintMatrix(PC pc) 760*3b03a366Sstefano_zampini { 761*3b03a366Sstefano_zampini PetscErrorCode ierr; 762*3b03a366Sstefano_zampini PC_IS* pcis = (PC_IS*)(pc->data); 763*3b03a366Sstefano_zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 764*3b03a366Sstefano_zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 765*3b03a366Sstefano_zampini PetscInt *nnz,*vertices,*is_indices; 766*3b03a366Sstefano_zampini PetscScalar *temp_quadrature_constraint; 767*3b03a366Sstefano_zampini PetscInt *temp_indices,*temp_indices_to_constraint; 768*3b03a366Sstefano_zampini PetscInt local_primal_size,i,j,k,total_counts,max_size_of_constraint; 769*3b03a366Sstefano_zampini PetscInt n_constraints,n_vertices,size_of_constraint; 770*3b03a366Sstefano_zampini PetscReal quad_value; 771*3b03a366Sstefano_zampini PetscBool nnsp_has_cnst=PETSC_FALSE,use_nnsp_true=pcbddc->use_nnsp_true; 772*3b03a366Sstefano_zampini PetscInt nnsp_size=0,nnsp_addone=0,temp_constraints,temp_start_ptr; 773*3b03a366Sstefano_zampini IS *used_IS; 774*3b03a366Sstefano_zampini const MatType impMatType=MATSEQAIJ; 775*3b03a366Sstefano_zampini PetscBLASInt Bs,Bt,lwork,lierr; 776*3b03a366Sstefano_zampini PetscReal tol=1.0e-8; 777*3b03a366Sstefano_zampini Vec *localnearnullsp; 778*3b03a366Sstefano_zampini PetscScalar *work,*temp_basis,*array_vector,*correlation_mat; 779*3b03a366Sstefano_zampini PetscReal *rwork,*singular_vals; 780*3b03a366Sstefano_zampini /* some conditional variables */ 781*3b03a366Sstefano_zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 782*3b03a366Sstefano_zampini PetscScalar dot_result; 783*3b03a366Sstefano_zampini PetscScalar one=1.0,zero=0.0; 784*3b03a366Sstefano_zampini PetscInt ii; 785*3b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 786*3b03a366Sstefano_zampini PetscScalar val1,val2; 787*3b03a366Sstefano_zampini #else 788*3b03a366Sstefano_zampini PetscBLASInt Bone=1; 789*3b03a366Sstefano_zampini #endif 790*3b03a366Sstefano_zampini #else 791*3b03a366Sstefano_zampini PetscBLASInt dummy_int; 792*3b03a366Sstefano_zampini PetscScalar dummy_scalar; 793*3b03a366Sstefano_zampini #endif 794*3b03a366Sstefano_zampini 795*3b03a366Sstefano_zampini 796*3b03a366Sstefano_zampini PetscFunctionBegin; 797*3b03a366Sstefano_zampini /* check if near null space is attached to global mat */ 798*3b03a366Sstefano_zampini if(pc->pmat->nearnullsp) { 799*3b03a366Sstefano_zampini nnsp_has_cnst = pc->pmat->nearnullsp->has_cnst; 800*3b03a366Sstefano_zampini nnsp_size = pc->pmat->nearnullsp->n; 801*3b03a366Sstefano_zampini } else { /* if near null space is not provided it uses constants */ 802*3b03a366Sstefano_zampini nnsp_has_cnst = PETSC_TRUE; 803*3b03a366Sstefano_zampini use_nnsp_true = PETSC_TRUE; 804*3b03a366Sstefano_zampini } 805*3b03a366Sstefano_zampini if(nnsp_has_cnst) { 806*3b03a366Sstefano_zampini nnsp_addone = 1; 807*3b03a366Sstefano_zampini } 808*3b03a366Sstefano_zampini /* 809*3b03a366Sstefano_zampini Evaluate maximum storage size needed by the procedure 810*3b03a366Sstefano_zampini - temp_indices will contain start index of each constraint stored as follows 811*3b03a366Sstefano_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 812*3b03a366Sstefano_zampini - temp_quadrature_constraint[temp_indices[i],...,temp[indices[i+1]-1] will contain the scalars representing the constraint itself 813*3b03a366Sstefano_zampini */ 814*3b03a366Sstefano_zampini total_counts = pcbddc->n_ISForFaces+pcbddc->n_ISForEdges; 815*3b03a366Sstefano_zampini total_counts *= (nnsp_addone+nnsp_size); 816*3b03a366Sstefano_zampini ierr = PetscMalloc((total_counts+1)*sizeof(PetscInt),&temp_indices);CHKERRQ(ierr); 817*3b03a366Sstefano_zampini total_counts = 0; 818*3b03a366Sstefano_zampini max_size_of_constraint = 0; 819*3b03a366Sstefano_zampini for(i=0;i<pcbddc->n_ISForEdges+pcbddc->n_ISForFaces;i++){ 820*3b03a366Sstefano_zampini if(i<pcbddc->n_ISForEdges){ 821*3b03a366Sstefano_zampini used_IS = &pcbddc->ISForEdges[i]; 822*3b03a366Sstefano_zampini } else { 823*3b03a366Sstefano_zampini used_IS = &pcbddc->ISForFaces[i-pcbddc->n_ISForEdges]; 824*3b03a366Sstefano_zampini } 825*3b03a366Sstefano_zampini ierr = ISGetSize(*used_IS,&j);CHKERRQ(ierr); 826*3b03a366Sstefano_zampini total_counts += j; 827*3b03a366Sstefano_zampini if(j>max_size_of_constraint) max_size_of_constraint=j; 828*3b03a366Sstefano_zampini } 829*3b03a366Sstefano_zampini total_counts *= (nnsp_addone+nnsp_size); 830*3b03a366Sstefano_zampini ierr = PetscMalloc(total_counts*sizeof(PetscScalar),&temp_quadrature_constraint);CHKERRQ(ierr); 831*3b03a366Sstefano_zampini ierr = PetscMalloc(total_counts*sizeof(PetscInt),&temp_indices_to_constraint);CHKERRQ(ierr); 832*3b03a366Sstefano_zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd or LAPACKsyev/LAPACKheev */ 833*3b03a366Sstefano_zampini rwork = 0; 834*3b03a366Sstefano_zampini work = 0; 835*3b03a366Sstefano_zampini singular_vals = 0; 836*3b03a366Sstefano_zampini temp_basis = 0; 837*3b03a366Sstefano_zampini correlation_mat = 0; 838*3b03a366Sstefano_zampini if(!pcbddc->use_nnsp_true) { 839*3b03a366Sstefano_zampini PetscScalar temp_work; 840*3b03a366Sstefano_zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 841*3b03a366Sstefano_zampini /* POD */ 842*3b03a366Sstefano_zampini PetscInt max_n; 843*3b03a366Sstefano_zampini max_n = nnsp_addone+nnsp_size; 844*3b03a366Sstefano_zampini /* using some techniques borrowed from Proper Orthogonal Decomposition */ 845*3b03a366Sstefano_zampini ierr = PetscMalloc(max_n*max_n*sizeof(PetscScalar),&correlation_mat);CHKERRQ(ierr); 846*3b03a366Sstefano_zampini ierr = PetscMalloc(max_n*sizeof(PetscReal),&singular_vals);CHKERRQ(ierr); 847*3b03a366Sstefano_zampini ierr = PetscMalloc(max_size_of_constraint*(nnsp_addone+nnsp_size)*sizeof(PetscScalar),&temp_basis);CHKERRQ(ierr); 848*3b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 849*3b03a366Sstefano_zampini ierr = PetscMalloc(3*max_n*sizeof(PetscReal),&rwork);CHKERRQ(ierr); 850*3b03a366Sstefano_zampini #endif 851*3b03a366Sstefano_zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 852*3b03a366Sstefano_zampini Bt = PetscBLASIntCast(max_n); 853*3b03a366Sstefano_zampini lwork=-1; 854*3b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 855*3b03a366Sstefano_zampini LAPACKsyev_("V","U",&Bt,correlation_mat,&Bt,singular_vals,&temp_work,&lwork,&lierr); 856*3b03a366Sstefano_zampini #else 857*3b03a366Sstefano_zampini LAPACKsyev_("V","U",&Bt,correlation_mat,&Bt,singular_vals,&temp_work,&lwork,rwork,&lierr); 858*3b03a366Sstefano_zampini #endif 859*3b03a366Sstefano_zampini #else /* on missing GESVD */ 860*3b03a366Sstefano_zampini /* SVD */ 861*3b03a366Sstefano_zampini PetscInt max_n,min_n; 862*3b03a366Sstefano_zampini max_n = max_size_of_constraint; 863*3b03a366Sstefano_zampini min_n = nnsp_addone+nnsp_size; 864*3b03a366Sstefano_zampini if(max_size_of_constraint < ( nnsp_addone+nnsp_size ) ) { 865*3b03a366Sstefano_zampini min_n = max_size_of_constraint; 866*3b03a366Sstefano_zampini max_n = nnsp_addone+nnsp_size; 867*3b03a366Sstefano_zampini } 868*3b03a366Sstefano_zampini ierr = PetscMalloc(min_n*sizeof(PetscReal),&singular_vals);CHKERRQ(ierr); 869*3b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 870*3b03a366Sstefano_zampini ierr = PetscMalloc(5*min_n*sizeof(PetscReal),&rwork);CHKERRQ(ierr); 871*3b03a366Sstefano_zampini #endif 872*3b03a366Sstefano_zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 873*3b03a366Sstefano_zampini lwork=-1; 874*3b03a366Sstefano_zampini Bs = PetscBLASIntCast(max_n); 875*3b03a366Sstefano_zampini Bt = PetscBLASIntCast(min_n); 876*3b03a366Sstefano_zampini dummy_int = Bs; 877*3b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 878*3b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[0],&Bs,singular_vals, 879*3b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,&temp_work,&lwork,&lierr); 880*3b03a366Sstefano_zampini #else 881*3b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[0],&Bs,singular_vals, 882*3b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,&temp_work,&lwork,rwork,&lierr); 883*3b03a366Sstefano_zampini #endif 884*3b03a366Sstefano_zampini if ( lierr ) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SVD Lapack routine %d",(int)lierr); 885*3b03a366Sstefano_zampini #endif 886*3b03a366Sstefano_zampini /* Allocate optimal workspace */ 887*3b03a366Sstefano_zampini lwork = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work)); 888*3b03a366Sstefano_zampini total_counts = (PetscInt)lwork; 889*3b03a366Sstefano_zampini ierr = PetscMalloc(total_counts*sizeof(PetscScalar),&work);CHKERRQ(ierr); 890*3b03a366Sstefano_zampini } 891*3b03a366Sstefano_zampini /* get local part of global near null space vectors */ 892*3b03a366Sstefano_zampini ierr = PetscMalloc(nnsp_size*sizeof(Vec),&localnearnullsp);CHKERRQ(ierr); 893*3b03a366Sstefano_zampini for(k=0;k<nnsp_size;k++) { 894*3b03a366Sstefano_zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 895*3b03a366Sstefano_zampini ierr = VecScatterBegin(matis->ctx,pc->pmat->nearnullsp->vecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 896*3b03a366Sstefano_zampini ierr = VecScatterEnd (matis->ctx,pc->pmat->nearnullsp->vecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 897*3b03a366Sstefano_zampini } 898*3b03a366Sstefano_zampini /* Now we can loop on constraining sets */ 899*3b03a366Sstefano_zampini total_counts=0; 900*3b03a366Sstefano_zampini temp_indices[0]=0; 901*3b03a366Sstefano_zampini for(i=0;i<pcbddc->n_ISForEdges+pcbddc->n_ISForFaces;i++){ 902*3b03a366Sstefano_zampini if(i<pcbddc->n_ISForEdges){ 903*3b03a366Sstefano_zampini used_IS = &pcbddc->ISForEdges[i]; 904*3b03a366Sstefano_zampini } else { 905*3b03a366Sstefano_zampini used_IS = &pcbddc->ISForFaces[i-pcbddc->n_ISForEdges]; 906*3b03a366Sstefano_zampini } 907*3b03a366Sstefano_zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 908*3b03a366Sstefano_zampini temp_start_ptr = total_counts; /* need to know the starting index of constraints stored */ 909*3b03a366Sstefano_zampini ierr = ISGetSize(*used_IS,&size_of_constraint);CHKERRQ(ierr); 910*3b03a366Sstefano_zampini ierr = ISGetIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 911*3b03a366Sstefano_zampini if(nnsp_has_cnst) { 912*3b03a366Sstefano_zampini temp_constraints++; 913*3b03a366Sstefano_zampini quad_value = 1.0/PetscSqrtReal((PetscReal)size_of_constraint); 914*3b03a366Sstefano_zampini for(j=0;j<size_of_constraint;j++) { 915*3b03a366Sstefano_zampini temp_indices_to_constraint[temp_indices[total_counts]+j]=is_indices[j]; 916*3b03a366Sstefano_zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=quad_value; 917*3b03a366Sstefano_zampini } 918*3b03a366Sstefano_zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 919*3b03a366Sstefano_zampini total_counts++; 920*3b03a366Sstefano_zampini } 921*3b03a366Sstefano_zampini for(k=0;k<nnsp_size;k++) { 922*3b03a366Sstefano_zampini temp_constraints++; 923*3b03a366Sstefano_zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array_vector);CHKERRQ(ierr); 924*3b03a366Sstefano_zampini for(j=0;j<size_of_constraint;j++) { 925*3b03a366Sstefano_zampini temp_indices_to_constraint[temp_indices[total_counts]+j]=is_indices[j]; 926*3b03a366Sstefano_zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=array_vector[is_indices[j]]; 927*3b03a366Sstefano_zampini } 928*3b03a366Sstefano_zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array_vector);CHKERRQ(ierr); 929*3b03a366Sstefano_zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 930*3b03a366Sstefano_zampini total_counts++; 931*3b03a366Sstefano_zampini } 932*3b03a366Sstefano_zampini ierr = ISRestoreIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 933*3b03a366Sstefano_zampini /* perform SVD on the constraint if use true has not be requested by the user */ 934*3b03a366Sstefano_zampini if(!use_nnsp_true) { 935*3b03a366Sstefano_zampini Bs = PetscBLASIntCast(size_of_constraint); 936*3b03a366Sstefano_zampini Bt = PetscBLASIntCast(temp_constraints); 937*3b03a366Sstefano_zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 938*3b03a366Sstefano_zampini ierr = PetscMemzero(correlation_mat,Bt*Bt*sizeof(PetscScalar));CHKERRQ(ierr); 939*3b03a366Sstefano_zampini /* Store upper triangular part of correlation matrix */ 940*3b03a366Sstefano_zampini for(j=0;j<temp_constraints;j++) { 941*3b03a366Sstefano_zampini for(k=0;k<j+1;k++) { 942*3b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 943*3b03a366Sstefano_zampini /* hand made complex dot product */ 944*3b03a366Sstefano_zampini dot_result = 0.0; 945*3b03a366Sstefano_zampini for (ii=0; ii<size_of_constraint; ii++) { 946*3b03a366Sstefano_zampini val1 = temp_quadrature_constraint[temp_indices[temp_start_ptr+j]+ii]; 947*3b03a366Sstefano_zampini val2 = temp_quadrature_constraint[temp_indices[temp_start_ptr+k]+ii]; 948*3b03a366Sstefano_zampini dot_result += val1*PetscConj(val2); 949*3b03a366Sstefano_zampini } 950*3b03a366Sstefano_zampini #else 951*3b03a366Sstefano_zampini dot_result = BLASdot_(&Bs,&temp_quadrature_constraint[temp_indices[temp_start_ptr+j]],&Bone, 952*3b03a366Sstefano_zampini &temp_quadrature_constraint[temp_indices[temp_start_ptr+k]],&Bone); 953*3b03a366Sstefano_zampini #endif 954*3b03a366Sstefano_zampini correlation_mat[j*temp_constraints+k]=dot_result; 955*3b03a366Sstefano_zampini } 956*3b03a366Sstefano_zampini } 957*3b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 958*3b03a366Sstefano_zampini LAPACKsyev_("V","U",&Bt,correlation_mat,&Bt,singular_vals,work,&lwork,&lierr); 959*3b03a366Sstefano_zampini #else 960*3b03a366Sstefano_zampini LAPACKsyev_("V","U",&Bt,correlation_mat,&Bt,singular_vals,work,&lwork,rwork,&lierr); 961*3b03a366Sstefano_zampini #endif 962*3b03a366Sstefano_zampini if ( lierr ) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in EV Lapack routine %d",(int)lierr); 963*3b03a366Sstefano_zampini /* retain eigenvalues greater than tol: note that lapack SYEV gives eigs in ascending order */ 964*3b03a366Sstefano_zampini j=0; 965*3b03a366Sstefano_zampini while( j < Bt && singular_vals[j] < tol) j++; 966*3b03a366Sstefano_zampini total_counts=total_counts-j; 967*3b03a366Sstefano_zampini if(j<temp_constraints) { 968*3b03a366Sstefano_zampini for(k=j;k<Bt;k++) { singular_vals[k]=1.0/PetscSqrtReal(singular_vals[k]); } 969*3b03a366Sstefano_zampini BLASgemm_("N","N",&Bs,&Bt,&Bt,&one,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Bs,correlation_mat,&Bt,&zero,temp_basis,&Bs); 970*3b03a366Sstefano_zampini /* copy POD basis into used quadrature memory */ 971*3b03a366Sstefano_zampini for(k=0;k<Bt-j;k++) { 972*3b03a366Sstefano_zampini for(ii=0;ii<size_of_constraint;ii++) { 973*3b03a366Sstefano_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]; 974*3b03a366Sstefano_zampini } 975*3b03a366Sstefano_zampini } 976*3b03a366Sstefano_zampini } 977*3b03a366Sstefano_zampini #else /* on missing GESVD */ 978*3b03a366Sstefano_zampini PetscInt min_n = temp_constraints; 979*3b03a366Sstefano_zampini if(min_n > size_of_constraint) min_n = size_of_constraint; 980*3b03a366Sstefano_zampini dummy_int = Bs; 981*3b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 982*3b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Bs,singular_vals, 983*3b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,work,&lwork,&lierr); 984*3b03a366Sstefano_zampini #else 985*3b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Bs,singular_vals, 986*3b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,work,&lwork,rwork,&lierr); 987*3b03a366Sstefano_zampini #endif 988*3b03a366Sstefano_zampini if ( lierr ) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SVD Lapack routine %d",(int)lierr); 989*3b03a366Sstefano_zampini /* retain eigenvalues greater than tol: note that lapack SVD gives eigs in descending order */ 990*3b03a366Sstefano_zampini j=0; 991*3b03a366Sstefano_zampini while( j < min_n && singular_vals[min_n-j-1] < tol) j++; 992*3b03a366Sstefano_zampini total_counts = total_counts-(PetscInt)Bt+(min_n-j); 993*3b03a366Sstefano_zampini #endif 994*3b03a366Sstefano_zampini } 995*3b03a366Sstefano_zampini } 996*3b03a366Sstefano_zampini n_constraints=total_counts; 997*3b03a366Sstefano_zampini ierr = ISGetSize(pcbddc->ISForVertices,&n_vertices);CHKERRQ(ierr); 998*3b03a366Sstefano_zampini local_primal_size = n_vertices+n_constraints; 999*3b03a366Sstefano_zampini ierr = PetscMalloc(local_primal_size*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 1000*3b03a366Sstefano_zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 1001*3b03a366Sstefano_zampini ierr = MatSetType(pcbddc->ConstraintMatrix,impMatType);CHKERRQ(ierr); 1002*3b03a366Sstefano_zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,local_primal_size,pcis->n,local_primal_size,pcis->n);CHKERRQ(ierr); 1003*3b03a366Sstefano_zampini for(i=0;i<n_vertices;i++) { nnz[i]= 1; } 1004*3b03a366Sstefano_zampini for(i=0;i<n_constraints;i++) { nnz[i+n_vertices]=temp_indices[i+1]-temp_indices[i]; } 1005*3b03a366Sstefano_zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 1006*3b03a366Sstefano_zampini ierr = ISGetIndices(pcbddc->ISForVertices,(const PetscInt**)&vertices);CHKERRQ(ierr); 1007*3b03a366Sstefano_zampini for(i=0;i<n_vertices;i++) { ierr = MatSetValue(pcbddc->ConstraintMatrix,i,vertices[i],1.0,INSERT_VALUES);CHKERRQ(ierr); } 1008*3b03a366Sstefano_zampini ierr = ISRestoreIndices(pcbddc->ISForVertices,(const PetscInt**)&vertices);CHKERRQ(ierr); 1009*3b03a366Sstefano_zampini for(i=0;i<n_constraints;i++) { 1010*3b03a366Sstefano_zampini j=i+n_vertices; 1011*3b03a366Sstefano_zampini size_of_constraint=temp_indices[i+1]-temp_indices[i]; 1012*3b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&j,size_of_constraint,&temp_indices_to_constraint[temp_indices[i]],&temp_quadrature_constraint[temp_indices[i]],INSERT_VALUES);CHKERRQ(ierr); 1013*3b03a366Sstefano_zampini } 1014*3b03a366Sstefano_zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1015*3b03a366Sstefano_zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1016*3b03a366Sstefano_zampini /* set quantities in pcbddc data structure */ 1017*3b03a366Sstefano_zampini pcbddc->n_vertices = n_vertices; 1018*3b03a366Sstefano_zampini pcbddc->n_constraints = n_constraints; 1019*3b03a366Sstefano_zampini pcbddc->local_primal_size = n_vertices+n_constraints; 1020*3b03a366Sstefano_zampini /* free workspace no longer needed */ 1021*3b03a366Sstefano_zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 1022*3b03a366Sstefano_zampini ierr = PetscFree(work);CHKERRQ(ierr); 1023*3b03a366Sstefano_zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 1024*3b03a366Sstefano_zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 1025*3b03a366Sstefano_zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 1026*3b03a366Sstefano_zampini ierr = PetscFree(temp_indices);CHKERRQ(ierr); 1027*3b03a366Sstefano_zampini ierr = PetscFree(temp_indices_to_constraint);CHKERRQ(ierr); 1028*3b03a366Sstefano_zampini ierr = PetscFree(temp_quadrature_constraint);CHKERRQ(ierr); 1029*3b03a366Sstefano_zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 1030*3b03a366Sstefano_zampini for(k=0;k<nnsp_size;k++) { ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); } 1031*3b03a366Sstefano_zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 1032*3b03a366Sstefano_zampini PetscFunctionReturn(0); 1033*3b03a366Sstefano_zampini } 1034*3b03a366Sstefano_zampini #ifdef BDDC_USE_POD 1035*3b03a366Sstefano_zampini #undef PETSC_MISSING_LAPACK_GESVD 1036*3b03a366Sstefano_zampini #endif 1037*3b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 1038*3b03a366Sstefano_zampini /* 10390c7d97c5SJed Brown PCBDDCCoarseSetUp - 10400c7d97c5SJed Brown */ 10410c7d97c5SJed Brown #undef __FUNCT__ 10420c7d97c5SJed Brown #define __FUNCT__ "PCBDDCCoarseSetUp" 104353cdbc3dSStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC pc) 10440c7d97c5SJed Brown { 10450c7d97c5SJed Brown PetscErrorCode ierr; 10460c7d97c5SJed Brown 10470c7d97c5SJed Brown PC_IS* pcis = (PC_IS*)(pc->data); 10480c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 10490c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 10500c7d97c5SJed Brown IS is_R_local; 10510c7d97c5SJed Brown IS is_V_local; 10520c7d97c5SJed Brown IS is_C_local; 10530c7d97c5SJed Brown IS is_aux1; 10540c7d97c5SJed Brown IS is_aux2; 10550c7d97c5SJed Brown const VecType impVecType; 10560c7d97c5SJed Brown const MatType impMatType; 10570c7d97c5SJed Brown PetscInt n_R=0; 10580c7d97c5SJed Brown PetscInt n_D=0; 10590c7d97c5SJed Brown PetscInt n_B=0; 10600c7d97c5SJed Brown PetscMPIInt totprocs; 10610c7d97c5SJed Brown PetscScalar zero=0.0; 10620c7d97c5SJed Brown PetscScalar one=1.0; 10630c7d97c5SJed Brown PetscScalar m_one=-1.0; 10640c7d97c5SJed Brown PetscScalar* array; 10650c7d97c5SJed Brown PetscScalar *coarse_submat_vals; 10660c7d97c5SJed Brown PetscInt *idx_R_local; 10670c7d97c5SJed Brown PetscInt *idx_V_B; 10680c7d97c5SJed Brown PetscScalar *coarsefunctions_errors; 10690c7d97c5SJed Brown PetscScalar *constraints_errors; 10700c7d97c5SJed Brown /* auxiliary indices */ 10710c7d97c5SJed Brown PetscInt s,i,j,k; 1072e269702eSStefano Zampini /* for verbose output of bddc */ 1073e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 1074e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 1075a0ba757dSStefano Zampini /* for counting coarse dofs */ 1076a0ba757dSStefano Zampini PetscScalar coarsesum; 1077*3b03a366Sstefano_zampini PetscInt n_vertices=pcbddc->n_vertices,n_constraints=pcbddc->n_constraints; 1078*3b03a366Sstefano_zampini PetscInt size_of_constraint; 1079*3b03a366Sstefano_zampini PetscInt *row_cmat_indices; 1080*3b03a366Sstefano_zampini PetscScalar *row_cmat_values; 1081*3b03a366Sstefano_zampini const PetscInt *vertices; 10820c7d97c5SJed Brown 10830c7d97c5SJed Brown PetscFunctionBegin; 10840c7d97c5SJed Brown /* Set Non-overlapping dimensions */ 10850c7d97c5SJed Brown n_B = pcis->n_B; n_D = pcis->n - n_B; 1086*3b03a366Sstefano_zampini ierr = ISGetIndices(pcbddc->ISForVertices,&vertices);CHKERRQ(ierr); 1087a0ba757dSStefano Zampini /* First let's count coarse dofs: note that we allow to have a constraint on a subdomain and not its counterpart on the neighbour subdomain (if user wants) */ 1088a0ba757dSStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 1089a0ba757dSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1090*3b03a366Sstefano_zampini for(i=0;i<n_vertices;i++) { array[ vertices[i] ] = one; } 1091*3b03a366Sstefano_zampini 1092*3b03a366Sstefano_zampini for(i=0;i<n_constraints;i++) { 1093*3b03a366Sstefano_zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,n_vertices+i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 1094*3b03a366Sstefano_zampini for (j=0; j<size_of_constraint; j++) { 1095*3b03a366Sstefano_zampini k = row_cmat_indices[j]; 1096a0ba757dSStefano Zampini if( array[k] == zero ) { 1097a0ba757dSStefano Zampini array[k] = one; 1098a0ba757dSStefano Zampini break; 1099a0ba757dSStefano Zampini } 1100a0ba757dSStefano Zampini } 1101*3b03a366Sstefano_zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,n_vertices+i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 1102a0ba757dSStefano Zampini } 1103a0ba757dSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1104a0ba757dSStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 1105a0ba757dSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1106a0ba757dSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1107a0ba757dSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1108a0ba757dSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1109a0ba757dSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1110a0ba757dSStefano Zampini for(i=0;i<pcis->n;i++) { if( array[i] > zero) array[i] = one/array[i]; } 1111a0ba757dSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1112a0ba757dSStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 1113a0ba757dSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1114a0ba757dSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1115a0ba757dSStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 1116a0ba757dSStefano Zampini pcbddc->coarse_size = (PetscInt) coarsesum; 1117a0ba757dSStefano Zampini 11180c7d97c5SJed Brown /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 11190c7d97c5SJed Brown ierr = VecSet(pcis->vec1_N,one);CHKERRQ(ierr); 11200c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1121*3b03a366Sstefano_zampini for (i=0;i<n_vertices;i++) { array[ vertices[i] ] = zero; } 1122*3b03a366Sstefano_zampini ierr = PetscMalloc(( pcis->n - n_vertices )*sizeof(PetscInt),&idx_R_local);CHKERRQ(ierr); 11230c7d97c5SJed Brown for (i=0, n_R=0; i<pcis->n; i++) { if (array[i] == one) { idx_R_local[n_R] = i; n_R++; } } 11240c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1125e269702eSStefano Zampini if(dbg_flag) { 11260c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 11270c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 11280c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 11290c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 1130*3b03a366Sstefano_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); 11310c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1132a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1133a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem = %d (%f)\n",pcbddc->coarse_size,coarsesum);CHKERRQ(ierr); 1134a0ba757dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 11350c7d97c5SJed Brown } 11360c7d97c5SJed Brown /* Allocate needed vectors */ 11370c7d97c5SJed Brown /* Set Mat type for local matrices needed by BDDC precondtioner */ 11380c7d97c5SJed Brown impMatType = MATSEQDENSE; 11390c7d97c5SJed Brown impVecType = VECSEQ; 11400c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_D,&pcbddc->vec4_D);CHKERRQ(ierr); 11410c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_N,&pcis->vec2_N);CHKERRQ(ierr); 11420c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_R);CHKERRQ(ierr); 11430c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_R,n_R,n_R);CHKERRQ(ierr); 11440c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 1145d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 11460c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_P);CHKERRQ(ierr); 11470c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_P,pcbddc->local_primal_size,pcbddc->local_primal_size);CHKERRQ(ierr); 11480c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 11490c7d97c5SJed Brown 11500c7d97c5SJed Brown /* Creating some index sets needed */ 11510c7d97c5SJed Brown /* For submatrices */ 11520c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,n_R,idx_R_local,PETSC_COPY_VALUES,&is_R_local);CHKERRQ(ierr); 1153*3b03a366Sstefano_zampini if(n_vertices) { 1154*3b03a366Sstefano_zampini ierr = ISDuplicate(pcbddc->ISForVertices,&is_V_local);CHKERRQ(ierr); 1155*3b03a366Sstefano_zampini ierr = ISCopy(pcbddc->ISForVertices,is_V_local);CHKERRQ(ierr); 1156*3b03a366Sstefano_zampini } 1157*3b03a366Sstefano_zampini if(n_constraints) { ierr = ISCreateStride (PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_C_local);CHKERRQ(ierr); } 11580c7d97c5SJed Brown /* For VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 11590c7d97c5SJed Brown { 11600c7d97c5SJed Brown PetscInt *aux_array1; 11610c7d97c5SJed Brown PetscInt *aux_array2; 11620c7d97c5SJed Brown PetscScalar value; 11630c7d97c5SJed Brown 1164*3b03a366Sstefano_zampini ierr = PetscMalloc( (pcis->n_B-n_vertices)*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 1165*3b03a366Sstefano_zampini ierr = PetscMalloc( (pcis->n_B-n_vertices)*sizeof(PetscInt),&aux_array2);CHKERRQ(ierr); 11660c7d97c5SJed Brown 1167d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 11680c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 11690c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 11700c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11710c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11720c7d97c5SJed Brown ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11730c7d97c5SJed Brown ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11740c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 11750c7d97c5SJed Brown for (i=0, s=0; i<n_R; i++) { if (array[idx_R_local[i]] > one) { aux_array1[s] = i; s++; } } 11760c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 11770c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 11780c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 11790c7d97c5SJed Brown for (i=0, s=0; i<n_B; i++) { if (array[i] > one) { aux_array2[s] = i; s++; } } 11803828260eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 11810c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array2,PETSC_COPY_VALUES,&is_aux2);CHKERRQ(ierr); 11820c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 11830c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 11840c7d97c5SJed Brown ierr = PetscFree(aux_array2);CHKERRQ(ierr); 11850c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 11860c7d97c5SJed Brown ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 11870c7d97c5SJed Brown 1188e269702eSStefano Zampini if(pcbddc->prec_type || dbg_flag ) { 11890c7d97c5SJed Brown ierr = PetscMalloc(n_D*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 11900c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 11910c7d97c5SJed Brown for (i=0, s=0; i<n_R; i++) { if (array[idx_R_local[i]] == one) { aux_array1[s] = i; s++; } } 11920c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 11930c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 11940c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 11950c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 11960c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 11970c7d97c5SJed Brown } 11980c7d97c5SJed Brown 11990c7d97c5SJed Brown /* Check scatters */ 1200e269702eSStefano Zampini if(dbg_flag) { 12010c7d97c5SJed Brown 12020c7d97c5SJed Brown Vec vec_aux; 12030c7d97c5SJed Brown 12040c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 12050c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Checking pcbddc->R_to_B scatter\n");CHKERRQ(ierr); 12060c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1207d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 1208d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_B,PETSC_NULL);CHKERRQ(ierr); 1209d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&vec_aux);CHKERRQ(ierr); 1210d49ef151SStefano Zampini ierr = VecCopy(pcbddc->vec1_R,vec_aux);CHKERRQ(ierr); 1211d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1212d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1213d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1214d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1215d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 1216d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 12170c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_B FORWARD error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 1218d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 12190c7d97c5SJed Brown 1220d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 1221d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_B,PETSC_NULL);CHKERRQ(ierr); 1222d49ef151SStefano Zampini ierr = VecDuplicate(pcis->vec1_B,&vec_aux);CHKERRQ(ierr); 1223d49ef151SStefano Zampini ierr = VecCopy(pcis->vec1_B,vec_aux);CHKERRQ(ierr); 1224d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1225d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1226d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1227d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1228d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcis->vec1_B);CHKERRQ(ierr); 1229d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 12300c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_B REVERSE error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 1231d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 12320c7d97c5SJed Brown 12330c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 12340c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Checking pcbddc->R_to_D scatter\n");CHKERRQ(ierr); 12350c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 12360c7d97c5SJed Brown 1237d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 1238d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL);CHKERRQ(ierr); 1239d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&vec_aux);CHKERRQ(ierr); 1240d49ef151SStefano Zampini ierr = VecCopy(pcbddc->vec1_R,vec_aux);CHKERRQ(ierr); 1241d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1242d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1243d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1244d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1245d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 1246d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 12470c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_D FORWARD error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 1248d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 12490c7d97c5SJed Brown 1250d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 1251d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL);CHKERRQ(ierr); 1252d49ef151SStefano Zampini ierr = VecDuplicate(pcis->vec1_D,&vec_aux);CHKERRQ(ierr); 1253d49ef151SStefano Zampini ierr = VecCopy(pcis->vec1_D,vec_aux);CHKERRQ(ierr); 1254d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1255d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1256d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1257d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1258d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcis->vec1_D);CHKERRQ(ierr); 1259d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 12600c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_D REVERSE error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 1261d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 12620c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 12630c7d97c5SJed Brown 12640c7d97c5SJed Brown } 12650c7d97c5SJed Brown } 12660c7d97c5SJed Brown 12670c7d97c5SJed Brown /* vertices in boundary numbering */ 1268*3b03a366Sstefano_zampini if(n_vertices) { 1269d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,m_one);CHKERRQ(ierr); 12700c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1271*3b03a366Sstefano_zampini for (i=0; i<n_vertices; i++) { array[ vertices[i] ] = i; } 12720c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1273d49ef151SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1274d49ef151SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1275*3b03a366Sstefano_zampini ierr = PetscMalloc(n_vertices*sizeof(PetscInt),&idx_V_B);CHKERRQ(ierr); 12760c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1277*3b03a366Sstefano_zampini for (i=0; i<n_vertices; i++) { 12780c7d97c5SJed Brown s=0; 12790c7d97c5SJed Brown while (array[s] != i ) {s++;} 12800c7d97c5SJed Brown idx_V_B[i]=s; 12810c7d97c5SJed Brown } 12820c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 12830c7d97c5SJed Brown } 12840c7d97c5SJed Brown 12850c7d97c5SJed Brown 12860c7d97c5SJed Brown /* Creating PC contexts for local Dirichlet and Neumann problems */ 12870c7d97c5SJed Brown { 12880c7d97c5SJed Brown Mat A_RR; 128953cdbc3dSStefano Zampini PC pc_temp; 12900c7d97c5SJed Brown /* Matrix for Dirichlet problem is A_II -> we already have it from pcis.c code */ 129153cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 129253cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 129353cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II,SAME_PRECONDITIONER);CHKERRQ(ierr); 129453cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 1295a0ba757dSStefano Zampini //ierr = KSPSetOptionsPrefix();CHKERRQ(ierr); 12960c7d97c5SJed Brown /* default */ 129753cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 129853cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 12990c7d97c5SJed Brown /* Allow user's customization */ 130053cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 130153cdbc3dSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 130253cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 13030c7d97c5SJed Brown /* Matrix for Neumann problem is A_RR -> we need to create it */ 13040c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_R_local,is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 130553cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 130653cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 130753cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR,SAME_PRECONDITIONER);CHKERRQ(ierr); 130853cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 1309a0ba757dSStefano Zampini //ierr = KSPSetOptionsPrefix();CHKERRQ(ierr); 13100c7d97c5SJed Brown /* default */ 131153cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 131253cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 13130c7d97c5SJed Brown /* Allow user's customization */ 131453cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 131553cdbc3dSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 131653cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 1317a0ba757dSStefano Zampini /* check Dirichlet and Neumann solvers */ 1318e269702eSStefano Zampini if(pcbddc->dbg_flag) { 13190c7d97c5SJed Brown Vec temp_vec; 13200c7d97c5SJed Brown PetscScalar value; 13210c7d97c5SJed Brown 1322a0ba757dSStefano Zampini ierr = VecDuplicate(pcis->vec1_D,&temp_vec);CHKERRQ(ierr); 1323a0ba757dSStefano Zampini ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL);CHKERRQ(ierr); 1324a0ba757dSStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 1325a0ba757dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,temp_vec);CHKERRQ(ierr); 1326a0ba757dSStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcis->vec1_D);CHKERRQ(ierr); 1327a0ba757dSStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 1328a0ba757dSStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1329a0ba757dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1330a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1331a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Checking solution of Dirichlet and Neumann problems\n");CHKERRQ(ierr); 1332a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Dirichlet solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 1333d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&temp_vec);CHKERRQ(ierr); 1334d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 1335d49ef151SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 1336d49ef151SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,temp_vec);CHKERRQ(ierr); 1337d49ef151SStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 1338d49ef151SStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 1339e269702eSStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 13400c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Neumann solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 1341d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 13420c7d97c5SJed Brown } 13430c7d97c5SJed Brown /* free Neumann problem's matrix */ 13440c7d97c5SJed Brown ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 13450c7d97c5SJed Brown } 13460c7d97c5SJed Brown 13470c7d97c5SJed Brown /* Assemble all remaining stuff needed to apply BDDC */ 13480c7d97c5SJed Brown { 13490c7d97c5SJed Brown Mat A_RV,A_VR,A_VV; 13500c7d97c5SJed Brown Mat M1,M2; 13510c7d97c5SJed Brown Mat C_CR; 1352*3b03a366Sstefano_zampini Mat AUXMAT; 13530c7d97c5SJed Brown Vec vec1_C; 13540c7d97c5SJed Brown Vec vec2_C; 13550c7d97c5SJed Brown Vec vec1_V; 13560c7d97c5SJed Brown Vec vec2_V; 13570c7d97c5SJed Brown PetscInt *nnz; 13580c7d97c5SJed Brown PetscInt *auxindices; 135953cdbc3dSStefano Zampini PetscInt index; 13600c7d97c5SJed Brown PetscScalar* array2; 13610c7d97c5SJed Brown MatFactorInfo matinfo; 13620c7d97c5SJed Brown 13630c7d97c5SJed Brown /* Allocating some extra storage just to be safe */ 13640c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 13650c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&auxindices);CHKERRQ(ierr); 13660c7d97c5SJed Brown for(i=0;i<pcis->n;i++) {auxindices[i]=i;} 13670c7d97c5SJed Brown 13680c7d97c5SJed Brown /* some work vectors on vertices and/or constraints */ 1369*3b03a366Sstefano_zampini if(n_vertices) { 13700c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_V);CHKERRQ(ierr); 1371*3b03a366Sstefano_zampini ierr = VecSetSizes(vec1_V,n_vertices,n_vertices);CHKERRQ(ierr); 13720c7d97c5SJed Brown ierr = VecSetType(vec1_V,impVecType);CHKERRQ(ierr); 13730c7d97c5SJed Brown ierr = VecDuplicate(vec1_V,&vec2_V);CHKERRQ(ierr); 13740c7d97c5SJed Brown } 13750c7d97c5SJed Brown if(pcbddc->n_constraints) { 13760c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_C);CHKERRQ(ierr); 13770c7d97c5SJed Brown ierr = VecSetSizes(vec1_C,pcbddc->n_constraints,pcbddc->n_constraints);CHKERRQ(ierr); 13780c7d97c5SJed Brown ierr = VecSetType(vec1_C,impVecType);CHKERRQ(ierr); 13790c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&vec2_C);CHKERRQ(ierr); 13800c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&pcbddc->vec1_C);CHKERRQ(ierr); 13810c7d97c5SJed Brown } 13820c7d97c5SJed Brown /* Precompute stuffs needed for preprocessing and application of BDDC*/ 1383*3b03a366Sstefano_zampini if(n_constraints) { 13840c7d97c5SJed Brown /* some work vectors */ 13850c7d97c5SJed Brown ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->local_auxmat2);CHKERRQ(ierr); 1386*3b03a366Sstefano_zampini ierr = MatSetSizes(pcbddc->local_auxmat2,n_R,n_constraints,n_R,n_constraints);CHKERRQ(ierr); 13870c7d97c5SJed Brown ierr = MatSetType(pcbddc->local_auxmat2,impMatType);CHKERRQ(ierr); 1388*3b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(pcbddc->local_auxmat2,PETSC_NULL);CHKERRQ(ierr); 13890c7d97c5SJed Brown 13900c7d97c5SJed Brown /* Assemble local_auxmat2 = - A_{RR}^{-1} C^T_{CR} needed by BDDC application */ 1391*3b03a366Sstefano_zampini for(i=0;i<n_constraints;i++) { 1392d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 1393*3b03a366Sstefano_zampini ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 1394*3b03a366Sstefano_zampini /* Get row of constraint matrix in R numbering */ 13950c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1396*3b03a366Sstefano_zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,n_vertices+i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 1397*3b03a366Sstefano_zampini for(j=0;j<size_of_constraint;j++) { array[ row_cmat_indices[j] ] = - row_cmat_values[j]; } 1398*3b03a366Sstefano_zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,n_vertices+i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 13990c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 14000c7d97c5SJed Brown for(j=0;j<n_R;j++) { array2[j] = array[ idx_R_local[j] ]; } 14010c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14020c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 1403*3b03a366Sstefano_zampini /* Solve for row of constraint matrix in R numbering */ 140453cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 1405*3b03a366Sstefano_zampini /* Set values */ 14060c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 1407*3b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->local_auxmat2,n_R,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 14080c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 14090c7d97c5SJed Brown } 14100c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14110c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14120c7d97c5SJed Brown 14130c7d97c5SJed Brown /* Create Constraint matrix on R nodes: C_{CR} */ 1414*3b03a366Sstefano_zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_C_local,is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 14150c7d97c5SJed Brown ierr = ISDestroy(&is_C_local);CHKERRQ(ierr); 14160c7d97c5SJed Brown 14170c7d97c5SJed Brown /* Assemble AUXMAT = ( LUFactor )( -C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 14180c7d97c5SJed Brown ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AUXMAT);CHKERRQ(ierr); 1419d49ef151SStefano Zampini ierr = MatFactorInfoInitialize(&matinfo);CHKERRQ(ierr); 1420*3b03a366Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,0,1,&is_aux1);CHKERRQ(ierr); 14210c7d97c5SJed Brown ierr = MatLUFactor(AUXMAT,is_aux1,is_aux1,&matinfo);CHKERRQ(ierr); 14220c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 14230c7d97c5SJed Brown 1424*3b03a366Sstefano_zampini /* Assemble explicitly M1 = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} needed in preproc */ 1425d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M1);CHKERRQ(ierr); 1426*3b03a366Sstefano_zampini ierr = MatSetSizes(M1,n_constraints,n_constraints,n_constraints,n_constraints);CHKERRQ(ierr); 14270c7d97c5SJed Brown ierr = MatSetType(M1,impMatType);CHKERRQ(ierr); 1428*3b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(M1,PETSC_NULL);CHKERRQ(ierr); 1429*3b03a366Sstefano_zampini for(i=0;i<n_constraints;i++) { 14300c7d97c5SJed Brown ierr = VecSet(vec1_C,zero);CHKERRQ(ierr); 14310c7d97c5SJed Brown ierr = VecSetValue(vec1_C,i,one,INSERT_VALUES);CHKERRQ(ierr); 14320c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_C);CHKERRQ(ierr); 14330c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_C);CHKERRQ(ierr); 14340c7d97c5SJed Brown ierr = MatSolve(AUXMAT,vec1_C,vec2_C);CHKERRQ(ierr); 14350c7d97c5SJed Brown ierr = VecScale(vec2_C,m_one);CHKERRQ(ierr); 14360c7d97c5SJed Brown ierr = VecGetArray(vec2_C,&array);CHKERRQ(ierr); 1437*3b03a366Sstefano_zampini ierr = MatSetValues(M1,n_constraints,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 14380c7d97c5SJed Brown ierr = VecRestoreArray(vec2_C,&array);CHKERRQ(ierr); 14390c7d97c5SJed Brown } 14400c7d97c5SJed Brown ierr = MatAssemblyBegin(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14410c7d97c5SJed Brown ierr = MatAssemblyEnd(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14420c7d97c5SJed Brown ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 14430c7d97c5SJed Brown /* Assemble local_auxmat1 = M1*C_{CR} needed by BDDC application in KSP and in preproc */ 14440c7d97c5SJed Brown ierr = MatMatMult(M1,C_CR,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 14450c7d97c5SJed Brown 14460c7d97c5SJed Brown } 14470c7d97c5SJed Brown 14480c7d97c5SJed Brown /* Get submatrices from subdomain matrix */ 1449*3b03a366Sstefano_zampini if(n_vertices){ 14500c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_R_local,is_V_local,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 14510c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_V_local,is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 14520c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_V_local,is_V_local,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 14530c7d97c5SJed Brown /* Assemble M2 = A_RR^{-1}A_RV */ 1454d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M2);CHKERRQ(ierr); 1455*3b03a366Sstefano_zampini ierr = MatSetSizes(M2,n_R,n_vertices,n_R,n_vertices);CHKERRQ(ierr); 14560c7d97c5SJed Brown ierr = MatSetType(M2,impMatType);CHKERRQ(ierr); 1457*3b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(M2,PETSC_NULL);CHKERRQ(ierr); 1458*3b03a366Sstefano_zampini for(i=0;i<n_vertices;i++) { 14590c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 14600c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 14610c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 14620c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 14630c7d97c5SJed Brown ierr = MatMult(A_RV,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 146453cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 14650c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 1466*3b03a366Sstefano_zampini ierr = MatSetValues(M2,n_R,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 14670c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 14680c7d97c5SJed Brown } 14690c7d97c5SJed Brown ierr = MatAssemblyBegin(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14700c7d97c5SJed Brown ierr = MatAssemblyEnd(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14710c7d97c5SJed Brown } 14720c7d97c5SJed Brown 14730c7d97c5SJed Brown /* Matrix of coarse basis functions (local) */ 1474d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 14750c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 14760c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_B,impMatType);CHKERRQ(ierr); 1477*3b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_phi_B,PETSC_NULL);CHKERRQ(ierr); 1478e269702eSStefano Zampini if(pcbddc->prec_type || dbg_flag ) { 1479d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 14800c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 14810c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_D,impMatType);CHKERRQ(ierr); 1482*3b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_phi_D,PETSC_NULL);CHKERRQ(ierr); 14830c7d97c5SJed Brown } 14840c7d97c5SJed Brown 1485e269702eSStefano Zampini if(dbg_flag) { 14860c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&coarsefunctions_errors);CHKERRQ(ierr); 14870c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&constraints_errors);CHKERRQ(ierr); 14880c7d97c5SJed Brown } 1489*3b03a366Sstefano_zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 14900c7d97c5SJed Brown ierr = PetscMalloc ((pcbddc->local_primal_size)*(pcbddc->local_primal_size)*sizeof(PetscScalar),&coarse_submat_vals);CHKERRQ(ierr); 14910c7d97c5SJed Brown 14920c7d97c5SJed Brown /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 1493*3b03a366Sstefano_zampini for(i=0;i<n_vertices;i++){ 14940c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 14950c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 14960c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 14970c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 14980c7d97c5SJed Brown /* solution of saddle point problem */ 14990c7d97c5SJed Brown ierr = MatMult(M2,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 15000c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_R,m_one);CHKERRQ(ierr); 1501*3b03a366Sstefano_zampini if(n_constraints) { 15020c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec1_R,vec1_C);CHKERRQ(ierr); 15030c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 15040c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 15050c7d97c5SJed Brown } 15060c7d97c5SJed Brown ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); 15070c7d97c5SJed Brown ierr = MatMultAdd(A_VV,vec1_V,vec2_V,vec2_V);CHKERRQ(ierr); 15080c7d97c5SJed Brown 15090c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 15100c7d97c5SJed Brown /* coarse basis functions */ 15110c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 15120c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15130c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15140c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1515*3b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 15160c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 15170c7d97c5SJed Brown ierr = MatSetValue(pcbddc->coarse_phi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 1518e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 15190c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15200c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15210c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 1522*3b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 15230c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 15240c7d97c5SJed Brown } 15250c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 15260c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 1527*3b03a366Sstefano_zampini for(j=0;j<n_vertices;j++) { coarse_submat_vals[i*pcbddc->local_primal_size+j] = array[j]; } //WARNING -> column major ordering 15280c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 1529*3b03a366Sstefano_zampini if(n_constraints) { 15300c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 1531*3b03a366Sstefano_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 15320c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 15330c7d97c5SJed Brown } 15340c7d97c5SJed Brown 1535e269702eSStefano Zampini if( dbg_flag ) { 15360c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 1537d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 15380c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 15390c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 15400c7d97c5SJed Brown for(j=0;j<n_R;j++) { array[idx_R_local[j]] = array2[j]; } 1541*3b03a366Sstefano_zampini array[ vertices[i] ] = one; 15420c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 15430c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 15440c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers (i.e. primal nodes) */ 1545d49ef151SStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 15460c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 15470c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 1548*3b03a366Sstefano_zampini for(j=0;j<n_vertices;j++) { array2[j]=array[j]; } 15490c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 1550*3b03a366Sstefano_zampini if(n_constraints) { 15510c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 1552*3b03a366Sstefano_zampini for(j=0;j<n_constraints;j++) { array2[j+n_vertices]=array[j]; } 15530c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 15540c7d97c5SJed Brown } 15550c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 15560c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_P,m_one);CHKERRQ(ierr); 15570c7d97c5SJed Brown /* check saddle point solution */ 15580c7d97c5SJed Brown ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 1559*3b03a366Sstefano_zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 1560*3b03a366Sstefano_zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[i]);CHKERRQ(ierr); 1561*3b03a366Sstefano_zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 15620c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 1563*3b03a366Sstefano_zampini array[i]=array[i]+m_one; /* shift by the identity matrix */ 15640c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 1565*3b03a366Sstefano_zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[i]);CHKERRQ(ierr); 15660c7d97c5SJed Brown } 15670c7d97c5SJed Brown } 15680c7d97c5SJed Brown 1569*3b03a366Sstefano_zampini for(i=0;i<n_constraints;i++){ 1570d49ef151SStefano Zampini ierr = VecSet(vec2_C,zero);CHKERRQ(ierr); 15710c7d97c5SJed Brown ierr = VecSetValue(vec2_C,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 15720c7d97c5SJed Brown ierr = VecAssemblyBegin(vec2_C);CHKERRQ(ierr); 15730c7d97c5SJed Brown ierr = VecAssemblyEnd(vec2_C);CHKERRQ(ierr); 15740c7d97c5SJed Brown /* solution of saddle point problem */ 15750c7d97c5SJed Brown ierr = MatMult(M1,vec2_C,vec1_C);CHKERRQ(ierr); 15760c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 15770c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 1578*3b03a366Sstefano_zampini if(n_vertices) { ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); } 15790c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 15800c7d97c5SJed Brown /* coarse basis functions */ 1581*3b03a366Sstefano_zampini index=i+n_vertices; 15820c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 15830c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15840c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15850c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 158653cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 15870c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1588e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 15890c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15900c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15910c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 159253cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 15930c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 15940c7d97c5SJed Brown } 15950c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 1596*3b03a366Sstefano_zampini if(n_vertices) { 15970c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 1598*3b03a366Sstefano_zampini for(j=0;j<n_vertices;j++) {coarse_submat_vals[index*pcbddc->local_primal_size+j]=array[j];} //WARNING -> column major ordering 15990c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 16000c7d97c5SJed Brown } 16010c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 1602*3b03a366Sstefano_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 16030c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 16040c7d97c5SJed Brown 1605e269702eSStefano Zampini if( dbg_flag ) { 16060c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 160753cdbc3dSStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 16080c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 16090c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 16100c7d97c5SJed Brown for(j=0;j<n_R;j++){ array[ idx_R_local[j] ] = array2[j]; } 16110c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 16120c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 16130c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers */ 161453cdbc3dSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 16150c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 1616*3b03a366Sstefano_zampini if( n_vertices) { 16170c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 1618*3b03a366Sstefano_zampini for(j=0;j<n_vertices;j++) {array2[j]=-array[j];} 16190c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 16200c7d97c5SJed Brown } 16210c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 1622*3b03a366Sstefano_zampini for(j=0;j<n_constraints;j++) {array2[j+n_vertices]=-array[j];} 16230c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 16240c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 16250c7d97c5SJed Brown /* check saddle point solution */ 16260c7d97c5SJed Brown ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 1627*3b03a366Sstefano_zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 162853cdbc3dSStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[index]);CHKERRQ(ierr); 1629*3b03a366Sstefano_zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 16300c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 163153cdbc3dSStefano Zampini array[index]=array[index]+m_one; /* shift by the identity matrix */ 16320c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 163353cdbc3dSStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[index]);CHKERRQ(ierr); 16340c7d97c5SJed Brown } 16350c7d97c5SJed Brown } 16360c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16370c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1638e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 16390c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16400c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16410c7d97c5SJed Brown } 16420c7d97c5SJed Brown /* Checking coarse_sub_mat and coarse basis functios */ 16430c7d97c5SJed Brown /* It shuld be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 16449d2fce94SStefano Zampini if(dbg_flag) { 16450c7d97c5SJed Brown 16460c7d97c5SJed Brown Mat coarse_sub_mat; 16470c7d97c5SJed Brown Mat TM1,TM2,TM3,TM4; 16480c7d97c5SJed Brown Mat coarse_phi_D,coarse_phi_B,A_II,A_BB,A_IB,A_BI; 1649a0ba757dSStefano Zampini const MatType checkmattype=MATSEQAIJ; 16500c7d97c5SJed Brown PetscScalar value; 16510c7d97c5SJed Brown 1652c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 1653c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 1654c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 1655c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 1656c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 1657c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 1658c042a7c3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 1659c042a7c3SStefano Zampini ierr = MatConvert(coarse_sub_mat,checkmattype,MAT_REUSE_MATRIX,&coarse_sub_mat);CHKERRQ(ierr); 16600c7d97c5SJed Brown 16610c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 16620c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Check coarse sub mat and local basis functions\n");CHKERRQ(ierr); 16630c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 166453cdbc3dSStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 166553cdbc3dSStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 166653cdbc3dSStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1667c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 166853cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 166953cdbc3dSStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1670c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 167153cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 167253cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 167353cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 167453cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 167553cdbc3dSStefano Zampini ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 167653cdbc3dSStefano Zampini ierr = MatNorm(TM1,NORM_INFINITY,&value);CHKERRQ(ierr); 16770c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"----------------------------------\n");CHKERRQ(ierr); 16780c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d \n",PetscGlobalRank);CHKERRQ(ierr); 16790c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"matrix error = % 1.14e\n",value);CHKERRQ(ierr); 16800c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"coarse functions errors\n");CHKERRQ(ierr); 168153cdbc3dSStefano 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); } 16820c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"constraints errors\n");CHKERRQ(ierr); 168353cdbc3dSStefano 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); } 16840c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 168553cdbc3dSStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 168653cdbc3dSStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 168753cdbc3dSStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 168853cdbc3dSStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 168953cdbc3dSStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 169053cdbc3dSStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 169153cdbc3dSStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 169253cdbc3dSStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 169353cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 169453cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 169553cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 16960c7d97c5SJed Brown ierr = PetscFree(coarsefunctions_errors);CHKERRQ(ierr); 16970c7d97c5SJed Brown ierr = PetscFree(constraints_errors);CHKERRQ(ierr); 16980c7d97c5SJed Brown } 16990c7d97c5SJed Brown 17000c7d97c5SJed Brown /* create coarse matrix and data structures for message passing associated actual choice of coarse problem type */ 17010c7d97c5SJed Brown ierr = PCBDDCSetupCoarseEnvironment(pc,coarse_submat_vals);CHKERRQ(ierr); 17020c7d97c5SJed Brown /* free memory */ 17030c7d97c5SJed Brown ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 17040c7d97c5SJed Brown ierr = PetscFree(auxindices);CHKERRQ(ierr); 17050c7d97c5SJed Brown ierr = PetscFree(nnz);CHKERRQ(ierr); 1706*3b03a366Sstefano_zampini if(n_vertices) { 17070c7d97c5SJed Brown ierr = VecDestroy(&vec1_V);CHKERRQ(ierr); 17080c7d97c5SJed Brown ierr = VecDestroy(&vec2_V);CHKERRQ(ierr); 17090c7d97c5SJed Brown ierr = MatDestroy(&M2);CHKERRQ(ierr); 17100c7d97c5SJed Brown ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 17110c7d97c5SJed Brown ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 17120c7d97c5SJed Brown ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 17130c7d97c5SJed Brown } 17140c7d97c5SJed Brown if(pcbddc->n_constraints) { 17150c7d97c5SJed Brown ierr = VecDestroy(&vec1_C);CHKERRQ(ierr); 17160c7d97c5SJed Brown ierr = VecDestroy(&vec2_C);CHKERRQ(ierr); 17170c7d97c5SJed Brown ierr = MatDestroy(&M1);CHKERRQ(ierr); 17180c7d97c5SJed Brown ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 17190c7d97c5SJed Brown } 17200c7d97c5SJed Brown } 17210c7d97c5SJed Brown /* free memory */ 1722*3b03a366Sstefano_zampini if(n_vertices) { 17230c7d97c5SJed Brown ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 17240c7d97c5SJed Brown ierr = ISDestroy(&is_V_local);CHKERRQ(ierr); 17250c7d97c5SJed Brown } 17260c7d97c5SJed Brown ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 17270c7d97c5SJed Brown ierr = ISDestroy(&is_R_local);CHKERRQ(ierr); 1728*3b03a366Sstefano_zampini ierr = ISRestoreIndices(pcbddc->ISForVertices,(const PetscInt**)&vertices);CHKERRQ(ierr); 17290c7d97c5SJed Brown 17300c7d97c5SJed Brown PetscFunctionReturn(0); 17310c7d97c5SJed Brown } 17320c7d97c5SJed Brown 17330c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 17340c7d97c5SJed Brown 17350c7d97c5SJed Brown #undef __FUNCT__ 17360c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetupCoarseEnvironment" 173753cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetupCoarseEnvironment(PC pc,PetscScalar* coarse_submat_vals) 17380c7d97c5SJed Brown { 17390c7d97c5SJed Brown 17400c7d97c5SJed Brown 17410c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 17420c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 17430c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 17440c7d97c5SJed Brown MPI_Comm prec_comm = ((PetscObject)pc)->comm; 17450c7d97c5SJed Brown MPI_Comm coarse_comm; 17460c7d97c5SJed Brown 17470c7d97c5SJed Brown /* common to all choiches */ 17480c7d97c5SJed Brown PetscScalar *temp_coarse_mat_vals; 17490c7d97c5SJed Brown PetscScalar *ins_coarse_mat_vals; 17500c7d97c5SJed Brown PetscInt *ins_local_primal_indices; 17510c7d97c5SJed Brown PetscMPIInt *localsizes2,*localdispl2; 17520c7d97c5SJed Brown PetscMPIInt size_prec_comm; 17530c7d97c5SJed Brown PetscMPIInt rank_prec_comm; 17540c7d97c5SJed Brown PetscMPIInt active_rank=MPI_PROC_NULL; 17550c7d97c5SJed Brown PetscMPIInt master_proc=0; 17560c7d97c5SJed Brown PetscInt ins_local_primal_size; 17570c7d97c5SJed Brown /* specific to MULTILEVEL_BDDC */ 17580c7d97c5SJed Brown PetscMPIInt *ranks_recv; 17590c7d97c5SJed Brown PetscMPIInt count_recv=0; 17600c7d97c5SJed Brown PetscMPIInt rank_coarse_proc_send_to; 17610c7d97c5SJed Brown PetscMPIInt coarse_color = MPI_UNDEFINED; 17620c7d97c5SJed Brown ISLocalToGlobalMapping coarse_ISLG; 17630c7d97c5SJed Brown /* some other variables */ 17640c7d97c5SJed Brown PetscErrorCode ierr; 17650c7d97c5SJed Brown const MatType coarse_mat_type; 17660c7d97c5SJed Brown const PCType coarse_pc_type; 176753cdbc3dSStefano Zampini const KSPType coarse_ksp_type; 176853cdbc3dSStefano Zampini PC pc_temp; 17690c7d97c5SJed Brown PetscInt i,j,k,bs; 1770*3b03a366Sstefano_zampini PetscInt max_it_coarse_ksp=1; /* don't increase this value */ 1771e269702eSStefano Zampini /* verbose output viewer */ 1772e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 1773e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 17740c7d97c5SJed Brown 17750c7d97c5SJed Brown PetscFunctionBegin; 17760c7d97c5SJed Brown 17770c7d97c5SJed Brown ins_local_primal_indices = 0; 17780c7d97c5SJed Brown ins_coarse_mat_vals = 0; 17790c7d97c5SJed Brown localsizes2 = 0; 17800c7d97c5SJed Brown localdispl2 = 0; 17810c7d97c5SJed Brown temp_coarse_mat_vals = 0; 17820c7d97c5SJed Brown coarse_ISLG = 0; 17830c7d97c5SJed Brown 178453cdbc3dSStefano Zampini ierr = MPI_Comm_size(prec_comm,&size_prec_comm);CHKERRQ(ierr); 178553cdbc3dSStefano Zampini ierr = MPI_Comm_rank(prec_comm,&rank_prec_comm);CHKERRQ(ierr); 17860c7d97c5SJed Brown ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 17870c7d97c5SJed Brown 1788beed3852SStefano Zampini /* Assign global numbering to coarse dofs */ 1789beed3852SStefano Zampini { 1790a0ba757dSStefano Zampini PetscScalar one=1.,zero=0.; 1791beed3852SStefano Zampini PetscScalar *array; 1792beed3852SStefano Zampini PetscMPIInt *auxlocal_primal; 1793beed3852SStefano Zampini PetscMPIInt *auxglobal_primal; 1794beed3852SStefano Zampini PetscMPIInt *all_auxglobal_primal; 1795beed3852SStefano Zampini PetscMPIInt *all_auxglobal_primal_dummy; 1796beed3852SStefano Zampini PetscMPIInt mpi_local_primal_size = (PetscMPIInt)pcbddc->local_primal_size; 1797*3b03a366Sstefano_zampini PetscInt *vertices,*row_cmat_indices; 1798*3b03a366Sstefano_zampini PetscInt size_of_constraint; 1799beed3852SStefano Zampini 1800beed3852SStefano Zampini /* Construct needed data structures for message passing */ 1801beed3852SStefano Zampini ierr = PetscMalloc(mpi_local_primal_size*sizeof(PetscMPIInt),&pcbddc->local_primal_indices);CHKERRQ(ierr); 1802beed3852SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&pcbddc->local_primal_sizes);CHKERRQ(ierr); 1803beed3852SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 1804beed3852SStefano Zampini /* Gather local_primal_size information for all processes */ 18055619798eSStefano Zampini ierr = MPI_Allgather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,prec_comm);CHKERRQ(ierr); 1806beed3852SStefano Zampini pcbddc->replicated_primal_size = 0; 1807beed3852SStefano Zampini for (i=0; i<size_prec_comm; i++) { 1808beed3852SStefano Zampini pcbddc->local_primal_displacements[i] = pcbddc->replicated_primal_size ; 1809beed3852SStefano Zampini pcbddc->replicated_primal_size += pcbddc->local_primal_sizes[i]; 1810beed3852SStefano Zampini } 18115619798eSStefano Zampini if(rank_prec_comm == 0) { 1812beed3852SStefano Zampini /* allocate some auxiliary space */ 1813beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->replicated_primal_size*sizeof(*all_auxglobal_primal),&all_auxglobal_primal);CHKERRQ(ierr); 1814beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->replicated_primal_size*sizeof(*all_auxglobal_primal_dummy),&all_auxglobal_primal_dummy);CHKERRQ(ierr); 1815beed3852SStefano Zampini } 1816beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscMPIInt),&auxlocal_primal);CHKERRQ(ierr); 1817beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscMPIInt),&auxglobal_primal);CHKERRQ(ierr); 1818beed3852SStefano Zampini 1819beed3852SStefano Zampini /* First let's count coarse dofs: note that we allow to have a constraint on a subdomain and not its counterpart on the neighbour subdomain (if user wants) 1820beed3852SStefano Zampini This code fragment assumes that the number of local constraints per connected component 1821beed3852SStefano Zampini is not greater than the number of nodes defined for the connected component 1822beed3852SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 1823*3b03a366Sstefano_zampini /* auxlocal_primal : primal indices in local nodes numbering (internal and interface) with complete queue sorted by global ordering */ 1824beed3852SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 1825*3b03a366Sstefano_zampini ierr = ISGetIndices(pcbddc->ISForVertices,(const PetscInt**)&vertices);CHKERRQ(ierr); 1826beed3852SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1827*3b03a366Sstefano_zampini for(i=0;i<pcbddc->n_vertices;i++) { /* note that pcbddc->n_vertices can be different from size of ISForVertices */ 1828*3b03a366Sstefano_zampini array[ vertices[i] ] = one; 1829*3b03a366Sstefano_zampini auxlocal_primal[i] = vertices[i]; 1830beed3852SStefano Zampini } 1831*3b03a366Sstefano_zampini ierr = ISRestoreIndices(pcbddc->ISForVertices,(const PetscInt**)&vertices);CHKERRQ(ierr); 1832beed3852SStefano Zampini for(i=0;i<pcbddc->n_constraints;i++) { 1833*3b03a366Sstefano_zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,pcbddc->n_vertices+i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 1834*3b03a366Sstefano_zampini for (j=0; j<size_of_constraint; j++) { 1835*3b03a366Sstefano_zampini k = row_cmat_indices[j]; 1836beed3852SStefano Zampini if( array[k] == zero ) { 1837beed3852SStefano Zampini array[k] = one; 1838beed3852SStefano Zampini auxlocal_primal[i+pcbddc->n_vertices] = k; 1839beed3852SStefano Zampini break; 1840beed3852SStefano Zampini } 1841beed3852SStefano Zampini } 1842*3b03a366Sstefano_zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,pcbddc->n_vertices+i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 1843beed3852SStefano Zampini } 1844beed3852SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1845a0ba757dSStefano Zampini 1846beed3852SStefano Zampini /* Now assign them a global numbering */ 1847beed3852SStefano Zampini /* auxglobal_primal contains indices in global nodes numbering (internal and interface) */ 1848beed3852SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,pcbddc->local_primal_size,auxlocal_primal,auxglobal_primal);CHKERRQ(ierr); 1849beed3852SStefano Zampini /* all_auxglobal_primal contains all primal nodes indices in global nodes numbering (internal and interface) */ 1850beed3852SStefano Zampini ierr = MPI_Gatherv(&auxglobal_primal[0],pcbddc->local_primal_size,MPIU_INT,&all_auxglobal_primal[0],pcbddc->local_primal_sizes,pcbddc->local_primal_displacements,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 1851beed3852SStefano Zampini 1852beed3852SStefano Zampini /* After this block all_auxglobal_primal should contains one copy of each primal node's indices in global nodes numbering */ 1853beed3852SStefano Zampini /* It implements a function similar to PetscSortRemoveDupsInt */ 1854beed3852SStefano Zampini if(rank_prec_comm==0) { 1855beed3852SStefano Zampini /* dummy argument since PetscSortMPIInt doesn't exist! */ 1856beed3852SStefano Zampini ierr = PetscSortMPIIntWithArray(pcbddc->replicated_primal_size,all_auxglobal_primal,all_auxglobal_primal_dummy);CHKERRQ(ierr); 1857beed3852SStefano Zampini k=1; 1858beed3852SStefano Zampini j=all_auxglobal_primal[0]; /* first dof in global numbering */ 1859beed3852SStefano Zampini for(i=1;i< pcbddc->replicated_primal_size ;i++) { 1860beed3852SStefano Zampini if(j != all_auxglobal_primal[i] ) { 1861beed3852SStefano Zampini all_auxglobal_primal[k]=all_auxglobal_primal[i]; 1862beed3852SStefano Zampini k++; 1863beed3852SStefano Zampini j=all_auxglobal_primal[i]; 1864beed3852SStefano Zampini } 1865beed3852SStefano Zampini } 1866beed3852SStefano Zampini } else { 1867beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscMPIInt),&all_auxglobal_primal);CHKERRQ(ierr); 1868beed3852SStefano Zampini } 18695619798eSStefano Zampini /* We only need to broadcast the indices from 0 to pcbddc->coarse_size. Remaning elements of array all_aux_global_primal are garbage. */ 1870beed3852SStefano Zampini ierr = MPI_Bcast(all_auxglobal_primal,pcbddc->coarse_size,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 1871beed3852SStefano Zampini 1872beed3852SStefano Zampini /* Now get global coarse numbering of local primal nodes */ 1873beed3852SStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) { 1874beed3852SStefano Zampini k=0; 1875beed3852SStefano Zampini while( all_auxglobal_primal[k] != auxglobal_primal[i] ) { k++;} 1876beed3852SStefano Zampini pcbddc->local_primal_indices[i]=k; 1877beed3852SStefano Zampini } 1878e269702eSStefano Zampini if(dbg_flag) { 1879e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1880e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 1881e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1882e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 1883e269702eSStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) { 1884e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_primal_indices[%d]=%d \n",i,pcbddc->local_primal_indices[i]); 1885e269702eSStefano Zampini } 1886e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1887e269702eSStefano Zampini } 1888beed3852SStefano Zampini /* free allocated memory */ 1889beed3852SStefano Zampini ierr = PetscFree(auxlocal_primal);CHKERRQ(ierr); 1890beed3852SStefano Zampini ierr = PetscFree(auxglobal_primal);CHKERRQ(ierr); 1891beed3852SStefano Zampini ierr = PetscFree(all_auxglobal_primal);CHKERRQ(ierr); 1892e269702eSStefano Zampini if(rank_prec_comm == 0) { 1893beed3852SStefano Zampini ierr = PetscFree(all_auxglobal_primal_dummy);CHKERRQ(ierr); 1894beed3852SStefano Zampini } 1895e269702eSStefano Zampini } 1896beed3852SStefano Zampini 18970c7d97c5SJed Brown /* adapt coarse problem type */ 18980c7d97c5SJed Brown if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC && pcbddc->active_procs < MIN_PROCS_FOR_BDDC ) 18990c7d97c5SJed Brown pcbddc->coarse_problem_type = PARALLEL_BDDC; 19000c7d97c5SJed Brown 19010c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 19020c7d97c5SJed Brown 19030c7d97c5SJed Brown case(MULTILEVEL_BDDC): //we define a coarse mesh where subdomains are elements 19040c7d97c5SJed Brown { 19050c7d97c5SJed Brown /* we need additional variables */ 19060c7d97c5SJed Brown MetisInt n_subdomains,n_parts,objval,ncon,faces_nvtxs; 19070c7d97c5SJed Brown MetisInt *metis_coarse_subdivision; 19080c7d97c5SJed Brown MetisInt options[METIS_NOPTIONS]; 19090c7d97c5SJed Brown PetscMPIInt size_coarse_comm,rank_coarse_comm; 19100c7d97c5SJed Brown PetscMPIInt procs_jumps_coarse_comm; 19110c7d97c5SJed Brown PetscMPIInt *coarse_subdivision; 19120c7d97c5SJed Brown PetscMPIInt *total_count_recv; 19130c7d97c5SJed Brown PetscMPIInt *total_ranks_recv; 19140c7d97c5SJed Brown PetscMPIInt *displacements_recv; 19150c7d97c5SJed Brown PetscMPIInt *my_faces_connectivity; 19160c7d97c5SJed Brown PetscMPIInt *petsc_faces_adjncy; 19170c7d97c5SJed Brown MetisInt *faces_adjncy; 19180c7d97c5SJed Brown MetisInt *faces_xadj; 19190c7d97c5SJed Brown PetscMPIInt *number_of_faces; 19200c7d97c5SJed Brown PetscMPIInt *faces_displacements; 19210c7d97c5SJed Brown PetscInt *array_int; 19220c7d97c5SJed Brown PetscMPIInt my_faces=0; 19230c7d97c5SJed Brown PetscMPIInt total_faces=0; 19243828260eSStefano Zampini PetscInt ranks_stretching_ratio; 19250c7d97c5SJed Brown 19260c7d97c5SJed Brown /* define some quantities */ 19270c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 19280c7d97c5SJed Brown coarse_mat_type = MATIS; 19290c7d97c5SJed Brown coarse_pc_type = PCBDDC; 1930*3b03a366Sstefano_zampini coarse_ksp_type = KSPCHEBYCHEV; 19310c7d97c5SJed Brown 19320c7d97c5SJed Brown /* details of coarse decomposition */ 19330c7d97c5SJed Brown n_subdomains = pcbddc->active_procs; 19340c7d97c5SJed Brown n_parts = n_subdomains/pcbddc->coarsening_ratio; 19353828260eSStefano Zampini ranks_stretching_ratio = size_prec_comm/pcbddc->active_procs; 19363828260eSStefano Zampini procs_jumps_coarse_comm = pcbddc->coarsening_ratio*ranks_stretching_ratio; 19373828260eSStefano Zampini 19383828260eSStefano Zampini printf("Coarse algorithm details: \n"); 1939a0ba757dSStefano Zampini printf("n_subdomains %d, n_parts %d\nstretch %d,jumps %d,coarse_ratio %d\nlevel should be log_%d(%d)\n",n_subdomains,n_parts,ranks_stretching_ratio,procs_jumps_coarse_comm,pcbddc->coarsening_ratio,pcbddc->coarsening_ratio,(ranks_stretching_ratio/pcbddc->coarsening_ratio+1)); 19400c7d97c5SJed Brown 19410c7d97c5SJed Brown /* build CSR graph of subdomains' connectivity through faces */ 19420c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&array_int);CHKERRQ(ierr); 19433828260eSStefano Zampini ierr = PetscMemzero(array_int,pcis->n*sizeof(PetscInt));CHKERRQ(ierr); 19440c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){/* i=1 so I don't count myself -> faces nodes counts to 1 */ 19450c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 19460c7d97c5SJed Brown array_int[ pcis->shared[i][j] ]+=1; 19470c7d97c5SJed Brown } 19480c7d97c5SJed Brown } 19490c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){ 19500c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 19510c7d97c5SJed Brown if(array_int[ pcis->shared[i][j] ] == 1 ){ 19520c7d97c5SJed Brown my_faces++; 19530c7d97c5SJed Brown break; 19540c7d97c5SJed Brown } 19550c7d97c5SJed Brown } 19560c7d97c5SJed Brown } 19570c7d97c5SJed Brown //printf("I found %d faces.\n",my_faces); 19580c7d97c5SJed Brown 195953cdbc3dSStefano Zampini ierr = MPI_Reduce(&my_faces,&total_faces,1,MPIU_INT,MPI_SUM,master_proc,prec_comm);CHKERRQ(ierr); 19600c7d97c5SJed Brown ierr = PetscMalloc (my_faces*sizeof(PetscInt),&my_faces_connectivity);CHKERRQ(ierr); 19610c7d97c5SJed Brown my_faces=0; 19620c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){ 19630c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 19640c7d97c5SJed Brown if(array_int[ pcis->shared[i][j] ] == 1 ){ 19650c7d97c5SJed Brown my_faces_connectivity[my_faces]=pcis->neigh[i]; 19660c7d97c5SJed Brown my_faces++; 19670c7d97c5SJed Brown break; 19680c7d97c5SJed Brown } 19690c7d97c5SJed Brown } 19700c7d97c5SJed Brown } 19710c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 19720c7d97c5SJed Brown //printf("I found %d total faces.\n",total_faces); 19730c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(PetscMPIInt),&petsc_faces_adjncy);CHKERRQ(ierr); 19740c7d97c5SJed Brown ierr = PetscMalloc (size_prec_comm*sizeof(PetscMPIInt),&number_of_faces);CHKERRQ(ierr); 19750c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(MetisInt),&faces_adjncy);CHKERRQ(ierr); 19760c7d97c5SJed Brown ierr = PetscMalloc ((n_subdomains+1)*sizeof(MetisInt),&faces_xadj);CHKERRQ(ierr); 19770c7d97c5SJed Brown ierr = PetscMalloc ((size_prec_comm+1)*sizeof(PetscMPIInt),&faces_displacements);CHKERRQ(ierr); 19780c7d97c5SJed Brown } 197953cdbc3dSStefano Zampini ierr = MPI_Gather(&my_faces,1,MPIU_INT,&number_of_faces[0],1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 19800c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 19810c7d97c5SJed Brown faces_xadj[0]=0; 19820c7d97c5SJed Brown faces_displacements[0]=0; 19830c7d97c5SJed Brown j=0; 19840c7d97c5SJed Brown for(i=1;i<size_prec_comm+1;i++) { 19850c7d97c5SJed Brown faces_displacements[i]=faces_displacements[i-1]+number_of_faces[i-1]; 19860c7d97c5SJed Brown if(number_of_faces[i-1]) { 19870c7d97c5SJed Brown j++; 19880c7d97c5SJed Brown faces_xadj[j]=faces_xadj[j-1]+number_of_faces[i-1]; 19890c7d97c5SJed Brown } 19900c7d97c5SJed Brown } 19910c7d97c5SJed Brown printf("The J I count is %d and should be %d\n",j,n_subdomains); 19920c7d97c5SJed Brown printf("Total faces seem %d and should be %d\n",faces_xadj[j],total_faces); 19930c7d97c5SJed Brown } 199453cdbc3dSStefano 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); 19950c7d97c5SJed Brown ierr = PetscFree(my_faces_connectivity);CHKERRQ(ierr); 19960c7d97c5SJed Brown ierr = PetscFree(array_int);CHKERRQ(ierr); 19970c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 19983828260eSStefano Zampini for(i=0;i<total_faces;i++) faces_adjncy[i]=(MetisInt)(petsc_faces_adjncy[i]/ranks_stretching_ratio); /* cast to MetisInt */ 19993828260eSStefano Zampini printf("This is the face connectivity (actual ranks)\n"); 20000c7d97c5SJed Brown for(i=0;i<n_subdomains;i++){ 20010c7d97c5SJed Brown printf("proc %d is connected with \n",i); 20020c7d97c5SJed Brown for(j=faces_xadj[i];j<faces_xadj[i+1];j++) 20030c7d97c5SJed Brown printf("%d ",faces_adjncy[j]); 20040c7d97c5SJed Brown printf("\n"); 20050c7d97c5SJed Brown } 20060c7d97c5SJed Brown ierr = PetscFree(faces_displacements);CHKERRQ(ierr); 20070c7d97c5SJed Brown ierr = PetscFree(number_of_faces);CHKERRQ(ierr); 20080c7d97c5SJed Brown ierr = PetscFree(petsc_faces_adjncy);CHKERRQ(ierr); 20090c7d97c5SJed Brown } 20100c7d97c5SJed Brown 20110c7d97c5SJed Brown if( rank_prec_comm == master_proc ) { 20120c7d97c5SJed Brown 20133828260eSStefano Zampini PetscInt heuristic_for_metis=3; 20143828260eSStefano Zampini 20150c7d97c5SJed Brown ncon=1; 20160c7d97c5SJed Brown faces_nvtxs=n_subdomains; 20170c7d97c5SJed Brown /* partition graoh induced by face connectivity */ 20180c7d97c5SJed Brown ierr = PetscMalloc (n_subdomains*sizeof(MetisInt),&metis_coarse_subdivision);CHKERRQ(ierr); 20190c7d97c5SJed Brown ierr = METIS_SetDefaultOptions(options); 20200c7d97c5SJed Brown /* we need a contiguous partition of the coarse mesh */ 20210c7d97c5SJed Brown options[METIS_OPTION_CONTIG]=1; 20220c7d97c5SJed Brown options[METIS_OPTION_DBGLVL]=1; 20230c7d97c5SJed Brown options[METIS_OPTION_NITER]=30; 20240c7d97c5SJed Brown //options[METIS_OPTION_NCUTS]=1; 20253828260eSStefano Zampini printf("METIS PART GRAPH\n"); 20263828260eSStefano Zampini if(n_subdomains>n_parts*heuristic_for_metis) { 20273828260eSStefano Zampini printf("Using Kway\n"); 20283828260eSStefano Zampini options[METIS_OPTION_IPTYPE]=METIS_IPTYPE_EDGE; 20293828260eSStefano Zampini options[METIS_OPTION_OBJTYPE]=METIS_OBJTYPE_CUT; 20300c7d97c5SJed Brown ierr = METIS_PartGraphKway(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 20313828260eSStefano Zampini } else { 20323828260eSStefano Zampini printf("Using Recursive\n"); 20333828260eSStefano Zampini ierr = METIS_PartGraphRecursive(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 20343828260eSStefano Zampini } 20350c7d97c5SJed Brown if(ierr != METIS_OK) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in METIS_PartGraphKway (metis error code %D) called from PCBDDCSetupCoarseEnvironment\n",ierr); 20363828260eSStefano Zampini printf("Partition done!\n"); 20370c7d97c5SJed Brown ierr = PetscFree(faces_xadj);CHKERRQ(ierr); 20380c7d97c5SJed Brown ierr = PetscFree(faces_adjncy);CHKERRQ(ierr); 20390c7d97c5SJed Brown coarse_subdivision = (PetscMPIInt*)calloc(size_prec_comm,sizeof(PetscMPIInt)); /* calloc for contiguous memory since we need to scatter these values later */ 20400c7d97c5SJed Brown /* copy/cast values avoiding possible type conflicts between PETSc, MPI and METIS */ 20413828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) coarse_subdivision[i]=MPI_PROC_NULL; 20423828260eSStefano Zampini for(i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=(PetscInt)(metis_coarse_subdivision[i]); 20430c7d97c5SJed Brown ierr = PetscFree(metis_coarse_subdivision);CHKERRQ(ierr); 20440c7d97c5SJed Brown } 20450c7d97c5SJed Brown 20460c7d97c5SJed Brown /* Create new communicator for coarse problem splitting the old one */ 20470c7d97c5SJed Brown if( !(rank_prec_comm%procs_jumps_coarse_comm) && rank_prec_comm < procs_jumps_coarse_comm*n_parts ){ 20480c7d97c5SJed Brown coarse_color=0; //for communicator splitting 20490c7d97c5SJed Brown active_rank=rank_prec_comm; //for insertion of matrix values 20500c7d97c5SJed Brown } 20510c7d97c5SJed Brown // procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 20520c7d97c5SJed Brown // key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator 205353cdbc3dSStefano Zampini ierr = MPI_Comm_split(prec_comm,coarse_color,rank_prec_comm,&coarse_comm);CHKERRQ(ierr); 20540c7d97c5SJed Brown 20550c7d97c5SJed Brown if( coarse_color == 0 ) { 205653cdbc3dSStefano Zampini ierr = MPI_Comm_size(coarse_comm,&size_coarse_comm);CHKERRQ(ierr); 205753cdbc3dSStefano Zampini ierr = MPI_Comm_rank(coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 20583828260eSStefano Zampini printf("Details of coarse comm\n"); 20593828260eSStefano Zampini printf("size = %d, myrank = %d\n",size_coarse_comm,rank_coarse_comm); 20603828260eSStefano Zampini printf("jumps = %d, coarse_color = %d, n_parts = %d\n",procs_jumps_coarse_comm,coarse_color,n_parts); 20610c7d97c5SJed Brown } else { 20620c7d97c5SJed Brown rank_coarse_comm = MPI_PROC_NULL; 20630c7d97c5SJed Brown } 20640c7d97c5SJed Brown 20650c7d97c5SJed Brown /* master proc take care of arranging and distributing coarse informations */ 20660c7d97c5SJed Brown if(rank_coarse_comm == master_proc) { 20670c7d97c5SJed Brown ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&displacements_recv);CHKERRQ(ierr); 20680c7d97c5SJed Brown //ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&total_count_recv);CHKERRQ(ierr); 20690c7d97c5SJed Brown //ierr = PetscMalloc (n_subdomains*sizeof(PetscMPIInt),&total_ranks_recv);CHKERRQ(ierr); 20700c7d97c5SJed Brown total_count_recv = (PetscMPIInt*)calloc(size_prec_comm,sizeof(PetscMPIInt)); 20710c7d97c5SJed Brown total_ranks_recv = (PetscMPIInt*)calloc(n_subdomains,sizeof(PetscMPIInt)); 20720c7d97c5SJed Brown /* some initializations */ 20730c7d97c5SJed Brown displacements_recv[0]=0; 20740c7d97c5SJed Brown //PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt)); not needed -> calloc initializes to zero 20750c7d97c5SJed Brown /* count from how many processes the j-th process of the coarse decomposition will receive data */ 20760c7d97c5SJed Brown for(j=0;j<size_coarse_comm;j++) 20773828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) 20780c7d97c5SJed Brown if(coarse_subdivision[i]==j) 20790c7d97c5SJed Brown total_count_recv[j]++; 20800c7d97c5SJed Brown /* displacements needed for scatterv of total_ranks_recv */ 20810c7d97c5SJed Brown for(i=1;i<size_coarse_comm;i++) displacements_recv[i]=displacements_recv[i-1]+total_count_recv[i-1]; 20820c7d97c5SJed Brown /* Now fill properly total_ranks_recv -> each coarse process will receive the ranks (in prec_comm communicator) of its friend (sending) processes */ 20830c7d97c5SJed Brown ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 20840c7d97c5SJed Brown for(j=0;j<size_coarse_comm;j++) { 20853828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) { 20860c7d97c5SJed Brown if(coarse_subdivision[i]==j) { 20870c7d97c5SJed Brown total_ranks_recv[displacements_recv[j]+total_count_recv[j]]=i; 20883828260eSStefano Zampini total_count_recv[j]+=1; 20890c7d97c5SJed Brown } 20900c7d97c5SJed Brown } 20910c7d97c5SJed Brown } 20923828260eSStefano Zampini for(j=0;j<size_coarse_comm;j++) { 20933828260eSStefano Zampini printf("process %d in new rank will receive from %d processes (original ranks follows)\n",j,total_count_recv[j]); 20943828260eSStefano Zampini for(i=0;i<total_count_recv[j];i++) { 20953828260eSStefano Zampini printf("%d ",total_ranks_recv[displacements_recv[j]+i]); 20963828260eSStefano Zampini } 20973828260eSStefano Zampini printf("\n"); 20983828260eSStefano Zampini } 20990c7d97c5SJed Brown 21000c7d97c5SJed Brown /* identify new decomposition in terms of ranks in the old communicator */ 21013828260eSStefano Zampini for(i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=coarse_subdivision[ranks_stretching_ratio*i]*procs_jumps_coarse_comm; 21020c7d97c5SJed Brown printf("coarse_subdivision in old end new ranks\n"); 21030c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) 21043828260eSStefano Zampini if(coarse_subdivision[i]!=MPI_PROC_NULL) { 21053828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]/procs_jumps_coarse_comm); 21063828260eSStefano Zampini } else { 21073828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]); 21083828260eSStefano Zampini } 21090c7d97c5SJed Brown printf("\n"); 21100c7d97c5SJed Brown } 21110c7d97c5SJed Brown 21120c7d97c5SJed Brown /* Scatter new decomposition for send details */ 211353cdbc3dSStefano Zampini ierr = MPI_Scatter(&coarse_subdivision[0],1,MPIU_INT,&rank_coarse_proc_send_to,1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 21140c7d97c5SJed Brown /* Scatter receiving details to members of coarse decomposition */ 21150c7d97c5SJed Brown if( coarse_color == 0) { 211653cdbc3dSStefano Zampini ierr = MPI_Scatter(&total_count_recv[0],1,MPIU_INT,&count_recv,1,MPIU_INT,master_proc,coarse_comm);CHKERRQ(ierr); 21170c7d97c5SJed Brown ierr = PetscMalloc (count_recv*sizeof(PetscMPIInt),&ranks_recv);CHKERRQ(ierr); 211853cdbc3dSStefano 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); 21190c7d97c5SJed Brown } 21200c7d97c5SJed Brown 21210c7d97c5SJed Brown //printf("I will send my matrix data to proc %d\n",rank_coarse_proc_send_to); 21220c7d97c5SJed Brown //if(coarse_color == 0) { 21230c7d97c5SJed Brown // printf("I will receive some matrix data from %d processes (ranks follows)\n",count_recv); 21240c7d97c5SJed Brown // for(i=0;i<count_recv;i++) 21250c7d97c5SJed Brown // printf("%d ",ranks_recv[i]); 21260c7d97c5SJed Brown // printf("\n"); 21270c7d97c5SJed Brown //} 21280c7d97c5SJed Brown 21290c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 21300c7d97c5SJed Brown //ierr = PetscFree(coarse_subdivision);CHKERRQ(ierr); 21310c7d97c5SJed Brown //ierr = PetscFree(total_count_recv);CHKERRQ(ierr); 21320c7d97c5SJed Brown //ierr = PetscFree(total_ranks_recv);CHKERRQ(ierr); 21330c7d97c5SJed Brown free(coarse_subdivision); 21340c7d97c5SJed Brown free(total_count_recv); 21350c7d97c5SJed Brown free(total_ranks_recv); 21360c7d97c5SJed Brown ierr = PetscFree(displacements_recv);CHKERRQ(ierr); 21370c7d97c5SJed Brown } 21380c7d97c5SJed Brown break; 21390c7d97c5SJed Brown } 21400c7d97c5SJed Brown 21410c7d97c5SJed Brown case(REPLICATED_BDDC): 21420c7d97c5SJed Brown 21430c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 21440c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 21450c7d97c5SJed Brown coarse_pc_type = PCLU; 214653cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 21470c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 21480c7d97c5SJed Brown active_rank = rank_prec_comm; 21490c7d97c5SJed Brown break; 21500c7d97c5SJed Brown 21510c7d97c5SJed Brown case(PARALLEL_BDDC): 21520c7d97c5SJed Brown 21530c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 21540c7d97c5SJed Brown coarse_mat_type = MATMPIAIJ; 21550c7d97c5SJed Brown coarse_pc_type = PCREDUNDANT; 215653cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 21570c7d97c5SJed Brown coarse_comm = prec_comm; 21580c7d97c5SJed Brown active_rank = rank_prec_comm; 21590c7d97c5SJed Brown break; 21600c7d97c5SJed Brown 21610c7d97c5SJed Brown case(SEQUENTIAL_BDDC): 21620c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 21630c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 21640c7d97c5SJed Brown coarse_pc_type = PCLU; 216553cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 21660c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 21670c7d97c5SJed Brown active_rank = master_proc; 21680c7d97c5SJed Brown break; 21690c7d97c5SJed Brown } 21700c7d97c5SJed Brown 21710c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 21720c7d97c5SJed Brown 21730c7d97c5SJed Brown case(SCATTERS_BDDC): 21740c7d97c5SJed Brown { 21750c7d97c5SJed Brown if(pcbddc->coarse_problem_type==MULTILEVEL_BDDC) { 21760c7d97c5SJed Brown 21770c7d97c5SJed Brown PetscMPIInt send_size; 21780c7d97c5SJed Brown PetscInt *aux_ins_indices; 21790c7d97c5SJed Brown PetscInt ii,jj; 21800c7d97c5SJed Brown MPI_Request *requests; 21810c7d97c5SJed Brown 21820c7d97c5SJed Brown /* allocate auxiliary space */ 21835619798eSStefano Zampini ierr = PetscMalloc (pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 21845619798eSStefano Zampini ierr = MPI_Allgatherv(&pcbddc->local_primal_indices[0],pcbddc->local_primal_size,MPIU_INT,&pcbddc->replicated_local_primal_indices[0],pcbddc->local_primal_sizes,pcbddc->local_primal_displacements,MPIU_INT,prec_comm);CHKERRQ(ierr); 21850c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->coarse_size*sizeof(PetscInt),&aux_ins_indices);CHKERRQ(ierr); 21860c7d97c5SJed Brown ierr = PetscMemzero(aux_ins_indices,pcbddc->coarse_size*sizeof(PetscInt));CHKERRQ(ierr); 21870c7d97c5SJed Brown /* allocate stuffs for message massing */ 21880c7d97c5SJed Brown ierr = PetscMalloc ( (count_recv+1)*sizeof(MPI_Request),&requests);CHKERRQ(ierr); 21890c7d97c5SJed Brown for(i=0;i<count_recv+1;i++) requests[i]=MPI_REQUEST_NULL; 21900c7d97c5SJed Brown ierr = PetscMalloc ( count_recv*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 21910c7d97c5SJed Brown ierr = PetscMalloc ( count_recv*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 21920c7d97c5SJed Brown /* fill up quantities */ 21930c7d97c5SJed Brown j=0; 21940c7d97c5SJed Brown for(i=0;i<count_recv;i++){ 21950c7d97c5SJed Brown ii = ranks_recv[i]; 21960c7d97c5SJed Brown localsizes2[i]=pcbddc->local_primal_sizes[ii]*pcbddc->local_primal_sizes[ii]; 21970c7d97c5SJed Brown localdispl2[i]=j; 21980c7d97c5SJed Brown j+=localsizes2[i]; 21990c7d97c5SJed Brown jj = pcbddc->local_primal_displacements[ii]; 22000c7d97c5SJed Brown for(k=0;k<pcbddc->local_primal_sizes[ii];k++) aux_ins_indices[pcbddc->replicated_local_primal_indices[jj+k]]+=1; // it counts the coarse subdomains sharing the coarse node 22010c7d97c5SJed Brown } 22020c7d97c5SJed Brown //printf("aux_ins_indices 1\n"); 22030c7d97c5SJed Brown //for(i=0;i<pcbddc->coarse_size;i++) 22040c7d97c5SJed Brown // printf("%d ",aux_ins_indices[i]); 22050c7d97c5SJed Brown //printf("\n"); 22060c7d97c5SJed Brown /* temp_coarse_mat_vals used to store temporarly received matrix values */ 22070c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 22080c7d97c5SJed Brown /* evaluate how many values I will insert in coarse mat */ 22090c7d97c5SJed Brown ins_local_primal_size=0; 22100c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++) 22110c7d97c5SJed Brown if(aux_ins_indices[i]) 22120c7d97c5SJed Brown ins_local_primal_size++; 22130c7d97c5SJed Brown /* evaluate indices I will insert in coarse mat */ 22140c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 22150c7d97c5SJed Brown j=0; 22160c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++) 22170c7d97c5SJed Brown if(aux_ins_indices[i]) 22180c7d97c5SJed Brown ins_local_primal_indices[j++]=i; 22190c7d97c5SJed Brown /* use aux_ins_indices to realize a global to local mapping */ 22200c7d97c5SJed Brown j=0; 22210c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++){ 22220c7d97c5SJed Brown if(aux_ins_indices[i]==0){ 22230c7d97c5SJed Brown aux_ins_indices[i]=-1; 22240c7d97c5SJed Brown } else { 22250c7d97c5SJed Brown aux_ins_indices[i]=j; 22260c7d97c5SJed Brown j++; 22270c7d97c5SJed Brown } 22280c7d97c5SJed Brown } 22290c7d97c5SJed Brown 22300c7d97c5SJed Brown //printf("New details localsizes2 localdispl2\n"); 22310c7d97c5SJed Brown //for(i=0;i<count_recv;i++) 22320c7d97c5SJed Brown // printf("(%d %d) ",localsizes2[i],localdispl2[i]); 22330c7d97c5SJed Brown //printf("\n"); 22340c7d97c5SJed Brown //printf("aux_ins_indices 2\n"); 22350c7d97c5SJed Brown //for(i=0;i<pcbddc->coarse_size;i++) 22360c7d97c5SJed Brown // printf("%d ",aux_ins_indices[i]); 22370c7d97c5SJed Brown //printf("\n"); 22380c7d97c5SJed Brown //printf("ins_local_primal_indices\n"); 22390c7d97c5SJed Brown //for(i=0;i<ins_local_primal_size;i++) 22400c7d97c5SJed Brown // printf("%d ",ins_local_primal_indices[i]); 22410c7d97c5SJed Brown //printf("\n"); 22420c7d97c5SJed Brown //printf("coarse_submat_vals\n"); 22430c7d97c5SJed Brown //for(i=0;i<pcbddc->local_primal_size;i++) 22440c7d97c5SJed Brown // for(j=0;j<pcbddc->local_primal_size;j++) 22450c7d97c5SJed Brown // printf("(%lf %d %d)\n",coarse_submat_vals[j*pcbddc->local_primal_size+i],pcbddc->local_primal_indices[i],pcbddc->local_primal_indices[j]); 22460c7d97c5SJed Brown //printf("\n"); 22470c7d97c5SJed Brown 22480c7d97c5SJed Brown /* processes partecipating in coarse problem receive matrix data from their friends */ 224953cdbc3dSStefano Zampini for(i=0;i<count_recv;i++) ierr = MPI_Irecv(&temp_coarse_mat_vals[localdispl2[i]],localsizes2[i],MPIU_SCALAR,ranks_recv[i],666,prec_comm,&requests[i]);CHKERRQ(ierr); 22500c7d97c5SJed Brown if(rank_coarse_proc_send_to != MPI_PROC_NULL ) { 22510c7d97c5SJed Brown send_size=pcbddc->local_primal_size*pcbddc->local_primal_size; 225253cdbc3dSStefano 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); 22530c7d97c5SJed Brown } 225453cdbc3dSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 22550c7d97c5SJed Brown 22560c7d97c5SJed Brown //if(coarse_color == 0) { 22570c7d97c5SJed Brown // printf("temp_coarse_mat_vals\n"); 22580c7d97c5SJed Brown // for(k=0;k<count_recv;k++){ 22590c7d97c5SJed Brown // printf("---- %d ----\n",ranks_recv[k]); 22600c7d97c5SJed Brown // for(i=0;i<pcbddc->local_primal_sizes[ranks_recv[k]];i++) 22610c7d97c5SJed Brown // for(j=0;j<pcbddc->local_primal_sizes[ranks_recv[k]];j++) 22620c7d97c5SJed Brown // printf("(%lf %d %d)\n",temp_coarse_mat_vals[localdispl2[k]+j*pcbddc->local_primal_sizes[ranks_recv[k]]+i],pcbddc->replicated_local_primal_indices[pcbddc->local_primal_displacements[ranks_recv[k]]+i],pcbddc->replicated_local_primal_indices[pcbddc->local_primal_displacements[ranks_recv[k]]+j]); 22630c7d97c5SJed Brown // printf("\n"); 22640c7d97c5SJed Brown // } 22650c7d97c5SJed Brown //} 22660c7d97c5SJed Brown /* calculate data to insert in coarse mat */ 22670c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 22680c7d97c5SJed Brown PetscMemzero(ins_coarse_mat_vals,ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar)); 22690c7d97c5SJed Brown 22700c7d97c5SJed Brown PetscMPIInt rr,kk,lps,lpd; 22710c7d97c5SJed Brown PetscInt row_ind,col_ind; 22720c7d97c5SJed Brown for(k=0;k<count_recv;k++){ 22730c7d97c5SJed Brown rr = ranks_recv[k]; 22740c7d97c5SJed Brown kk = localdispl2[k]; 22750c7d97c5SJed Brown lps = pcbddc->local_primal_sizes[rr]; 22760c7d97c5SJed Brown lpd = pcbddc->local_primal_displacements[rr]; 22770c7d97c5SJed Brown //printf("Inserting the following indices (received from %d)\n",rr); 22780c7d97c5SJed Brown for(j=0;j<lps;j++){ 22790c7d97c5SJed Brown col_ind=aux_ins_indices[pcbddc->replicated_local_primal_indices[lpd+j]]; 22800c7d97c5SJed Brown for(i=0;i<lps;i++){ 22810c7d97c5SJed Brown row_ind=aux_ins_indices[pcbddc->replicated_local_primal_indices[lpd+i]]; 22820c7d97c5SJed Brown //printf("%d %d\n",row_ind,col_ind); 22830c7d97c5SJed Brown ins_coarse_mat_vals[col_ind*ins_local_primal_size+row_ind]+=temp_coarse_mat_vals[kk+j*lps+i]; 22840c7d97c5SJed Brown } 22850c7d97c5SJed Brown } 22860c7d97c5SJed Brown } 22870c7d97c5SJed Brown ierr = PetscFree(requests);CHKERRQ(ierr); 22880c7d97c5SJed Brown ierr = PetscFree(aux_ins_indices);CHKERRQ(ierr); 22890c7d97c5SJed Brown ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr); 22900c7d97c5SJed Brown if(coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 22910c7d97c5SJed Brown 22920c7d97c5SJed Brown /* create local to global mapping needed by coarse MATIS */ 22930c7d97c5SJed Brown { 22940c7d97c5SJed Brown IS coarse_IS; 229553cdbc3dSStefano Zampini if(coarse_comm != MPI_COMM_NULL ) ierr = MPI_Comm_free(&coarse_comm);CHKERRQ(ierr); 22960c7d97c5SJed Brown coarse_comm = prec_comm; 22970c7d97c5SJed Brown active_rank=rank_prec_comm; 22980c7d97c5SJed Brown ierr = ISCreateGeneral(coarse_comm,ins_local_primal_size,ins_local_primal_indices,PETSC_COPY_VALUES,&coarse_IS);CHKERRQ(ierr); 22990c7d97c5SJed Brown ierr = ISLocalToGlobalMappingCreateIS(coarse_IS,&coarse_ISLG);CHKERRQ(ierr); 23000c7d97c5SJed Brown ierr = ISDestroy(&coarse_IS);CHKERRQ(ierr); 23010c7d97c5SJed Brown } 23020c7d97c5SJed Brown } 23030c7d97c5SJed Brown if(pcbddc->coarse_problem_type==PARALLEL_BDDC) { 23040c7d97c5SJed Brown /* arrays for values insertion */ 23050c7d97c5SJed Brown ins_local_primal_size = pcbddc->local_primal_size; 23060c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscMPIInt),&ins_local_primal_indices);CHKERRQ(ierr); 23070c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 23080c7d97c5SJed Brown for(j=0;j<ins_local_primal_size;j++){ 23090c7d97c5SJed Brown ins_local_primal_indices[j]=pcbddc->local_primal_indices[j]; 23100c7d97c5SJed Brown for(i=0;i<ins_local_primal_size;i++) ins_coarse_mat_vals[j*ins_local_primal_size+i]=coarse_submat_vals[j*ins_local_primal_size+i]; 23110c7d97c5SJed Brown } 23120c7d97c5SJed Brown } 23130c7d97c5SJed Brown break; 23140c7d97c5SJed Brown 23150c7d97c5SJed Brown } 23160c7d97c5SJed Brown 23170c7d97c5SJed Brown case(GATHERS_BDDC): 23180c7d97c5SJed Brown { 23190c7d97c5SJed Brown 23200c7d97c5SJed Brown PetscMPIInt mysize,mysize2; 23210c7d97c5SJed Brown 23220c7d97c5SJed Brown if(rank_prec_comm==active_rank) { 23230c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 23240c7d97c5SJed Brown pcbddc->replicated_local_primal_values = (PetscScalar*)calloc(pcbddc->replicated_primal_size,sizeof(PetscScalar)); 23250c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 23260c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 23270c7d97c5SJed Brown /* arrays for values insertion */ 23280c7d97c5SJed Brown ins_local_primal_size = pcbddc->coarse_size; 23290c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscMPIInt),&ins_local_primal_indices);CHKERRQ(ierr); 23300c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 23310c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) localsizes2[i]=pcbddc->local_primal_sizes[i]*pcbddc->local_primal_sizes[i]; 23320c7d97c5SJed Brown localdispl2[0]=0; 23330c7d97c5SJed Brown for(i=1;i<size_prec_comm;i++) localdispl2[i]=localsizes2[i-1]+localdispl2[i-1]; 23340c7d97c5SJed Brown j=0; 23350c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) j+=localsizes2[i]; 23360c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 23370c7d97c5SJed Brown } 23380c7d97c5SJed Brown 23390c7d97c5SJed Brown mysize=pcbddc->local_primal_size; 23400c7d97c5SJed Brown mysize2=pcbddc->local_primal_size*pcbddc->local_primal_size; 23410c7d97c5SJed Brown if(pcbddc->coarse_problem_type == SEQUENTIAL_BDDC){ 234253cdbc3dSStefano Zampini ierr = MPI_Gatherv(&pcbddc->local_primal_indices[0],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); 234353cdbc3dSStefano 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); 23440c7d97c5SJed Brown } else { 234553cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&pcbddc->local_primal_indices[0],mysize,MPIU_INT,&pcbddc->replicated_local_primal_indices[0],pcbddc->local_primal_sizes,pcbddc->local_primal_displacements,MPIU_INT,prec_comm);CHKERRQ(ierr); 234653cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,prec_comm);CHKERRQ(ierr); 23470c7d97c5SJed Brown } 23480c7d97c5SJed Brown 23490c7d97c5SJed Brown /* free data structures no longer needed and allocate some space which will be needed in BDDC application */ 23500c7d97c5SJed Brown if(rank_prec_comm==active_rank) { 23510c7d97c5SJed Brown PetscInt offset,offset2,row_ind,col_ind; 23520c7d97c5SJed Brown for(j=0;j<ins_local_primal_size;j++){ 23530c7d97c5SJed Brown ins_local_primal_indices[j]=j; 23540c7d97c5SJed Brown for(i=0;i<ins_local_primal_size;i++) ins_coarse_mat_vals[j*ins_local_primal_size+i]=0.0; 23550c7d97c5SJed Brown } 23560c7d97c5SJed Brown for(k=0;k<size_prec_comm;k++){ 23570c7d97c5SJed Brown offset=pcbddc->local_primal_displacements[k]; 23580c7d97c5SJed Brown offset2=localdispl2[k]; 23590c7d97c5SJed Brown for(j=0;j<pcbddc->local_primal_sizes[k];j++){ 23600c7d97c5SJed Brown col_ind=pcbddc->replicated_local_primal_indices[offset+j]; 23610c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_sizes[k];i++){ 23620c7d97c5SJed Brown row_ind=pcbddc->replicated_local_primal_indices[offset+i]; 23630c7d97c5SJed Brown ins_coarse_mat_vals[col_ind*pcbddc->coarse_size+row_ind]+=temp_coarse_mat_vals[offset2+j*pcbddc->local_primal_sizes[k]+i]; 23640c7d97c5SJed Brown } 23650c7d97c5SJed Brown } 23660c7d97c5SJed Brown } 23670c7d97c5SJed Brown } 23680c7d97c5SJed Brown break; 23690c7d97c5SJed Brown }//switch on coarse problem and communications associated with finished 23700c7d97c5SJed Brown } 23710c7d97c5SJed Brown 23720c7d97c5SJed Brown /* Now create and fill up coarse matrix */ 23730c7d97c5SJed Brown if( rank_prec_comm == active_rank ) { 23740c7d97c5SJed Brown if(pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 23750c7d97c5SJed Brown ierr = MatCreate(coarse_comm,&pcbddc->coarse_mat);CHKERRQ(ierr); 23760c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_mat,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size);CHKERRQ(ierr); 23770c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_mat,coarse_mat_type);CHKERRQ(ierr); 2378*3b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 23790c7d97c5SJed Brown ierr = MatSetOption(pcbddc->coarse_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); //local values stored in column major 2380*3b03a366Sstefano_zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 23810c7d97c5SJed Brown } else { 23820c7d97c5SJed Brown Mat matis_coarse_local_mat; 23830c7d97c5SJed Brown ierr = MatCreateIS(coarse_comm,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_ISLG,&pcbddc->coarse_mat);CHKERRQ(ierr); 2384*3b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 23850c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 2386*3b03a366Sstefano_zampini ierr = MatSetUp(matis_coarse_local_mat);CHKERRQ(ierr); 23870c7d97c5SJed Brown ierr = MatSetOption(matis_coarse_local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); //local values stored in column major 2388a0ba757dSStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 23890c7d97c5SJed Brown } 2390a0ba757dSStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 23910c7d97c5SJed 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); 23920c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 23930c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 23940c7d97c5SJed Brown if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 23950c7d97c5SJed Brown Mat matis_coarse_local_mat; 23960c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 23970c7d97c5SJed Brown ierr = MatSetBlockSize(matis_coarse_local_mat,bs);CHKERRQ(ierr); 23980c7d97c5SJed Brown } 23990c7d97c5SJed Brown 24000c7d97c5SJed Brown ierr = MatGetVecs(pcbddc->coarse_mat,&pcbddc->coarse_vec,&pcbddc->coarse_rhs);CHKERRQ(ierr); 24010c7d97c5SJed Brown /* Preconditioner for coarse problem */ 240253cdbc3dSStefano Zampini ierr = KSPCreate(coarse_comm,&pcbddc->coarse_ksp);CHKERRQ(ierr); 240353cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 240453cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 2405*3b03a366Sstefano_zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,max_it_coarse_ksp);CHKERRQ(ierr); 240653cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 240753cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 240853cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 24090c7d97c5SJed Brown /* Allow user's customization */ 241053cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 24110c7d97c5SJed Brown /* Set Up PC for coarse problem BDDC */ 241253cdbc3dSStefano Zampini if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2413e269702eSStefano Zampini if(dbg_flag) { 2414e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------Setting up a new level---------------\n");CHKERRQ(ierr); 2415e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2416e269702eSStefano Zampini } 241753cdbc3dSStefano Zampini ierr = PCBDDCSetCoarseProblemType(pc_temp,MULTILEVEL_BDDC);CHKERRQ(ierr); 241853cdbc3dSStefano Zampini } 241953cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 24205619798eSStefano Zampini if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 24215619798eSStefano Zampini if(dbg_flag) { 24225619798eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------New level set------------------------\n");CHKERRQ(ierr); 24235619798eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 24245619798eSStefano Zampini } 24255619798eSStefano Zampini } 24260c7d97c5SJed Brown } 24270c7d97c5SJed Brown if(pcbddc->coarse_communications_type == SCATTERS_BDDC) { 24280c7d97c5SJed Brown IS local_IS,global_IS; 24290c7d97c5SJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&local_IS);CHKERRQ(ierr); 24300c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_indices,PETSC_COPY_VALUES,&global_IS);CHKERRQ(ierr); 24310c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_P,local_IS,pcbddc->coarse_vec,global_IS,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 24320c7d97c5SJed Brown ierr = ISDestroy(&local_IS);CHKERRQ(ierr); 24330c7d97c5SJed Brown ierr = ISDestroy(&global_IS);CHKERRQ(ierr); 24340c7d97c5SJed Brown } 24350c7d97c5SJed Brown 24360c7d97c5SJed Brown 2437*3b03a366Sstefano_zampini /* Evaluate condition number of coarse problem for cheby (and verbose output if requested) */ 2438*3b03a366Sstefano_zampini if( pcbddc->coarse_problem_type == MULTILEVEL_BDDC && rank_prec_comm == active_rank ) { 24390c7d97c5SJed Brown PetscScalar m_one=-1.0; 24405619798eSStefano Zampini PetscReal infty_error,lambda_min,lambda_max,kappa_2; 2441*3b03a366Sstefano_zampini const KSPType check_ksp_type=KSPGMRES; 24420c7d97c5SJed Brown 24435619798eSStefano Zampini /* change coarse ksp object to an iterative method suitable for extreme eigenvalues' estimation */ 2444*3b03a366Sstefano_zampini ierr = KSPSetType(pcbddc->coarse_ksp,check_ksp_type);CHKERRQ(ierr); 2445d49ef151SStefano Zampini ierr = KSPSetComputeSingularValues(pcbddc->coarse_ksp,PETSC_TRUE);CHKERRQ(ierr); 24465619798eSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,1.e-8,1.e-8,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 24475619798eSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 2448d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->coarse_rhs,PETSC_NULL);CHKERRQ(ierr); 2449d49ef151SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 2450d49ef151SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,pcbddc->coarse_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 2451d49ef151SStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,pcbddc->coarse_rhs,pcbddc->coarse_rhs);CHKERRQ(ierr); 2452d49ef151SStefano Zampini ierr = KSPComputeExtremeSingularValues(pcbddc->coarse_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); 2453*3b03a366Sstefano_zampini if(dbg_flag) { 24545619798eSStefano Zampini kappa_2=lambda_max/lambda_min; 24555619798eSStefano Zampini ierr = KSPGetIterationNumber(pcbddc->coarse_ksp,&k);CHKERRQ(ierr); 2456d49ef151SStefano Zampini ierr = VecAXPY(pcbddc->coarse_rhs,m_one,pcbddc->coarse_vec);CHKERRQ(ierr); 2457d49ef151SStefano Zampini ierr = VecNorm(pcbddc->coarse_rhs,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 2458*3b03a366Sstefano_zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem condition number estimated with %d iterations of %s is: % 1.14e\n",k,check_ksp_type,kappa_2);CHKERRQ(ierr); 2459e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues: % 1.14e %1.14e\n",lambda_min,lambda_max);CHKERRQ(ierr); 2460e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem infty_error: %1.14e\n",infty_error);CHKERRQ(ierr); 2461*3b03a366Sstefano_zampini } 24625619798eSStefano Zampini /* restore coarse ksp to default values */ 2463d49ef151SStefano Zampini ierr = KSPSetComputeSingularValues(pcbddc->coarse_ksp,PETSC_FALSE);CHKERRQ(ierr); 24645619798eSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 2465*3b03a366Sstefano_zampini ierr = KSPChebychevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 2466*3b03a366Sstefano_zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,max_it_coarse_ksp);CHKERRQ(ierr); 24675619798eSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 24685619798eSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 246953cdbc3dSStefano Zampini } 24700c7d97c5SJed Brown 24710c7d97c5SJed Brown /* free data structures no longer needed */ 24720c7d97c5SJed Brown if(coarse_ISLG) { ierr = ISLocalToGlobalMappingDestroy(&coarse_ISLG);CHKERRQ(ierr); } 24730c7d97c5SJed Brown if(ins_local_primal_indices) { ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); } 24740c7d97c5SJed Brown if(ins_coarse_mat_vals) { ierr = PetscFree(ins_coarse_mat_vals);CHKERRQ(ierr);} 24750c7d97c5SJed Brown if(localsizes2) { ierr = PetscFree(localsizes2);CHKERRQ(ierr);} 24760c7d97c5SJed Brown if(localdispl2) { ierr = PetscFree(localdispl2);CHKERRQ(ierr);} 24770c7d97c5SJed Brown if(temp_coarse_mat_vals) { ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr);} 24780c7d97c5SJed Brown 24790c7d97c5SJed Brown PetscFunctionReturn(0); 24800c7d97c5SJed Brown } 24810c7d97c5SJed Brown 24820c7d97c5SJed Brown #undef __FUNCT__ 24830c7d97c5SJed Brown #define __FUNCT__ "PCBDDCManageLocalBoundaries" 248453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCManageLocalBoundaries(PC pc) 24850c7d97c5SJed Brown { 24860c7d97c5SJed Brown 24870c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 24880c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 24890c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 24900c7d97c5SJed Brown PCBDDCGraph mat_graph; 24910c7d97c5SJed Brown Mat mat_adj; 2492*3b03a366Sstefano_zampini PetscInt **neighbours_set; 2493a0ba757dSStefano Zampini PetscInt *queue_in_global_numbering; 2494*3b03a366Sstefano_zampini PetscInt bs,ierr,i,j,s,k,iindex,neumann_bsize,dirichlet_bsize; 2495*3b03a366Sstefano_zampini PetscInt total_counts,nodes_touched=0,where_values=1,vertex_size; 2496*3b03a366Sstefano_zampini PetscMPIInt adapt_interface=0,adapt_interface_reduced=0; 2497*3b03a366Sstefano_zampini PetscBool same_set,flg_row; 2498*3b03a366Sstefano_zampini PetscBool symmetrize_rowij=PETSC_TRUE,compressed_rowij=PETSC_FALSE; 2499a0ba757dSStefano Zampini MPI_Comm interface_comm=((PetscObject)pc)->comm; 2500*3b03a366Sstefano_zampini PetscBool use_faces=PETSC_FALSE,use_edges=PETSC_FALSE; 2501*3b03a366Sstefano_zampini const PetscInt *neumann_nodes; 2502*3b03a366Sstefano_zampini const PetscInt *dirichlet_nodes; 25030c7d97c5SJed Brown 25040c7d97c5SJed Brown PetscFunctionBegin; 2505a0ba757dSStefano Zampini /* allocate and initialize needed graph structure */ 25060c7d97c5SJed Brown ierr = PetscMalloc(sizeof(*mat_graph),&mat_graph);CHKERRQ(ierr); 25070c7d97c5SJed Brown ierr = MatConvert(matis->A,MATMPIADJ,MAT_INITIAL_MATRIX,&mat_adj);CHKERRQ(ierr); 2508a0ba757dSStefano Zampini /* ierr = MatDuplicate(matis->A,MAT_COPY_VALUES,&mat_adj);CHKERRQ(ierr); */ 2509a0ba757dSStefano Zampini ierr = MatGetRowIJ(mat_adj,0,symmetrize_rowij,compressed_rowij,&mat_graph->nvtxs,&mat_graph->xadj,&mat_graph->adjncy,&flg_row);CHKERRQ(ierr); 25100c7d97c5SJed Brown if(!flg_row) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatGetRowIJ called from PCBDDCManageLocalBoundaries.\n"); 2511a0ba757dSStefano Zampini i = mat_graph->nvtxs; 2512a0ba757dSStefano 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); 2513a0ba757dSStefano Zampini ierr = PetscMalloc3(i,PetscInt,&mat_graph->which_dof,i,PetscBool,&mat_graph->touched,i,PetscInt,&queue_in_global_numbering);CHKERRQ(ierr); 2514a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->where,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2515a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->count,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2516a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->which_dof,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2517a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->queue,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 25183828260eSStefano Zampini ierr = PetscMemzero(mat_graph->cptr,(mat_graph->nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 25193828260eSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){mat_graph->touched[i]=PETSC_FALSE;} 2520a0ba757dSStefano Zampini 25219c0446d6SStefano Zampini /* Setting dofs splitting in mat_graph->which_dof */ 25229c0446d6SStefano Zampini if(pcbddc->n_ISForDofs) { /* get information about dofs' splitting if provided by the user */ 25239c0446d6SStefano Zampini PetscInt *is_indices; 25249c0446d6SStefano Zampini PetscInt is_size; 25259c0446d6SStefano Zampini for(i=0;i<pcbddc->n_ISForDofs;i++) { 25269c0446d6SStefano Zampini ierr = ISGetSize(pcbddc->ISForDofs[i],&is_size);CHKERRQ(ierr); 25279c0446d6SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofs[i],(const PetscInt**)&is_indices);CHKERRQ(ierr); 25289c0446d6SStefano Zampini for(j=0;j<is_size;j++) { 25299c0446d6SStefano Zampini mat_graph->which_dof[is_indices[j]]=i; 25309c0446d6SStefano Zampini } 25319c0446d6SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofs[i],(const PetscInt**)&is_indices);CHKERRQ(ierr); 25329c0446d6SStefano Zampini } 2533*3b03a366Sstefano_zampini /* use mat block size as vertex size */ 2534*3b03a366Sstefano_zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 2535*3b03a366Sstefano_zampini } else { /* otherwise it assumes a constant block size */ 2536a0ba757dSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 25370c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs/bs;i++) { 25380c7d97c5SJed Brown for(s=0;s<bs;s++) { 25390c7d97c5SJed Brown mat_graph->which_dof[i*bs+s]=s; 25400c7d97c5SJed Brown } 25410c7d97c5SJed Brown } 2542*3b03a366Sstefano_zampini vertex_size=1; 25439c0446d6SStefano Zampini } 2544*3b03a366Sstefano_zampini /* count number of neigh per node */ 25450c7d97c5SJed Brown total_counts=0; 2546*3b03a366Sstefano_zampini for(i=1;i<pcis->n_neigh;i++){ 25470c7d97c5SJed Brown s=pcis->n_shared[i]; 25480c7d97c5SJed Brown total_counts+=s; 254953cdbc3dSStefano Zampini for(j=0;j<s;j++){ 25500c7d97c5SJed Brown mat_graph->count[pcis->shared[i][j]] += 1; 25510c7d97c5SJed Brown } 25520c7d97c5SJed Brown } 2553*3b03a366Sstefano_zampini /* Take into account Neumann data -> it increments number of sharing subdomains for all but faces nodes lying on the interface */ 255453cdbc3dSStefano Zampini if(pcbddc->NeumannBoundaries) { 25559c0446d6SStefano Zampini ierr = ISGetSize(pcbddc->NeumannBoundaries,&neumann_bsize);CHKERRQ(ierr); 255653cdbc3dSStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundaries,&neumann_nodes);CHKERRQ(ierr); 255753cdbc3dSStefano Zampini for(i=0;i<neumann_bsize;i++){ 255853cdbc3dSStefano Zampini iindex = neumann_nodes[i]; 2559*3b03a366Sstefano_zampini if(mat_graph->count[iindex] > 1){ 256053cdbc3dSStefano Zampini mat_graph->count[iindex]+=1; 25610c7d97c5SJed Brown total_counts++; 25620c7d97c5SJed Brown } 25630c7d97c5SJed Brown } 25640c7d97c5SJed Brown } 2565*3b03a366Sstefano_zampini /* allocate space for storing the set of neighbours of each node */ 256653cdbc3dSStefano Zampini ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt*),&neighbours_set);CHKERRQ(ierr); 2567*3b03a366Sstefano_zampini if(mat_graph->nvtxs) { ierr = PetscMalloc(total_counts*sizeof(PetscInt),&neighbours_set[0]);CHKERRQ(ierr); } 256853cdbc3dSStefano Zampini for(i=1;i<mat_graph->nvtxs;i++) neighbours_set[i]=neighbours_set[i-1]+mat_graph->count[i-1]; 2569a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->count,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2570*3b03a366Sstefano_zampini for(i=1;i<pcis->n_neigh;i++){ 25710c7d97c5SJed Brown s=pcis->n_shared[i]; 25720c7d97c5SJed Brown for(j=0;j<s;j++) { 25730c7d97c5SJed Brown k=pcis->shared[i][j]; 257453cdbc3dSStefano Zampini neighbours_set[k][mat_graph->count[k]] = pcis->neigh[i]; 25750c7d97c5SJed Brown mat_graph->count[k]+=1; 25760c7d97c5SJed Brown } 25770c7d97c5SJed Brown } 2578*3b03a366Sstefano_zampini /* set -1 fake neighbour to mimic Neumann boundary */ 257953cdbc3dSStefano Zampini if(pcbddc->NeumannBoundaries) { 258053cdbc3dSStefano Zampini for(i=0;i<neumann_bsize;i++){ 258153cdbc3dSStefano Zampini iindex = neumann_nodes[i]; 2582*3b03a366Sstefano_zampini if(mat_graph->count[iindex] > 1){ 2583*3b03a366Sstefano_zampini neighbours_set[iindex][mat_graph->count[iindex]] = -1; 258453cdbc3dSStefano Zampini mat_graph->count[iindex]+=1; 25850c7d97c5SJed Brown } 25860c7d97c5SJed Brown } 258753cdbc3dSStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundaries,&neumann_nodes);CHKERRQ(ierr); 25880c7d97c5SJed Brown } 2589*3b03a366Sstefano_zampini /* sort set of sharing subdomains (needed for comparison below) */ 259053cdbc3dSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++) { ierr = PetscSortInt(mat_graph->count[i],neighbours_set[i]);CHKERRQ(ierr); } 2591*3b03a366Sstefano_zampini /* remove interior nodes and dirichlet boundary nodes from the next search into the graph */ 2592*3b03a366Sstefano_zampini if(pcbddc->DirichletBoundaries) { 2593*3b03a366Sstefano_zampini ierr = ISGetSize(pcbddc->DirichletBoundaries,&dirichlet_bsize);CHKERRQ(ierr); 2594*3b03a366Sstefano_zampini ierr = ISGetIndices(pcbddc->DirichletBoundaries,&dirichlet_nodes);CHKERRQ(ierr); 2595*3b03a366Sstefano_zampini for(i=0;i<dirichlet_bsize;i++){ 2596*3b03a366Sstefano_zampini mat_graph->count[dirichlet_nodes[i]]=0; 2597*3b03a366Sstefano_zampini } 2598*3b03a366Sstefano_zampini ierr = ISRestoreIndices(pcbddc->DirichletBoundaries,&dirichlet_nodes);CHKERRQ(ierr); 2599*3b03a366Sstefano_zampini } 26000c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs;i++){ 2601*3b03a366Sstefano_zampini if(!mat_graph->count[i]){ /* interior nodes */ 26020c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 26030c7d97c5SJed Brown mat_graph->where[i]=0; 26040c7d97c5SJed Brown nodes_touched++; 26050c7d97c5SJed Brown } 26060c7d97c5SJed Brown } 26070c7d97c5SJed Brown mat_graph->ncmps = 0; 26080c7d97c5SJed Brown while(nodes_touched<mat_graph->nvtxs) { 2609a0ba757dSStefano Zampini /* find first untouched node in local ordering */ 26100c7d97c5SJed Brown i=0; 26110c7d97c5SJed Brown while(mat_graph->touched[i]) i++; 26120c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 2613a0ba757dSStefano Zampini mat_graph->where[i]=where_values; 26140c7d97c5SJed Brown nodes_touched++; 2615a0ba757dSStefano Zampini /* now find all other nodes having the same set of sharing subdomains */ 26160c7d97c5SJed Brown for(j=i+1;j<mat_graph->nvtxs;j++){ 2617a0ba757dSStefano Zampini /* check for same number of sharing subdomains and dof number */ 26180c7d97c5SJed Brown if(mat_graph->count[i]==mat_graph->count[j] && mat_graph->which_dof[i] == mat_graph->which_dof[j] ){ 2619a0ba757dSStefano Zampini /* check for same set of sharing subdomains */ 26200c7d97c5SJed Brown same_set=PETSC_TRUE; 26210c7d97c5SJed Brown for(k=0;k<mat_graph->count[j];k++){ 262253cdbc3dSStefano Zampini if(neighbours_set[i][k]!=neighbours_set[j][k]) { 26230c7d97c5SJed Brown same_set=PETSC_FALSE; 26240c7d97c5SJed Brown } 26250c7d97c5SJed Brown } 2626a0ba757dSStefano Zampini /* I found a friend of mine */ 26270c7d97c5SJed Brown if(same_set) { 2628a0ba757dSStefano Zampini mat_graph->where[j]=where_values; 26290c7d97c5SJed Brown mat_graph->touched[j]=PETSC_TRUE; 26300c7d97c5SJed Brown nodes_touched++; 26310c7d97c5SJed Brown } 26320c7d97c5SJed Brown } 26330c7d97c5SJed Brown } 2634a0ba757dSStefano Zampini where_values++; 26350c7d97c5SJed Brown } 2636a0ba757dSStefano Zampini where_values--; if(where_values<0) where_values=0; 2637a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscMPIInt),&mat_graph->where_ncmps);CHKERRQ(ierr); 2638a0ba757dSStefano Zampini /* Find connected components defined on the shared interface */ 2639a0ba757dSStefano Zampini if(where_values) { 2640a0ba757dSStefano Zampini ierr = PCBDDCFindConnectedComponents(mat_graph, where_values); 2641*3b03a366Sstefano_zampini /* For consistency among neughbouring procs, I need to sort (by global ordering) each connected component */ 2642a0ba757dSStefano Zampini for(i=0;i<mat_graph->ncmps;i++) { 2643a0ba757dSStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,mat_graph->cptr[i+1]-mat_graph->cptr[i],&mat_graph->queue[mat_graph->cptr[i]],&queue_in_global_numbering[mat_graph->cptr[i]]);CHKERRQ(ierr); 2644a0ba757dSStefano Zampini ierr = PetscSortIntWithArray(mat_graph->cptr[i+1]-mat_graph->cptr[i],&queue_in_global_numbering[mat_graph->cptr[i]],&mat_graph->queue[mat_graph->cptr[i]]);CHKERRQ(ierr); 2645a0ba757dSStefano Zampini } 2646a0ba757dSStefano Zampini } 2647a0ba757dSStefano Zampini /* check consistency of connected components among neighbouring subdomains -> it adapt them in case it is needed */ 2648a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 2649*3b03a366Sstefano_zampini /* We are not sure that two connected components will be the same among subdomains sharing a subset of local interface */ 2650*3b03a366Sstefano_zampini if(mat_graph->where_ncmps[i]>1) { 2651a0ba757dSStefano Zampini adapt_interface=1; 2652a0ba757dSStefano Zampini break; 2653a0ba757dSStefano Zampini } 2654a0ba757dSStefano Zampini } 2655a0ba757dSStefano Zampini ierr = MPI_Allreduce(&adapt_interface,&adapt_interface_reduced,1,MPIU_INT,MPI_LOR,interface_comm);CHKERRQ(ierr); 2656a0ba757dSStefano Zampini if(where_values && adapt_interface_reduced) { 26570c7d97c5SJed Brown 2658*3b03a366Sstefano_zampini printf("Adapting Interface\n"); 2659*3b03a366Sstefano_zampini 2660a0ba757dSStefano Zampini PetscInt sum_requests=0,my_rank; 2661a0ba757dSStefano Zampini PetscInt buffer_size,start_of_recv,size_of_recv,start_of_send; 2662a0ba757dSStefano Zampini PetscInt temp_buffer_size,ins_val,global_where_counter; 2663a0ba757dSStefano Zampini PetscInt *cum_recv_counts; 2664a0ba757dSStefano Zampini PetscInt *where_to_nodes_indices; 2665a0ba757dSStefano Zampini PetscInt *petsc_buffer; 2666a0ba757dSStefano Zampini PetscMPIInt *recv_buffer; 2667a0ba757dSStefano Zampini PetscMPIInt *recv_buffer_where; 2668a0ba757dSStefano Zampini PetscMPIInt *send_buffer; 2669a0ba757dSStefano Zampini PetscMPIInt size_of_send; 2670a0ba757dSStefano Zampini PetscInt *sizes_of_sends; 2671a0ba757dSStefano Zampini MPI_Request *send_requests; 2672a0ba757dSStefano Zampini MPI_Request *recv_requests; 2673a0ba757dSStefano Zampini PetscInt *where_cc_adapt; 2674a0ba757dSStefano Zampini PetscInt **temp_buffer; 2675a0ba757dSStefano Zampini PetscInt *nodes_to_temp_buffer_indices; 2676a0ba757dSStefano Zampini PetscInt *add_to_where; 2677a0ba757dSStefano Zampini 2678a0ba757dSStefano Zampini ierr = MPI_Comm_rank(interface_comm,&my_rank);CHKERRQ(ierr); 2679a0ba757dSStefano Zampini ierr = PetscMalloc((where_values+1)*sizeof(PetscInt),&cum_recv_counts);CHKERRQ(ierr); 2680a0ba757dSStefano Zampini ierr = PetscMemzero(cum_recv_counts,(where_values+1)*sizeof(PetscInt));CHKERRQ(ierr); 2681a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&where_to_nodes_indices);CHKERRQ(ierr); 2682a0ba757dSStefano Zampini /* first count how many neighbours per connected component I will receive from */ 2683a0ba757dSStefano Zampini cum_recv_counts[0]=0; 2684a0ba757dSStefano Zampini for(i=1;i<where_values+1;i++){ 2685a0ba757dSStefano Zampini j=0; 2686a0ba757dSStefano Zampini while(mat_graph->where[j] != i) j++; 2687a0ba757dSStefano Zampini where_to_nodes_indices[i-1]=j; 2688*3b03a366Sstefano_zampini if(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 */ 2689*3b03a366Sstefano_zampini else { cum_recv_counts[i]=cum_recv_counts[i-1]+mat_graph->count[j]-1; } 2690a0ba757dSStefano Zampini } 2691a0ba757dSStefano Zampini buffer_size=2*cum_recv_counts[where_values]+mat_graph->nvtxs; 2692a0ba757dSStefano Zampini ierr = PetscMalloc(2*cum_recv_counts[where_values]*sizeof(PetscMPIInt),&recv_buffer_where);CHKERRQ(ierr); 2693a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 2694a0ba757dSStefano Zampini ierr = PetscMalloc(cum_recv_counts[where_values]*sizeof(MPI_Request),&send_requests);CHKERRQ(ierr); 2695a0ba757dSStefano Zampini ierr = PetscMalloc(cum_recv_counts[where_values]*sizeof(MPI_Request),&recv_requests);CHKERRQ(ierr); 2696a0ba757dSStefano Zampini for(i=0;i<cum_recv_counts[where_values];i++) { 2697a0ba757dSStefano Zampini send_requests[i]=MPI_REQUEST_NULL; 2698a0ba757dSStefano Zampini recv_requests[i]=MPI_REQUEST_NULL; 2699a0ba757dSStefano Zampini } 2700a0ba757dSStefano Zampini /* exchange with my neighbours the number of my connected components on the shared interface */ 2701a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2702a0ba757dSStefano Zampini j=where_to_nodes_indices[i]; 2703a0ba757dSStefano Zampini k = (neighbours_set[j][0] == -1 ? 1 : 0); 2704a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2705a0ba757dSStefano Zampini ierr = MPI_Isend(&mat_graph->where_ncmps[i],1,MPIU_INT,neighbours_set[j][k],(my_rank+1)*mat_graph->count[j],interface_comm,&send_requests[sum_requests]);CHKERRQ(ierr); 2706a0ba757dSStefano Zampini ierr = MPI_Irecv(&recv_buffer_where[sum_requests],1,MPIU_INT,neighbours_set[j][k],(neighbours_set[j][k]+1)*mat_graph->count[j],interface_comm,&recv_requests[sum_requests]);CHKERRQ(ierr); 2707a0ba757dSStefano Zampini sum_requests++; 2708a0ba757dSStefano Zampini } 2709a0ba757dSStefano Zampini } 2710a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2711a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2712a0ba757dSStefano Zampini /* determine the connected component I need to adapt */ 2713a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&where_cc_adapt);CHKERRQ(ierr); 2714a0ba757dSStefano Zampini ierr = PetscMemzero(where_cc_adapt,where_values*sizeof(PetscInt));CHKERRQ(ierr); 2715a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2716a0ba757dSStefano Zampini for(j=cum_recv_counts[i];j<cum_recv_counts[i+1];j++){ 2717*3b03a366Sstefano_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 */ 2718*3b03a366Sstefano_zampini if( mat_graph->where_ncmps[i]!=recv_buffer_where[j] || mat_graph->where_ncmps[i] > 1 ) { 2719a0ba757dSStefano Zampini where_cc_adapt[i]=PETSC_TRUE; 2720a0ba757dSStefano Zampini break; 2721a0ba757dSStefano Zampini } 2722a0ba757dSStefano Zampini } 2723a0ba757dSStefano Zampini } 2724a0ba757dSStefano Zampini /* now get from neighbours their ccs (in global numbering) and adapt them (in case it is needed) */ 2725a0ba757dSStefano Zampini /* first determine how much data to send (size of each queue plus the global indices) and communicate it to neighbours */ 2726a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&sizes_of_sends);CHKERRQ(ierr); 2727a0ba757dSStefano Zampini ierr = PetscMemzero(sizes_of_sends,where_values*sizeof(PetscInt));CHKERRQ(ierr); 2728a0ba757dSStefano Zampini sum_requests=0; 2729a0ba757dSStefano Zampini start_of_send=0; 2730a0ba757dSStefano Zampini start_of_recv=cum_recv_counts[where_values]; 2731a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 2732a0ba757dSStefano Zampini if(where_cc_adapt[i]) { 2733a0ba757dSStefano Zampini size_of_send=0; 2734a0ba757dSStefano Zampini for(j=i;j<mat_graph->ncmps;j++) { 2735a0ba757dSStefano Zampini if(mat_graph->where[mat_graph->queue[mat_graph->cptr[j]]] == i+1) { /* WARNING -> where values goes from 1 to where_values included */ 2736a0ba757dSStefano Zampini send_buffer[start_of_send+size_of_send]=mat_graph->cptr[j+1]-mat_graph->cptr[j]; 2737a0ba757dSStefano Zampini size_of_send+=1; 2738a0ba757dSStefano Zampini for(k=0;k<mat_graph->cptr[j+1]-mat_graph->cptr[j];k++) { 2739a0ba757dSStefano Zampini send_buffer[start_of_send+size_of_send+k]=queue_in_global_numbering[mat_graph->cptr[j]+k]; 2740a0ba757dSStefano Zampini } 2741a0ba757dSStefano Zampini size_of_send=size_of_send+mat_graph->cptr[j+1]-mat_graph->cptr[j]; 2742a0ba757dSStefano Zampini } 2743a0ba757dSStefano Zampini } 2744a0ba757dSStefano Zampini j = where_to_nodes_indices[i]; 2745a0ba757dSStefano Zampini k = (neighbours_set[j][0] == -1 ? 1 : 0); 2746a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2747a0ba757dSStefano Zampini ierr = MPI_Isend(&size_of_send,1,MPIU_INT,neighbours_set[j][k],(my_rank+1)*mat_graph->count[j],interface_comm,&send_requests[sum_requests]);CHKERRQ(ierr); 2748a0ba757dSStefano Zampini ierr = MPI_Irecv(&recv_buffer_where[sum_requests+start_of_recv],1,MPIU_INT,neighbours_set[j][k],(neighbours_set[j][k]+1)*mat_graph->count[j],interface_comm,&recv_requests[sum_requests]);CHKERRQ(ierr); 2749a0ba757dSStefano Zampini sum_requests++; 2750a0ba757dSStefano Zampini } 2751a0ba757dSStefano Zampini sizes_of_sends[i]=size_of_send; 2752a0ba757dSStefano Zampini start_of_send+=size_of_send; 2753a0ba757dSStefano Zampini } 2754a0ba757dSStefano Zampini } 2755a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2756a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2757a0ba757dSStefano Zampini buffer_size=0; 2758a0ba757dSStefano Zampini for(k=0;k<sum_requests;k++) { buffer_size+=recv_buffer_where[start_of_recv+k]; } 2759a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscMPIInt),&recv_buffer);CHKERRQ(ierr); 2760a0ba757dSStefano Zampini /* now exchange the data */ 2761a0ba757dSStefano Zampini start_of_recv=0; 2762a0ba757dSStefano Zampini start_of_send=0; 2763a0ba757dSStefano Zampini sum_requests=0; 2764a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 2765a0ba757dSStefano Zampini if(where_cc_adapt[i]) { 2766a0ba757dSStefano Zampini size_of_send = sizes_of_sends[i]; 2767a0ba757dSStefano Zampini j = where_to_nodes_indices[i]; 2768a0ba757dSStefano Zampini k = (neighbours_set[j][0] == -1 ? 1 : 0); 2769a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2770a0ba757dSStefano Zampini ierr = MPI_Isend(&send_buffer[start_of_send],size_of_send,MPIU_INT,neighbours_set[j][k],(my_rank+1)*mat_graph->count[j],interface_comm,&send_requests[sum_requests]);CHKERRQ(ierr); 2771a0ba757dSStefano Zampini size_of_recv=recv_buffer_where[cum_recv_counts[where_values]+sum_requests]; 2772a0ba757dSStefano Zampini ierr = MPI_Irecv(&recv_buffer[start_of_recv],size_of_recv,MPIU_INT,neighbours_set[j][k],(neighbours_set[j][k]+1)*mat_graph->count[j],interface_comm,&recv_requests[sum_requests]);CHKERRQ(ierr); 2773a0ba757dSStefano Zampini start_of_recv+=size_of_recv; 2774a0ba757dSStefano Zampini sum_requests++; 2775a0ba757dSStefano Zampini } 2776a0ba757dSStefano Zampini start_of_send+=size_of_send; 2777a0ba757dSStefano Zampini } 2778a0ba757dSStefano Zampini } 2779a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2780a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2781a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscInt),&petsc_buffer);CHKERRQ(ierr); 2782a0ba757dSStefano Zampini for(k=0;k<start_of_recv;k++) { petsc_buffer[k]=(PetscInt)recv_buffer[k]; } 2783a0ba757dSStefano Zampini for(j=0;j<buffer_size;) { 2784a0ba757dSStefano Zampini ierr = ISGlobalToLocalMappingApply(matis->mapping,IS_GTOLM_MASK,petsc_buffer[j],&petsc_buffer[j+1],&petsc_buffer[j],&petsc_buffer[j+1]);CHKERRQ(ierr); 2785a0ba757dSStefano Zampini k=petsc_buffer[j]+1; 2786a0ba757dSStefano Zampini j+=k; 2787a0ba757dSStefano Zampini } 2788a0ba757dSStefano Zampini sum_requests=cum_recv_counts[where_values]; 2789a0ba757dSStefano Zampini start_of_recv=0; 2790a0ba757dSStefano Zampini ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt),&nodes_to_temp_buffer_indices);CHKERRQ(ierr); 2791a0ba757dSStefano Zampini global_where_counter=0; 2792a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2793a0ba757dSStefano Zampini if(where_cc_adapt[i]){ 2794a0ba757dSStefano Zampini temp_buffer_size=0; 2795a0ba757dSStefano Zampini /* find nodes on the shared interface we need to adapt */ 2796a0ba757dSStefano Zampini for(j=0;j<mat_graph->nvtxs;j++){ 2797a0ba757dSStefano Zampini if(mat_graph->where[j]==i+1) { 2798a0ba757dSStefano Zampini nodes_to_temp_buffer_indices[j]=temp_buffer_size; 2799a0ba757dSStefano Zampini temp_buffer_size++; 2800a0ba757dSStefano Zampini } else { 2801a0ba757dSStefano Zampini nodes_to_temp_buffer_indices[j]=-1; 2802a0ba757dSStefano Zampini } 2803a0ba757dSStefano Zampini } 2804a0ba757dSStefano Zampini /* allocate some temporary space */ 2805a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*sizeof(PetscInt*),&temp_buffer);CHKERRQ(ierr); 2806a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*(cum_recv_counts[i+1]-cum_recv_counts[i])*sizeof(PetscInt),&temp_buffer[0]);CHKERRQ(ierr); 2807a0ba757dSStefano Zampini ierr = PetscMemzero(temp_buffer[0],temp_buffer_size*(cum_recv_counts[i+1]-cum_recv_counts[i])*sizeof(PetscInt));CHKERRQ(ierr); 2808a0ba757dSStefano Zampini for(j=1;j<temp_buffer_size;j++){ 2809a0ba757dSStefano Zampini temp_buffer[j]=temp_buffer[j-1]+cum_recv_counts[i+1]-cum_recv_counts[i]; 2810a0ba757dSStefano Zampini } 2811a0ba757dSStefano Zampini /* analyze contributions from neighbouring subdomains for i-th conn comp 2812a0ba757dSStefano Zampini temp buffer structure: 2813a0ba757dSStefano Zampini supposing part of the interface has dimension 5 (global nodes 0,1,2,3,4) 2814a0ba757dSStefano Zampini 3 neighs procs with structured connected components: 2815a0ba757dSStefano Zampini neigh 0: [0 1 4], [2 3]; (2 connected components) 2816a0ba757dSStefano Zampini neigh 1: [0 1], [2 3 4]; (2 connected components) 2817a0ba757dSStefano Zampini neigh 2: [0 4], [1], [2 3]; (3 connected components) 2818a0ba757dSStefano Zampini tempbuffer (row-oriented) should be filled as: 2819a0ba757dSStefano Zampini [ 0, 0, 0; 2820a0ba757dSStefano Zampini 0, 0, 1; 2821a0ba757dSStefano Zampini 1, 1, 2; 2822a0ba757dSStefano Zampini 1, 1, 2; 2823a0ba757dSStefano Zampini 0, 1, 0; ]; 2824a0ba757dSStefano Zampini This way we can simply recover the resulting structure account for possible intersections of ccs among neighs. 2825a0ba757dSStefano Zampini The mat_graph->where array will be modified to reproduce the following 4 connected components [0], [1], [2 3], [4]; 2826a0ba757dSStefano Zampini */ 2827a0ba757dSStefano Zampini for(j=0;j<cum_recv_counts[i+1]-cum_recv_counts[i];j++) { 2828a0ba757dSStefano Zampini ins_val=0; 2829a0ba757dSStefano Zampini size_of_recv=recv_buffer_where[sum_requests]; /* total size of recv from neighs */ 2830a0ba757dSStefano Zampini for(buffer_size=0;buffer_size<size_of_recv;) { /* loop until all data from neighs has been taken into account */ 2831a0ba757dSStefano Zampini for(k=1;k<petsc_buffer[buffer_size+start_of_recv]+1;k++) { /* filling properly temp_buffer using data from a single recv */ 2832a0ba757dSStefano Zampini temp_buffer[ nodes_to_temp_buffer_indices[ petsc_buffer[ start_of_recv+buffer_size+k ] ] ][j]=ins_val; 2833a0ba757dSStefano Zampini } 2834a0ba757dSStefano Zampini buffer_size+=k; 2835a0ba757dSStefano Zampini ins_val++; 2836a0ba757dSStefano Zampini } 2837a0ba757dSStefano Zampini start_of_recv+=size_of_recv; 2838a0ba757dSStefano Zampini sum_requests++; 2839a0ba757dSStefano Zampini } 2840a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*sizeof(PetscInt),&add_to_where);CHKERRQ(ierr); 2841a0ba757dSStefano Zampini ierr = PetscMemzero(add_to_where,temp_buffer_size*sizeof(PetscInt));CHKERRQ(ierr); 2842a0ba757dSStefano Zampini for(j=0;j<temp_buffer_size;j++){ 2843a0ba757dSStefano Zampini if(!add_to_where[j]){ /* found a new cc */ 2844a0ba757dSStefano Zampini global_where_counter++; 2845a0ba757dSStefano Zampini add_to_where[j]=global_where_counter; 2846a0ba757dSStefano Zampini for(k=j+1;k<temp_buffer_size;k++){ /* check for other nodes in new cc */ 2847a0ba757dSStefano Zampini same_set=PETSC_TRUE; 2848a0ba757dSStefano Zampini for(s=0;s<cum_recv_counts[i+1]-cum_recv_counts[i];s++){ 2849a0ba757dSStefano Zampini if(temp_buffer[j][s]!=temp_buffer[k][s]) { 2850a0ba757dSStefano Zampini same_set=PETSC_FALSE; 2851a0ba757dSStefano Zampini break; 2852a0ba757dSStefano Zampini } 2853a0ba757dSStefano Zampini } 2854a0ba757dSStefano Zampini if(same_set) add_to_where[k]=global_where_counter; 2855a0ba757dSStefano Zampini } 2856a0ba757dSStefano Zampini } 2857a0ba757dSStefano Zampini } 2858a0ba757dSStefano Zampini /* insert new data in where array */ 2859a0ba757dSStefano Zampini temp_buffer_size=0; 2860a0ba757dSStefano Zampini for(j=0;j<mat_graph->nvtxs;j++){ 2861a0ba757dSStefano Zampini if(mat_graph->where[j]==i+1) { 2862a0ba757dSStefano Zampini mat_graph->where[j]=where_values+add_to_where[temp_buffer_size]; 2863a0ba757dSStefano Zampini temp_buffer_size++; 2864a0ba757dSStefano Zampini } 2865a0ba757dSStefano Zampini } 2866a0ba757dSStefano Zampini ierr = PetscFree(temp_buffer[0]);CHKERRQ(ierr); 2867a0ba757dSStefano Zampini ierr = PetscFree(temp_buffer);CHKERRQ(ierr); 2868a0ba757dSStefano Zampini ierr = PetscFree(add_to_where);CHKERRQ(ierr); 2869a0ba757dSStefano Zampini } 2870a0ba757dSStefano Zampini } 2871a0ba757dSStefano Zampini ierr = PetscFree(nodes_to_temp_buffer_indices);CHKERRQ(ierr); 2872a0ba757dSStefano Zampini ierr = PetscFree(sizes_of_sends);CHKERRQ(ierr); 2873a0ba757dSStefano Zampini ierr = PetscFree(send_requests);CHKERRQ(ierr); 2874a0ba757dSStefano Zampini ierr = PetscFree(recv_requests);CHKERRQ(ierr); 2875a0ba757dSStefano Zampini ierr = PetscFree(petsc_buffer);CHKERRQ(ierr); 2876a0ba757dSStefano Zampini ierr = PetscFree(recv_buffer);CHKERRQ(ierr); 2877a0ba757dSStefano Zampini ierr = PetscFree(recv_buffer_where);CHKERRQ(ierr); 2878a0ba757dSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 2879a0ba757dSStefano Zampini ierr = PetscFree(cum_recv_counts);CHKERRQ(ierr); 2880a0ba757dSStefano Zampini ierr = PetscFree(where_to_nodes_indices);CHKERRQ(ierr); 2881a0ba757dSStefano Zampini /* We are ready to evaluate consistent connected components on each part of the shared interface */ 2882a0ba757dSStefano Zampini if(global_where_counter) { 2883a0ba757dSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){ mat_graph->touched[i]=PETSC_FALSE; } 2884a0ba757dSStefano Zampini global_where_counter=0; 2885a0ba757dSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){ 2886a0ba757dSStefano Zampini if(mat_graph->where[i] && !mat_graph->touched[i]) { 2887a0ba757dSStefano Zampini global_where_counter++; 2888a0ba757dSStefano Zampini for(j=i+1;j<mat_graph->nvtxs;j++){ 2889a0ba757dSStefano Zampini if(!mat_graph->touched[j] && mat_graph->where[j]==mat_graph->where[i]) { 2890a0ba757dSStefano Zampini mat_graph->where[j]=global_where_counter; 2891a0ba757dSStefano Zampini mat_graph->touched[j]=PETSC_TRUE; 2892a0ba757dSStefano Zampini } 2893a0ba757dSStefano Zampini } 2894a0ba757dSStefano Zampini mat_graph->where[i]=global_where_counter; 2895a0ba757dSStefano Zampini mat_graph->touched[i]=PETSC_TRUE; 2896a0ba757dSStefano Zampini } 2897a0ba757dSStefano Zampini } 2898a0ba757dSStefano Zampini where_values=global_where_counter; 2899a0ba757dSStefano Zampini } 2900a0ba757dSStefano Zampini if(global_where_counter) { 2901a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->cptr,(mat_graph->nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 2902a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->queue,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2903a0ba757dSStefano Zampini ierr = PetscFree(mat_graph->where_ncmps);CHKERRQ(ierr); 2904a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscMPIInt),&mat_graph->where_ncmps);CHKERRQ(ierr); 2905a0ba757dSStefano Zampini ierr = PCBDDCFindConnectedComponents(mat_graph, where_values); 2906a0ba757dSStefano Zampini for(i=0;i<mat_graph->ncmps;i++) { 2907a0ba757dSStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,mat_graph->cptr[i+1]-mat_graph->cptr[i],&mat_graph->queue[mat_graph->cptr[i]],&queue_in_global_numbering[mat_graph->cptr[i]]);CHKERRQ(ierr); 2908a0ba757dSStefano Zampini ierr = PetscSortIntWithArray(mat_graph->cptr[i+1]-mat_graph->cptr[i],&queue_in_global_numbering[mat_graph->cptr[i]],&mat_graph->queue[mat_graph->cptr[i]]);CHKERRQ(ierr); 2909a0ba757dSStefano Zampini } 2910a0ba757dSStefano Zampini } 2911*3b03a366Sstefano_zampini } /* Finished adapting interface */ 29120c7d97c5SJed Brown PetscInt nfc=0; 29130c7d97c5SJed Brown PetscInt nec=0; 29140c7d97c5SJed Brown PetscInt nvc=0; 2915*3b03a366Sstefano_zampini PetscBool twodim_flag=PETSC_FALSE; 29160c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 2917*3b03a366Sstefano_zampini if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > vertex_size ){ 2918*3b03a366Sstefano_zampini if(mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]==1){ /* 1 neigh */ 29190c7d97c5SJed Brown nfc++; 2920*3b03a366Sstefano_zampini } else { /* note that nec will be zero in 2d */ 2921*3b03a366Sstefano_zampini nec++; 2922*3b03a366Sstefano_zampini } 29230c7d97c5SJed Brown } else { 2924*3b03a366Sstefano_zampini nvc+=mat_graph->cptr[i+1]-mat_graph->cptr[i]; 2925*3b03a366Sstefano_zampini } 2926*3b03a366Sstefano_zampini } 2927*3b03a366Sstefano_zampini 2928*3b03a366Sstefano_zampini if(!nec) { /* we are in a 2d case -> no faces, only edges */ 2929*3b03a366Sstefano_zampini nec = nfc; 2930*3b03a366Sstefano_zampini nfc = 0; 2931*3b03a366Sstefano_zampini twodim_flag = PETSC_TRUE; 2932*3b03a366Sstefano_zampini } 2933*3b03a366Sstefano_zampini /* allocate IS arrays for faces, edges. Vertices need a single index set. 2934*3b03a366Sstefano_zampini Reusing space allocated in mat_graph->where for creating IS objects */ 2935*3b03a366Sstefano_zampini if(!pcbddc->vertices_flag && !pcbddc->edges_flag) { 2936*3b03a366Sstefano_zampini ierr = PetscMalloc(nfc*sizeof(IS),&pcbddc->ISForFaces);CHKERRQ(ierr); 2937*3b03a366Sstefano_zampini use_faces=PETSC_TRUE; 2938*3b03a366Sstefano_zampini } 2939*3b03a366Sstefano_zampini if(!pcbddc->vertices_flag && !pcbddc->faces_flag) { 2940*3b03a366Sstefano_zampini ierr = PetscMalloc(nec*sizeof(IS),&pcbddc->ISForEdges);CHKERRQ(ierr); 2941*3b03a366Sstefano_zampini use_edges=PETSC_TRUE; 2942*3b03a366Sstefano_zampini } 2943*3b03a366Sstefano_zampini nfc=0; 2944*3b03a366Sstefano_zampini nec=0; 2945*3b03a366Sstefano_zampini for (i=0; i<mat_graph->ncmps; i++) { 2946*3b03a366Sstefano_zampini if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > vertex_size ){ 2947*3b03a366Sstefano_zampini for(j=0;j<mat_graph->cptr[i+1]-mat_graph->cptr[i];j++) { 2948*3b03a366Sstefano_zampini mat_graph->where[j]=mat_graph->queue[mat_graph->cptr[i]+j]; 2949*3b03a366Sstefano_zampini } 2950*3b03a366Sstefano_zampini if(mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]==1){ 2951*3b03a366Sstefano_zampini if(twodim_flag) { 2952*3b03a366Sstefano_zampini if(use_edges) { 2953*3b03a366Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,mat_graph->where,PETSC_COPY_VALUES,&pcbddc->ISForEdges[nec]);CHKERRQ(ierr); 2954*3b03a366Sstefano_zampini nec++; 2955*3b03a366Sstefano_zampini } 2956*3b03a366Sstefano_zampini } else { 2957*3b03a366Sstefano_zampini if(use_faces) { 2958*3b03a366Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,mat_graph->where,PETSC_COPY_VALUES,&pcbddc->ISForFaces[nfc]);CHKERRQ(ierr); 2959*3b03a366Sstefano_zampini nfc++; 2960*3b03a366Sstefano_zampini } 2961*3b03a366Sstefano_zampini } 2962*3b03a366Sstefano_zampini } else { 2963*3b03a366Sstefano_zampini if(use_edges) { 2964*3b03a366Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,mat_graph->where,PETSC_COPY_VALUES,&pcbddc->ISForEdges[nec]);CHKERRQ(ierr); 29650c7d97c5SJed Brown nec++; 29660c7d97c5SJed Brown } 29670c7d97c5SJed Brown } 29680c7d97c5SJed Brown } 2969*3b03a366Sstefano_zampini } 2970*3b03a366Sstefano_zampini pcbddc->n_ISForFaces=nfc; 2971*3b03a366Sstefano_zampini pcbddc->n_ISForEdges=nec; 2972*3b03a366Sstefano_zampini nvc=0; 29730c7d97c5SJed Brown if( !pcbddc->constraints_flag ) { 2974*3b03a366Sstefano_zampini for (i=0; i<mat_graph->ncmps; i++) { 2975*3b03a366Sstefano_zampini if( mat_graph->cptr[i+1]-mat_graph->cptr[i] <= vertex_size ){ 2976*3b03a366Sstefano_zampini for( j=mat_graph->cptr[i];j<mat_graph->cptr[i+1];j++) { 2977*3b03a366Sstefano_zampini mat_graph->where[nvc]=mat_graph->queue[j]; 29780c7d97c5SJed Brown nvc++; 29790c7d97c5SJed Brown } 29800c7d97c5SJed Brown } 29810c7d97c5SJed Brown } 29820c7d97c5SJed Brown } 2983a0ba757dSStefano Zampini /* sort vertex set (by local ordering) */ 2984*3b03a366Sstefano_zampini ierr = PetscSortInt(nvc,mat_graph->where);CHKERRQ(ierr); 2985*3b03a366Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nvc,mat_graph->where,PETSC_COPY_VALUES,&pcbddc->ISForVertices);CHKERRQ(ierr); 29860c7d97c5SJed Brown 2987e269702eSStefano Zampini if(pcbddc->dbg_flag) { 2988e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 2989e269702eSStefano Zampini 2990d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2991d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Details from PCBDDCManageLocalBoundaries for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 2992d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2993a0ba757dSStefano Zampini /* ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Graph (adjacency structure) of local Neumann mat\n");CHKERRQ(ierr); 2994a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2995e269702eSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++) { 2996a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Nodes connected to node number %d are %d\n",i,mat_graph->xadj[i+1]-mat_graph->xadj[i]);CHKERRQ(ierr); 2997e269702eSStefano Zampini for(j=mat_graph->xadj[i];j<mat_graph->xadj[i+1];j++){ 2998a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d ",mat_graph->adjncy[j]);CHKERRQ(ierr); 2999e269702eSStefano Zampini } 3000a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n--------------------------------------------------------------\n");CHKERRQ(ierr); 3001*3b03a366Sstefano_zampini } 3002d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Matrix graph has %d connected components", mat_graph->ncmps);CHKERRQ(ierr); 30030c7d97c5SJed Brown for(i=0;i<mat_graph->ncmps;i++) { 3004*3b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\nDetails for connected component number %02d: size %04d, count %01d. Nodes follow.\n", 3005*3b03a366Sstefano_zampini i,mat_graph->cptr[i+1]-mat_graph->cptr[i],mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]);CHKERRQ(ierr); 30060c7d97c5SJed Brown for (j=mat_graph->cptr[i]; j<mat_graph->cptr[i+1]; j++){ 30073828260eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d (%d), ",queue_in_global_numbering[j],mat_graph->queue[j]);CHKERRQ(ierr); 30080c7d97c5SJed Brown } 30090c7d97c5SJed Brown } 3010*3b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n--------------------------------------------------------------\n");CHKERRQ(ierr);*/ 3011*3b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local vertices\n",PetscGlobalRank,nvc);CHKERRQ(ierr); 3012*3b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local faces\n",PetscGlobalRank,nfc);CHKERRQ(ierr); 3013*3b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local edges\n",PetscGlobalRank,nec);CHKERRQ(ierr); 3014d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 30150c7d97c5SJed Brown } 30160c7d97c5SJed Brown 3017a0ba757dSStefano Zampini /* Restore CSR structure into sequantial matrix and free memory space no longer needed */ 3018a0ba757dSStefano Zampini ierr = MatRestoreRowIJ(mat_adj,0,symmetrize_rowij,compressed_rowij,&mat_graph->nvtxs,&mat_graph->xadj,&mat_graph->adjncy,&flg_row);CHKERRQ(ierr); 30190c7d97c5SJed Brown if(!flg_row) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called from PCBDDCManageLocalBoundaries.\n"); 3020a0ba757dSStefano Zampini ierr = MatDestroy(&mat_adj);CHKERRQ(ierr); 3021a0ba757dSStefano Zampini /* Free graph structure */ 30220c7d97c5SJed Brown if(mat_graph->nvtxs){ 3023a0ba757dSStefano Zampini ierr = PetscFree(neighbours_set[0]);CHKERRQ(ierr); 3024a0ba757dSStefano Zampini ierr = PetscFree(neighbours_set);CHKERRQ(ierr); 3025a0ba757dSStefano Zampini ierr = PetscFree4(mat_graph->where,mat_graph->count,mat_graph->cptr,mat_graph->queue);CHKERRQ(ierr); 3026a0ba757dSStefano Zampini ierr = PetscFree3(mat_graph->which_dof,mat_graph->touched,queue_in_global_numbering);CHKERRQ(ierr); 3027a0ba757dSStefano Zampini ierr = PetscFree(mat_graph->where_ncmps);CHKERRQ(ierr); 30280c7d97c5SJed Brown } 30290c7d97c5SJed Brown ierr = PetscFree(mat_graph);CHKERRQ(ierr); 30300c7d97c5SJed Brown 30310c7d97c5SJed Brown PetscFunctionReturn(0); 30320c7d97c5SJed Brown 30330c7d97c5SJed Brown } 30340c7d97c5SJed Brown 30350c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 30360c7d97c5SJed Brown 30370c7d97c5SJed Brown /* The following code has been adapted from function IsConnectedSubdomain contained 30380c7d97c5SJed Brown in source file contig.c of METIS library (version 5.0.1) */ 30390c7d97c5SJed Brown 30400c7d97c5SJed Brown #undef __FUNCT__ 30410c7d97c5SJed Brown #define __FUNCT__ "PCBDDCFindConnectedComponents" 30429c0446d6SStefano Zampini static PetscErrorCode PCBDDCFindConnectedComponents(PCBDDCGraph graph, PetscInt n_dist ) 30430c7d97c5SJed Brown { 30440c7d97c5SJed Brown PetscInt i, j, k, nvtxs, first, last, nleft, ncmps,pid,cum_queue,n,ncmps_pid; 30450c7d97c5SJed Brown PetscInt *xadj, *adjncy, *where, *queue; 30460c7d97c5SJed Brown PetscInt *cptr; 30470c7d97c5SJed Brown PetscBool *touched; 30480c7d97c5SJed Brown 30490c7d97c5SJed Brown PetscFunctionBegin; 30500c7d97c5SJed Brown 30510c7d97c5SJed Brown nvtxs = graph->nvtxs; 30520c7d97c5SJed Brown xadj = graph->xadj; 30530c7d97c5SJed Brown adjncy = graph->adjncy; 30540c7d97c5SJed Brown where = graph->where; 30550c7d97c5SJed Brown touched = graph->touched; 30560c7d97c5SJed Brown queue = graph->queue; 30570c7d97c5SJed Brown cptr = graph->cptr; 30580c7d97c5SJed Brown 30590c7d97c5SJed Brown for (i=0; i<nvtxs; i++) 30600c7d97c5SJed Brown touched[i] = PETSC_FALSE; 30610c7d97c5SJed Brown 30620c7d97c5SJed Brown cum_queue=0; 30630c7d97c5SJed Brown ncmps=0; 30640c7d97c5SJed Brown 30650c7d97c5SJed Brown for(n=0; n<n_dist; n++) { 3066a0ba757dSStefano Zampini pid = n+1; 30670c7d97c5SJed Brown nleft = 0; 30680c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 30690c7d97c5SJed Brown if (where[i] == pid) 30700c7d97c5SJed Brown nleft++; 30710c7d97c5SJed Brown } 30720c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 30730c7d97c5SJed Brown if (where[i] == pid) 30740c7d97c5SJed Brown break; 30750c7d97c5SJed Brown } 30760c7d97c5SJed Brown touched[i] = PETSC_TRUE; 30770c7d97c5SJed Brown queue[cum_queue] = i; 30780c7d97c5SJed Brown first = 0; last = 1; 30790c7d97c5SJed Brown cptr[ncmps] = cum_queue; /* This actually points to queue */ 30800c7d97c5SJed Brown ncmps_pid = 0; 30810c7d97c5SJed Brown while (first != nleft) { 30820c7d97c5SJed Brown if (first == last) { /* Find another starting vertex */ 30830c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 30840c7d97c5SJed Brown ncmps_pid++; 30850c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 30860c7d97c5SJed Brown if (where[i] == pid && !touched[i]) 30870c7d97c5SJed Brown break; 30880c7d97c5SJed Brown } 30890c7d97c5SJed Brown queue[cum_queue+last] = i; 30900c7d97c5SJed Brown last++; 30910c7d97c5SJed Brown touched[i] = PETSC_TRUE; 30920c7d97c5SJed Brown } 30930c7d97c5SJed Brown i = queue[cum_queue+first]; 30940c7d97c5SJed Brown first++; 30950c7d97c5SJed Brown for (j=xadj[i]; j<xadj[i+1]; j++) { 30960c7d97c5SJed Brown k = adjncy[j]; 30970c7d97c5SJed Brown if (where[k] == pid && !touched[k]) { 30980c7d97c5SJed Brown queue[cum_queue+last] = k; 30990c7d97c5SJed Brown last++; 31000c7d97c5SJed Brown touched[k] = PETSC_TRUE; 31010c7d97c5SJed Brown } 31020c7d97c5SJed Brown } 31030c7d97c5SJed Brown } 31040c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 31050c7d97c5SJed Brown ncmps_pid++; 31060c7d97c5SJed Brown cum_queue=cptr[ncmps]; 3107a0ba757dSStefano Zampini graph->where_ncmps[n] = ncmps_pid; 31080c7d97c5SJed Brown } 31090c7d97c5SJed Brown graph->ncmps = ncmps; 31100c7d97c5SJed Brown 31110c7d97c5SJed Brown PetscFunctionReturn(0); 31120c7d97c5SJed Brown } 31130c7d97c5SJed Brown 3114