153cdbc3dSStefano Zampini /* TODOLIST 2a0ba757dSStefano Zampini change how to deal with the coarse problem (PCBDDCSetCoarseEnvironment): 3a0ba757dSStefano Zampini - mind the problem with coarsening_factor 4a0ba757dSStefano Zampini - simplify coarse problem structure -> PCBDDC or PCREDUDANT, nothing else -> same comm for all levels? 5a0ba757dSStefano Zampini - remove coarse enums and allow use of PCBDDCGetCoarseKSP 6a0ba757dSStefano Zampini - remove metis dependency -> use MatPartitioning for multilevel -> Assemble serial adjacency in ManageLocalBoundaries? 7a0ba757dSStefano Zampini - Add level slot to bddc data structure and associated Set/Get functions 8a0ba757dSStefano Zampini code refactoring: 9a0ba757dSStefano Zampini - removing indices to constraints, quadrature constrainsts and similar from PCBDDCManageLocalBoundaries 10a0ba757dSStefano Zampini - analyze MatSetNearNullSpace as suggested by Jed 11a0ba757dSStefano Zampini - build constraint matrix after SVD on local connected components 12a0ba757dSStefano Zampini - pick up better names for static functions 13a0ba757dSStefano Zampini check log_summary for leaking (actually: 1 Vector per level plus only 1 IS) 14a0ba757dSStefano Zampini Inexact solvers: global preconditioner application is ready, ask to developers (Jed?) on how to best implement Dohrmann's approach (PCSHELL?) 15a0ba757dSStefano Zampini change options structure: 16a0ba757dSStefano Zampini - insert BDDC into MG framework? 17a0ba757dSStefano Zampini provide other ops? Ask to developers 18a0ba757dSStefano Zampini remove all unused printf 19a0ba757dSStefano Zampini remove // commments and adhere to PETSc code requirements 20a0ba757dSStefano Zampini man pages 2153cdbc3dSStefano Zampini */ 220c7d97c5SJed Brown 2353cdbc3dSStefano Zampini /* ---------------------------------------------------------------------------------------------------------------------------------------------- 240c7d97c5SJed Brown Implementation of BDDC preconditioner based on: 250c7d97c5SJed Brown C. Dohrmann "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 2653cdbc3dSStefano Zampini ---------------------------------------------------------------------------------------------------------------------------------------------- */ 2753cdbc3dSStefano Zampini 2853cdbc3dSStefano Zampini #include "bddc.h" /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 290c7d97c5SJed Brown 300c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 310c7d97c5SJed Brown #undef __FUNCT__ 320c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC" 330c7d97c5SJed Brown PetscErrorCode PCSetFromOptions_BDDC(PC pc) 340c7d97c5SJed Brown { 350c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 360c7d97c5SJed Brown PetscErrorCode ierr; 370c7d97c5SJed Brown 380c7d97c5SJed Brown PetscFunctionBegin; 390c7d97c5SJed Brown ierr = PetscOptionsHead("BDDC options");CHKERRQ(ierr); 400c7d97c5SJed Brown /* Verbose debugging of main data structures */ 41e269702eSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_check_all" ,"Verbose (debugging) output for PCBDDC" ,"none",pcbddc->dbg_flag ,&pcbddc->dbg_flag ,PETSC_NULL);CHKERRQ(ierr); 420c7d97c5SJed Brown /* Some customization for default primal space */ 430c7d97c5SJed 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); 440c7d97c5SJed 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); 450c7d97c5SJed 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); 460c7d97c5SJed 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); 470c7d97c5SJed Brown /* Coarse solver context */ 480c7d97c5SJed Brown static const char *avail_coarse_problems[] = {"sequential","replicated","parallel","multilevel",""}; //order of choiches depends on ENUM defined in bddc.h 490c7d97c5SJed 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); 500c7d97c5SJed Brown /* Two different application of BDDC to the whole set of dofs, internal and interface */ 510c7d97c5SJed 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); 520c7d97c5SJed 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); 530c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 540c7d97c5SJed Brown PetscFunctionReturn(0); 550c7d97c5SJed Brown } 560c7d97c5SJed Brown 570c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 580c7d97c5SJed Brown EXTERN_C_BEGIN 590c7d97c5SJed Brown #undef __FUNCT__ 600c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType_BDDC" 6153cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetCoarseProblemType_BDDC(PC pc, CoarseProblemType CPT) 620c7d97c5SJed Brown { 630c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 640c7d97c5SJed Brown 650c7d97c5SJed Brown PetscFunctionBegin; 660c7d97c5SJed Brown pcbddc->coarse_problem_type = CPT; 670c7d97c5SJed Brown PetscFunctionReturn(0); 680c7d97c5SJed Brown } 690c7d97c5SJed Brown EXTERN_C_END 700c7d97c5SJed Brown 710c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 720c7d97c5SJed Brown #undef __FUNCT__ 730c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType" 7453cdbc3dSStefano Zampini /*@ 75*9c0446d6SStefano Zampini PCBDDCSetCoarseProblemType - Set coarse problem type in PCBDDC. 7653cdbc3dSStefano Zampini 77*9c0446d6SStefano Zampini Not collective 7853cdbc3dSStefano Zampini 7953cdbc3dSStefano Zampini Input Parameters: 8053cdbc3dSStefano Zampini + pc - the preconditioning context 8153cdbc3dSStefano Zampini - CoarseProblemType - pick a better name and explain what this is 8253cdbc3dSStefano Zampini 8353cdbc3dSStefano Zampini Level: intermediate 8453cdbc3dSStefano Zampini 8553cdbc3dSStefano Zampini Notes: 86*9c0446d6SStefano Zampini Not collective but all procs must call this. 8753cdbc3dSStefano Zampini 8853cdbc3dSStefano Zampini .seealso: PCBDDC 8953cdbc3dSStefano Zampini @*/ 900c7d97c5SJed Brown PetscErrorCode PCBDDCSetCoarseProblemType(PC pc, CoarseProblemType CPT) 910c7d97c5SJed Brown { 920c7d97c5SJed Brown PetscErrorCode ierr; 930c7d97c5SJed Brown 940c7d97c5SJed Brown PetscFunctionBegin; 950c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 960c7d97c5SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetCoarseProblemType_C",(PC,CoarseProblemType),(pc,CPT));CHKERRQ(ierr); 970c7d97c5SJed Brown PetscFunctionReturn(0); 980c7d97c5SJed Brown } 990c7d97c5SJed Brown 1000c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1010c7d97c5SJed Brown EXTERN_C_BEGIN 1020c7d97c5SJed Brown #undef __FUNCT__ 1030c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 10453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 1050c7d97c5SJed Brown { 1060c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 10753cdbc3dSStefano Zampini PetscErrorCode ierr; 1080c7d97c5SJed Brown 1090c7d97c5SJed Brown PetscFunctionBegin; 110*9c0446d6SStefano Zampini //ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 11153cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 11253cdbc3dSStefano Zampini ierr = ISDuplicate(NeumannBoundaries,&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 11353cdbc3dSStefano Zampini ierr = ISCopy(NeumannBoundaries,pcbddc->NeumannBoundaries);CHKERRQ(ierr); 1140c7d97c5SJed Brown PetscFunctionReturn(0); 1150c7d97c5SJed Brown } 1160c7d97c5SJed Brown EXTERN_C_END 1170c7d97c5SJed Brown 1180c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1190c7d97c5SJed Brown #undef __FUNCT__ 1200c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 12157527edcSJed Brown /*@ 12253cdbc3dSStefano Zampini PCBDDCSetNeumannBoundaries - Set index set defining subdomain part of 12353cdbc3dSStefano Zampini Neumann boundaries for the global problem. 12457527edcSJed Brown 125*9c0446d6SStefano Zampini Not collective 12657527edcSJed Brown 12757527edcSJed Brown Input Parameters: 12857527edcSJed Brown + pc - the preconditioning context 129*9c0446d6SStefano Zampini - NeumannBoundaries - sequential index set defining the subdomain part of Neumann boundaries (can be PETSC_NULL) 13057527edcSJed Brown 13157527edcSJed Brown Level: intermediate 13257527edcSJed Brown 13357527edcSJed Brown Notes: 134*9c0446d6SStefano Zampini The sequential IS is copied; the user must destroy the IS object passed in. 13557527edcSJed Brown 13657527edcSJed Brown .seealso: PCBDDC 13757527edcSJed Brown @*/ 13853cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 1390c7d97c5SJed Brown { 1400c7d97c5SJed Brown PetscErrorCode ierr; 1410c7d97c5SJed Brown 1420c7d97c5SJed Brown PetscFunctionBegin; 1430c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 14453cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 14553cdbc3dSStefano Zampini PetscFunctionReturn(0); 14653cdbc3dSStefano Zampini } 14753cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 14853cdbc3dSStefano Zampini EXTERN_C_BEGIN 14953cdbc3dSStefano Zampini #undef __FUNCT__ 15053cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 15153cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 15253cdbc3dSStefano Zampini { 15353cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15453cdbc3dSStefano Zampini 15553cdbc3dSStefano Zampini PetscFunctionBegin; 15653cdbc3dSStefano Zampini if(pcbddc->NeumannBoundaries) { 15753cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 15853cdbc3dSStefano Zampini } else { 159*9c0446d6SStefano Zampini *NeumannBoundaries = PETSC_NULL; 160*9c0446d6SStefano Zampini //SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Error in %s: Neumann boundaries not set!.\n",__FUNCT__); 16153cdbc3dSStefano Zampini } 16253cdbc3dSStefano Zampini PetscFunctionReturn(0); 16353cdbc3dSStefano Zampini } 16453cdbc3dSStefano Zampini EXTERN_C_END 16553cdbc3dSStefano Zampini 16653cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 16753cdbc3dSStefano Zampini #undef __FUNCT__ 16853cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 16953cdbc3dSStefano Zampini /*@ 17053cdbc3dSStefano Zampini PCBDDCGetNeumannBoundaries - Get index set defining subdomain part of 17153cdbc3dSStefano Zampini Neumann boundaries for the global problem. 17253cdbc3dSStefano Zampini 173*9c0446d6SStefano Zampini Not collective 17453cdbc3dSStefano Zampini 17553cdbc3dSStefano Zampini Input Parameters: 17653cdbc3dSStefano Zampini + pc - the preconditioning context 17753cdbc3dSStefano Zampini 17853cdbc3dSStefano Zampini Output Parameters: 17953cdbc3dSStefano Zampini + NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 18053cdbc3dSStefano Zampini 18153cdbc3dSStefano Zampini Level: intermediate 18253cdbc3dSStefano Zampini 18353cdbc3dSStefano Zampini Notes: 184*9c0446d6SStefano Zampini If the user has not yet provided such information, PETSC_NULL is returned. 18553cdbc3dSStefano Zampini 18653cdbc3dSStefano Zampini .seealso: PCBDDC 18753cdbc3dSStefano Zampini @*/ 18853cdbc3dSStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 18953cdbc3dSStefano Zampini { 19053cdbc3dSStefano Zampini PetscErrorCode ierr; 19153cdbc3dSStefano Zampini 19253cdbc3dSStefano Zampini PetscFunctionBegin; 19353cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 19453cdbc3dSStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 1950c7d97c5SJed Brown PetscFunctionReturn(0); 1960c7d97c5SJed Brown } 1970c7d97c5SJed Brown 198*9c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 199*9c0446d6SStefano Zampini EXTERN_C_BEGIN 200*9c0446d6SStefano Zampini #undef __FUNCT__ 201*9c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 202*9c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 203*9c0446d6SStefano Zampini { 204*9c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 205*9c0446d6SStefano Zampini PetscInt i; 206*9c0446d6SStefano Zampini PetscErrorCode ierr; 207*9c0446d6SStefano Zampini 208*9c0446d6SStefano Zampini PetscFunctionBegin; 209*9c0446d6SStefano Zampini /* Destroy IS if already set */ 210*9c0446d6SStefano Zampini for(i=0;i<pcbddc->n_ISForDofs;i++) { 211*9c0446d6SStefano Zampini //ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 212*9c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 213*9c0446d6SStefano Zampini ierr = ISDuplicate(ISForDofs[i],&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 214*9c0446d6SStefano Zampini ierr = ISCopy(ISForDofs[i],pcbddc->ISForDofs[i]);CHKERRQ(ierr); 215*9c0446d6SStefano Zampini } 216*9c0446d6SStefano Zampini /* allocate space then copy ISs */ 217*9c0446d6SStefano Zampini ierr = PetscMalloc(n_is*sizeof(IS),&pcbddc->ISForDofs);CHKERRQ(ierr); 218*9c0446d6SStefano Zampini for(i=0;i<n_is;i++) { 219*9c0446d6SStefano Zampini ierr = ISDuplicate(ISForDofs[i],&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 220*9c0446d6SStefano Zampini ierr = ISCopy(ISForDofs[i],pcbddc->ISForDofs[i]);CHKERRQ(ierr); 221*9c0446d6SStefano Zampini } 222*9c0446d6SStefano Zampini pcbddc->n_ISForDofs=n_is; 223*9c0446d6SStefano Zampini PetscFunctionReturn(0); 224*9c0446d6SStefano Zampini } 225*9c0446d6SStefano Zampini EXTERN_C_END 226*9c0446d6SStefano Zampini 227*9c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 228*9c0446d6SStefano Zampini #undef __FUNCT__ 229*9c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 230*9c0446d6SStefano Zampini /*@ 231*9c0446d6SStefano Zampini PCBDDCSetDofsSplitting - Set index set defining how dofs are splitted. 232*9c0446d6SStefano Zampini 233*9c0446d6SStefano Zampini Not collective 234*9c0446d6SStefano Zampini 235*9c0446d6SStefano Zampini Input Parameters: 236*9c0446d6SStefano Zampini + pc - the preconditioning context 237*9c0446d6SStefano Zampini - n - number of index sets defining dofs spltting 238*9c0446d6SStefano Zampini - IS[] - array of IS describing dofs splitting 239*9c0446d6SStefano Zampini 240*9c0446d6SStefano Zampini Level: intermediate 241*9c0446d6SStefano Zampini 242*9c0446d6SStefano Zampini Notes: 243*9c0446d6SStefano Zampini Sequential ISs are copied, the user must destroy the array of IS passed in. 244*9c0446d6SStefano Zampini 245*9c0446d6SStefano Zampini .seealso: PCBDDC 246*9c0446d6SStefano Zampini @*/ 247*9c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 248*9c0446d6SStefano Zampini { 249*9c0446d6SStefano Zampini PetscErrorCode ierr; 250*9c0446d6SStefano Zampini 251*9c0446d6SStefano Zampini PetscFunctionBegin; 252*9c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 253*9c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 254*9c0446d6SStefano Zampini PetscFunctionReturn(0); 255*9c0446d6SStefano Zampini } 256*9c0446d6SStefano Zampini 25753cdbc3dSStefano Zampini #undef __FUNCT__ 25853cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 2590c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2600c7d97c5SJed Brown /* 2610c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 2620c7d97c5SJed Brown by setting data structures and options. 2630c7d97c5SJed Brown 2640c7d97c5SJed Brown Input Parameter: 26553cdbc3dSStefano Zampini + pc - the preconditioner context 2660c7d97c5SJed Brown 2670c7d97c5SJed Brown Application Interface Routine: PCSetUp() 2680c7d97c5SJed Brown 2690c7d97c5SJed Brown Notes: 2700c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 2710c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 2720c7d97c5SJed Brown */ 27353cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 2740c7d97c5SJed Brown { 2750c7d97c5SJed Brown PetscErrorCode ierr; 2760c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2770c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 2780c7d97c5SJed Brown 2790c7d97c5SJed Brown PetscFunctionBegin; 2800c7d97c5SJed Brown if (!pc->setupcalled) { 2810c7d97c5SJed Brown 2820c7d97c5SJed Brown /* For BDDC we need to define a local "Neumann" to that defined in PCISSetup 283*9c0446d6SStefano Zampini So, we set to pcnone the Neumann problem of pcis in order to avoid unneeded computation 2840c7d97c5SJed Brown Also, we decide to directly build the (same) Dirichlet problem */ 2850c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localN_pc_type","none");CHKERRQ(ierr); 2860c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localD_pc_type","none");CHKERRQ(ierr); 2870c7d97c5SJed Brown /* Set up all the "iterative substructuring" common block */ 2880c7d97c5SJed Brown ierr = PCISSetUp(pc);CHKERRQ(ierr); 2890c7d97c5SJed Brown /* Destroy some PC_IS data which is not needed by BDDC */ 2900c7d97c5SJed Brown //if (pcis->ksp_D) {ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr);} 2910c7d97c5SJed Brown //if (pcis->ksp_N) {ierr = KSPDestroy(&pcis->ksp_N);CHKERRQ(ierr);} 2920c7d97c5SJed Brown //if (pcis->vec2_B) {ierr = VecDestroy(&pcis->vec2_B);CHKERRQ(ierr);} 2930c7d97c5SJed Brown //if (pcis->vec3_B) {ierr = VecDestroy(&pcis->vec3_B);CHKERRQ(ierr);} 2940c7d97c5SJed Brown //pcis->ksp_D = 0; 2950c7d97c5SJed Brown //pcis->ksp_N = 0; 2960c7d97c5SJed Brown //pcis->vec2_B = 0; 2970c7d97c5SJed Brown //pcis->vec3_B = 0; 298e269702eSStefano Zampini if(pcbddc->dbg_flag) { 299e269702eSStefano Zampini ierr = PetscViewerASCIIGetStdout(((PetscObject)pc)->comm,&pcbddc->dbg_viewer);CHKERRQ(ierr); 300e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 301e269702eSStefano Zampini } 3020c7d97c5SJed Brown 3030c7d97c5SJed Brown //TODO MOVE CODE FRAGMENT 3040c7d97c5SJed Brown PetscInt im_active=0; 3050c7d97c5SJed Brown if(pcis->n) im_active = 1; 30653cdbc3dSStefano Zampini ierr = MPI_Allreduce(&im_active,&pcbddc->active_procs,1,MPIU_INT,MPI_SUM,((PetscObject)pc)->comm);CHKERRQ(ierr); 3070c7d97c5SJed Brown //printf("Calling PCBDDC MANAGE with active procs %d (im_active = %d)\n",pcbddc->active_procs,im_active); 3080c7d97c5SJed Brown /* Set up grid quantities for BDDC */ 3090c7d97c5SJed Brown //TODO only active procs must call this -> remove synchronized print inside (the only point of sync) 3100c7d97c5SJed Brown ierr = PCBDDCManageLocalBoundaries(pc);CHKERRQ(ierr); 3110c7d97c5SJed Brown 3120c7d97c5SJed Brown /* Create coarse and local stuffs used for evaluating action of preconditioner */ 3130c7d97c5SJed Brown ierr = PCBDDCCoarseSetUp(pc);CHKERRQ(ierr); 3140c7d97c5SJed Brown 3150c7d97c5SJed Brown if ( !pcis->n_neigh ) pcis->ISLocalToGlobalMappingGetInfoWasCalled=PETSC_FALSE; //processes fakely involved in multilevel should not call ISLocalToGlobalMappingRestoreInfo 3160c7d97c5SJed Brown /* We no more need this matrix */ 3170c7d97c5SJed Brown //if (pcis->A_BB) {ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr);} 3180c7d97c5SJed Brown //pcis->A_BB = 0; 3190c7d97c5SJed Brown 3200c7d97c5SJed Brown //printf("Using coarse problem type %d\n",pcbddc->coarse_problem_type); 3210c7d97c5SJed Brown //printf("Using coarse communications type %d\n",pcbddc->coarse_communications_type); 3220c7d97c5SJed Brown //printf("Using coarsening ratio %d\n",pcbddc->coarsening_ratio); 3230c7d97c5SJed Brown } 3240c7d97c5SJed Brown 3250c7d97c5SJed Brown PetscFunctionReturn(0); 3260c7d97c5SJed Brown } 3270c7d97c5SJed Brown 3280c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 3290c7d97c5SJed Brown /* 3300c7d97c5SJed Brown PCApply_BDDC - Applies the BDDC preconditioner to a vector. 3310c7d97c5SJed Brown 3320c7d97c5SJed Brown Input Parameters: 3330c7d97c5SJed Brown . pc - the preconditioner context 3340c7d97c5SJed Brown . r - input vector (global) 3350c7d97c5SJed Brown 3360c7d97c5SJed Brown Output Parameter: 3370c7d97c5SJed Brown . z - output vector (global) 3380c7d97c5SJed Brown 3390c7d97c5SJed Brown Application Interface Routine: PCApply() 3400c7d97c5SJed Brown */ 3410c7d97c5SJed Brown #undef __FUNCT__ 3420c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 34353cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 3440c7d97c5SJed Brown { 3450c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 3460c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 3470c7d97c5SJed Brown PetscErrorCode ierr; 3480c7d97c5SJed Brown PetscScalar one = 1.0; 3490c7d97c5SJed Brown PetscScalar m_one = -1.0; 3500c7d97c5SJed Brown 3510c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 3520c7d97c5SJed Brown NN interface preconditioner changed to BDDC 3530c7d97c5SJed Brown Added support for M_3 preconditioenr in the reference article (code is active if pcbddc->prec_type = PETSC_TRUE) */ 3540c7d97c5SJed Brown 3550c7d97c5SJed Brown PetscFunctionBegin; 3560c7d97c5SJed Brown /* First Dirichlet solve */ 3570c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3580c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 35953cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 3600c7d97c5SJed Brown /* 3610c7d97c5SJed Brown Assembling right hand side for BDDC operator 3620c7d97c5SJed Brown - vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE) 3630c7d97c5SJed Brown - the interface part of the global vector z 3640c7d97c5SJed Brown */ 3650c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 3660c7d97c5SJed Brown ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 3670c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3680c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 3690c7d97c5SJed Brown ierr = VecCopy(r,z);CHKERRQ(ierr); 3700c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3710c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3720c7d97c5SJed Brown 3730c7d97c5SJed Brown /* 3740c7d97c5SJed Brown Apply interface preconditioner 3750c7d97c5SJed Brown Results are stored in: 3760c7d97c5SJed Brown - vec1_D (if needed, i.e. with prec_type = PETSC_TRUE) 3770c7d97c5SJed Brown - the interface part of the global vector z 3780c7d97c5SJed Brown */ 3790c7d97c5SJed Brown ierr = PCBDDCApplyInterfacePreconditioner(pc,z);CHKERRQ(ierr); 3800c7d97c5SJed Brown 3810c7d97c5SJed Brown /* Second Dirichlet solves and assembling of output */ 3820c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3830c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3840c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 3850c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 38653cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr); 3870c7d97c5SJed Brown ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr); 3880c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); } 3890c7d97c5SJed Brown ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr); 3900c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3910c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3920c7d97c5SJed Brown 3930c7d97c5SJed Brown PetscFunctionReturn(0); 3940c7d97c5SJed Brown 3950c7d97c5SJed Brown } 3960c7d97c5SJed Brown 3970c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 3980c7d97c5SJed Brown /* 3990c7d97c5SJed Brown PCBDDCApplyInterfacePreconditioner - Apply the BDDC preconditioner at the interface. 4000c7d97c5SJed Brown 4010c7d97c5SJed Brown */ 4020c7d97c5SJed Brown #undef __FUNCT__ 4030c7d97c5SJed Brown #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 40453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, Vec z) 4050c7d97c5SJed Brown { 4060c7d97c5SJed Brown PetscErrorCode ierr; 4070c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4080c7d97c5SJed Brown PC_IS* pcis = (PC_IS*) (pc->data); 4090c7d97c5SJed Brown PetscScalar zero = 0.0; 4100c7d97c5SJed Brown 4110c7d97c5SJed Brown PetscFunctionBegin; 4120c7d97c5SJed Brown /* Get Local boundary and apply partition of unity */ 4130c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4140c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4150c7d97c5SJed Brown ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 4160c7d97c5SJed Brown 4170c7d97c5SJed Brown /* Application of PHI^T */ 4180c7d97c5SJed Brown ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 4190c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 4200c7d97c5SJed Brown 4210c7d97c5SJed Brown /* Scatter data of coarse_rhs */ 4220c7d97c5SJed Brown if(pcbddc->coarse_rhs) ierr = VecSet(pcbddc->coarse_rhs,zero);CHKERRQ(ierr); 4230c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4240c7d97c5SJed Brown 4250c7d97c5SJed Brown /* Local solution on R nodes */ 4260c7d97c5SJed Brown ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 4270c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4280c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4290c7d97c5SJed Brown if(pcbddc->prec_type) { 4300c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4310c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4320c7d97c5SJed Brown } 4330c7d97c5SJed Brown ierr = PCBDDCSolveSaddlePoint(pc);CHKERRQ(ierr); 4340c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 4350c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4360c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4370c7d97c5SJed Brown if(pcbddc->prec_type) { 4380c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4390c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4400c7d97c5SJed Brown } 4410c7d97c5SJed Brown 4420c7d97c5SJed Brown /* Coarse solution */ 4430c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 44453cdbc3dSStefano Zampini if(pcbddc->coarse_rhs) ierr = KSPSolve(pcbddc->coarse_ksp,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 4450c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4460c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd (pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4470c7d97c5SJed Brown 4480c7d97c5SJed Brown /* Sum contributions from two levels */ 4490c7d97c5SJed Brown /* Apply partition of unity and sum boundary values */ 4500c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 4510c7d97c5SJed Brown ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 4520c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 4530c7d97c5SJed Brown ierr = VecSet(z,zero);CHKERRQ(ierr); 4540c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4550c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4560c7d97c5SJed Brown 4570c7d97c5SJed Brown PetscFunctionReturn(0); 4580c7d97c5SJed Brown } 4590c7d97c5SJed Brown 4600c7d97c5SJed Brown 4610c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 4620c7d97c5SJed Brown /* 4630c7d97c5SJed Brown PCBDDCSolveSaddlePoint 4640c7d97c5SJed Brown 4650c7d97c5SJed Brown */ 4660c7d97c5SJed Brown #undef __FUNCT__ 4670c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSolveSaddlePoint" 46853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSolveSaddlePoint(PC pc) 4690c7d97c5SJed Brown { 4700c7d97c5SJed Brown PetscErrorCode ierr; 4710c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4720c7d97c5SJed Brown 4730c7d97c5SJed Brown PetscFunctionBegin; 4740c7d97c5SJed Brown 47553cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4760c7d97c5SJed Brown if(pcbddc->n_constraints) { 4770c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec2_R,pcbddc->vec1_C);CHKERRQ(ierr); 4780c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 4790c7d97c5SJed Brown } 4800c7d97c5SJed Brown 4810c7d97c5SJed Brown PetscFunctionReturn(0); 4820c7d97c5SJed Brown } 4830c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 4840c7d97c5SJed Brown /* 4850c7d97c5SJed Brown PCBDDCScatterCoarseDataBegin 4860c7d97c5SJed Brown 4870c7d97c5SJed Brown */ 4880c7d97c5SJed Brown #undef __FUNCT__ 4890c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 49053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,Vec vec_from, Vec vec_to, InsertMode imode, ScatterMode smode) 4910c7d97c5SJed Brown { 4920c7d97c5SJed Brown PetscErrorCode ierr; 4930c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4940c7d97c5SJed Brown 4950c7d97c5SJed Brown PetscFunctionBegin; 4960c7d97c5SJed Brown 4970c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 4980c7d97c5SJed Brown case SCATTERS_BDDC: 4990c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 5000c7d97c5SJed Brown break; 5010c7d97c5SJed Brown case GATHERS_BDDC: 5020c7d97c5SJed Brown break; 5030c7d97c5SJed Brown } 5040c7d97c5SJed Brown PetscFunctionReturn(0); 5050c7d97c5SJed Brown 5060c7d97c5SJed Brown } 5070c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 5080c7d97c5SJed Brown /* 5090c7d97c5SJed Brown PCBDDCScatterCoarseDataEnd 5100c7d97c5SJed Brown 5110c7d97c5SJed Brown */ 5120c7d97c5SJed Brown #undef __FUNCT__ 5130c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 51453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCScatterCoarseDataEnd(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 PetscScalar* array_to; 5190c7d97c5SJed Brown PetscScalar* array_from; 5200c7d97c5SJed Brown MPI_Comm comm=((PetscObject)pc)->comm; 5210c7d97c5SJed Brown PetscInt i; 5220c7d97c5SJed Brown 5230c7d97c5SJed Brown PetscFunctionBegin; 5240c7d97c5SJed Brown 5250c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 5260c7d97c5SJed Brown case SCATTERS_BDDC: 5270c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 5280c7d97c5SJed Brown break; 5290c7d97c5SJed Brown case GATHERS_BDDC: 5300c7d97c5SJed Brown if(vec_from) VecGetArray(vec_from,&array_from); 5310c7d97c5SJed Brown if(vec_to) VecGetArray(vec_to,&array_to); 5320c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 5330c7d97c5SJed Brown case SEQUENTIAL_BDDC: 5340c7d97c5SJed Brown if(smode == SCATTER_FORWARD) { 53553cdbc3dSStefano 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); 5360c7d97c5SJed Brown if(vec_to) { 5370c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 5380c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 5390c7d97c5SJed Brown } 5400c7d97c5SJed Brown } else { 5410c7d97c5SJed Brown if(vec_from) 5420c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 5430c7d97c5SJed Brown pcbddc->replicated_local_primal_values[i]=array_from[pcbddc->replicated_local_primal_indices[i]]; 54453cdbc3dSStefano 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); 5450c7d97c5SJed Brown } 5460c7d97c5SJed Brown break; 5470c7d97c5SJed Brown case REPLICATED_BDDC: 5480c7d97c5SJed Brown if(smode == SCATTER_FORWARD) { 54953cdbc3dSStefano 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); 5500c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 5510c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 5520c7d97c5SJed Brown } else { /* no communications needed for SCATTER_REVERSE since needed data is already present */ 5530c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_size;i++) 5540c7d97c5SJed Brown array_to[i]=array_from[pcbddc->local_primal_indices[i]]; 5550c7d97c5SJed Brown } 5560c7d97c5SJed Brown break; 55753cdbc3dSStefano Zampini case MULTILEVEL_BDDC: 55853cdbc3dSStefano Zampini break; 55953cdbc3dSStefano Zampini case PARALLEL_BDDC: 56053cdbc3dSStefano Zampini break; 5610c7d97c5SJed Brown } 5620c7d97c5SJed Brown if(vec_from) VecRestoreArray(vec_from,&array_from); 5630c7d97c5SJed Brown if(vec_to) VecRestoreArray(vec_to,&array_to); 5640c7d97c5SJed Brown break; 5650c7d97c5SJed Brown } 5660c7d97c5SJed Brown PetscFunctionReturn(0); 5670c7d97c5SJed Brown 5680c7d97c5SJed Brown } 5690c7d97c5SJed Brown 5700c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 5710c7d97c5SJed Brown /* 5720c7d97c5SJed Brown PCDestroy_BDDC - Destroys the private context for the NN preconditioner 5730c7d97c5SJed Brown that was created with PCCreate_BDDC(). 5740c7d97c5SJed Brown 5750c7d97c5SJed Brown Input Parameter: 5760c7d97c5SJed Brown . pc - the preconditioner context 5770c7d97c5SJed Brown 5780c7d97c5SJed Brown Application Interface Routine: PCDestroy() 5790c7d97c5SJed Brown */ 5800c7d97c5SJed Brown #undef __FUNCT__ 5810c7d97c5SJed Brown #define __FUNCT__ "PCDestroy_BDDC" 58253cdbc3dSStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 5830c7d97c5SJed Brown { 5840c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5850c7d97c5SJed Brown PetscErrorCode ierr; 5860c7d97c5SJed Brown 5870c7d97c5SJed Brown PetscFunctionBegin; 5880c7d97c5SJed Brown /* free data created by PCIS */ 5890c7d97c5SJed Brown ierr = PCISDestroy(pc);CHKERRQ(ierr); 5900c7d97c5SJed Brown /* free BDDC data */ 59153cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 59253cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->coarse_rhs);CHKERRQ(ierr); 59353cdbc3dSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 59453cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_mat);CHKERRQ(ierr); 59553cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 59653cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 59753cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 59853cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 59953cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 60053cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 60153cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 60253cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 60353cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec4_D);CHKERRQ(ierr); 60453cdbc3dSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 60553cdbc3dSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 60653cdbc3dSStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 60753cdbc3dSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 60853cdbc3dSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 60953cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 61053cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->vertices);CHKERRQ(ierr); 61153cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->local_primal_indices);CHKERRQ(ierr); 61253cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 6130c7d97c5SJed Brown if (pcbddc->replicated_local_primal_values) { free(pcbddc->replicated_local_primal_values); } 61453cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->local_primal_displacements);CHKERRQ(ierr); 61553cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->local_primal_sizes);CHKERRQ(ierr); 6160c7d97c5SJed Brown if (pcbddc->n_constraints) { 6170c7d97c5SJed Brown ierr = PetscFree(pcbddc->indices_to_constraint[0]);CHKERRQ(ierr); 6180c7d97c5SJed Brown ierr = PetscFree(pcbddc->indices_to_constraint);CHKERRQ(ierr); 6190c7d97c5SJed Brown ierr = PetscFree(pcbddc->quadrature_constraint[0]);CHKERRQ(ierr); 6200c7d97c5SJed Brown ierr = PetscFree(pcbddc->quadrature_constraint);CHKERRQ(ierr); 6210c7d97c5SJed Brown ierr = PetscFree(pcbddc->sizes_of_constraint);CHKERRQ(ierr); 6220c7d97c5SJed Brown } 623*9c0446d6SStefano Zampini PetscInt i; 624*9c0446d6SStefano Zampini for(i=0;i<pcbddc->n_ISForDofs;i++) { 625*9c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 626*9c0446d6SStefano Zampini } 627*9c0446d6SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs); 6280c7d97c5SJed Brown /* Free the private data structure that was hanging off the PC */ 6290c7d97c5SJed Brown ierr = PetscFree(pcbddc);CHKERRQ(ierr); 6300c7d97c5SJed Brown PetscFunctionReturn(0); 6310c7d97c5SJed Brown } 6320c7d97c5SJed Brown 6330c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 6340c7d97c5SJed Brown /*MC 6350c7d97c5SJed Brown PCBDDC - Balancing Domain Decomposition by Constraints. 6360c7d97c5SJed Brown 6370c7d97c5SJed Brown Options Database Keys: 638a0ba757dSStefano Zampini . -pcbddc ??? - 6390c7d97c5SJed Brown 6400c7d97c5SJed Brown Level: intermediate 6410c7d97c5SJed Brown 6420c7d97c5SJed Brown Notes: The matrix used with this preconditioner must be of type MATIS 6430c7d97c5SJed Brown 6440c7d97c5SJed Brown Unlike more 'conventional' interface preconditioners, this iterates over ALL the 6450c7d97c5SJed Brown degrees of freedom, NOT just those on the interface (this allows the use of approximate solvers 6460c7d97c5SJed Brown on the subdomains). 6470c7d97c5SJed Brown 648a0ba757dSStefano Zampini Options for the coarse grid preconditioner can be set with - 649a0ba757dSStefano Zampini Options for the Dirichlet subproblem can be set with - 650a0ba757dSStefano Zampini Options for the Neumann subproblem can be set with - 6510c7d97c5SJed Brown 6520c7d97c5SJed Brown Contributed by Stefano Zampini 6530c7d97c5SJed Brown 6540c7d97c5SJed Brown .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 6550c7d97c5SJed Brown M*/ 6560c7d97c5SJed Brown EXTERN_C_BEGIN 6570c7d97c5SJed Brown #undef __FUNCT__ 6580c7d97c5SJed Brown #define __FUNCT__ "PCCreate_BDDC" 6590c7d97c5SJed Brown PetscErrorCode PCCreate_BDDC(PC pc) 6600c7d97c5SJed Brown { 6610c7d97c5SJed Brown PetscErrorCode ierr; 6620c7d97c5SJed Brown PC_BDDC *pcbddc; 6630c7d97c5SJed Brown 6640c7d97c5SJed Brown PetscFunctionBegin; 6650c7d97c5SJed Brown /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 6660c7d97c5SJed Brown ierr = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr); 6670c7d97c5SJed Brown pc->data = (void*)pcbddc; 6680c7d97c5SJed Brown /* create PCIS data structure */ 6690c7d97c5SJed Brown ierr = PCISCreate(pc);CHKERRQ(ierr); 6700c7d97c5SJed Brown /* BDDC specific */ 6710c7d97c5SJed Brown pcbddc->coarse_vec = 0; 6720c7d97c5SJed Brown pcbddc->coarse_rhs = 0; 67353cdbc3dSStefano Zampini pcbddc->coarse_ksp = 0; 6740c7d97c5SJed Brown pcbddc->coarse_phi_B = 0; 6750c7d97c5SJed Brown pcbddc->coarse_phi_D = 0; 6760c7d97c5SJed Brown pcbddc->vec1_P = 0; 6770c7d97c5SJed Brown pcbddc->vec1_R = 0; 6780c7d97c5SJed Brown pcbddc->vec2_R = 0; 6790c7d97c5SJed Brown pcbddc->local_auxmat1 = 0; 6800c7d97c5SJed Brown pcbddc->local_auxmat2 = 0; 6810c7d97c5SJed Brown pcbddc->R_to_B = 0; 6820c7d97c5SJed Brown pcbddc->R_to_D = 0; 68353cdbc3dSStefano Zampini pcbddc->ksp_D = 0; 68453cdbc3dSStefano Zampini pcbddc->ksp_R = 0; 6850c7d97c5SJed Brown pcbddc->n_constraints = 0; 6860c7d97c5SJed Brown pcbddc->n_vertices = 0; 6870c7d97c5SJed Brown pcbddc->vertices = 0; 6880c7d97c5SJed Brown pcbddc->indices_to_constraint = 0; 6890c7d97c5SJed Brown pcbddc->quadrature_constraint = 0; 6900c7d97c5SJed Brown pcbddc->sizes_of_constraint = 0; 6910c7d97c5SJed Brown pcbddc->local_primal_indices = 0; 6920c7d97c5SJed Brown pcbddc->prec_type = PETSC_FALSE; 69353cdbc3dSStefano Zampini pcbddc->NeumannBoundaries = 0; 6940c7d97c5SJed Brown pcbddc->local_primal_sizes = 0; 6950c7d97c5SJed Brown pcbddc->local_primal_displacements = 0; 6960c7d97c5SJed Brown pcbddc->replicated_local_primal_indices = 0; 6970c7d97c5SJed Brown pcbddc->replicated_local_primal_values = 0; 6980c7d97c5SJed Brown pcbddc->coarse_loc_to_glob = 0; 699e269702eSStefano Zampini pcbddc->dbg_flag = PETSC_FALSE; 7000c7d97c5SJed Brown pcbddc->vertices_flag = PETSC_FALSE; 7010c7d97c5SJed Brown pcbddc->constraints_flag = PETSC_FALSE; 7020c7d97c5SJed Brown pcbddc->faces_flag = PETSC_FALSE; 7030c7d97c5SJed Brown pcbddc->edges_flag = PETSC_FALSE; 7040c7d97c5SJed Brown pcbddc->coarsening_ratio = 8; 7050c7d97c5SJed Brown /* function pointers */ 7060c7d97c5SJed Brown pc->ops->apply = PCApply_BDDC; 7070c7d97c5SJed Brown pc->ops->applytranspose = 0; 7080c7d97c5SJed Brown pc->ops->setup = PCSetUp_BDDC; 7090c7d97c5SJed Brown pc->ops->destroy = PCDestroy_BDDC; 7100c7d97c5SJed Brown pc->ops->setfromoptions = PCSetFromOptions_BDDC; 7110c7d97c5SJed Brown pc->ops->view = 0; 7120c7d97c5SJed Brown pc->ops->applyrichardson = 0; 7130c7d97c5SJed Brown pc->ops->applysymmetricleft = 0; 7140c7d97c5SJed Brown pc->ops->applysymmetricright = 0; 7150c7d97c5SJed Brown /* composing function */ 7160c7d97c5SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C","PCBDDCSetNeumannBoundaries_BDDC", 7170c7d97c5SJed Brown PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 71853cdbc3dSStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C","PCBDDCGetNeumannBoundaries_BDDC", 71953cdbc3dSStefano Zampini PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 7200c7d97c5SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetCoarseProblemType_C","PCBDDCSetCoarseProblemType_BDDC", 7210c7d97c5SJed Brown PCBDDCSetCoarseProblemType_BDDC);CHKERRQ(ierr); 722*9c0446d6SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetDofsSplitting_C","PCBDDCSetDofsSplitting_BDDC", 723*9c0446d6SStefano Zampini PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 7240c7d97c5SJed Brown PetscFunctionReturn(0); 7250c7d97c5SJed Brown } 7260c7d97c5SJed Brown EXTERN_C_END 7270c7d97c5SJed Brown 7280c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 7290c7d97c5SJed Brown /* 7300c7d97c5SJed Brown PCBDDCCoarseSetUp - 7310c7d97c5SJed Brown */ 7320c7d97c5SJed Brown #undef __FUNCT__ 7330c7d97c5SJed Brown #define __FUNCT__ "PCBDDCCoarseSetUp" 73453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC pc) 7350c7d97c5SJed Brown { 7360c7d97c5SJed Brown PetscErrorCode ierr; 7370c7d97c5SJed Brown 7380c7d97c5SJed Brown PC_IS* pcis = (PC_IS*)(pc->data); 7390c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 7400c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 7410c7d97c5SJed Brown IS is_R_local; 7420c7d97c5SJed Brown IS is_V_local; 7430c7d97c5SJed Brown IS is_C_local; 7440c7d97c5SJed Brown IS is_aux1; 7450c7d97c5SJed Brown IS is_aux2; 7460c7d97c5SJed Brown const VecType impVecType; 7470c7d97c5SJed Brown const MatType impMatType; 7480c7d97c5SJed Brown PetscInt n_R=0; 7490c7d97c5SJed Brown PetscInt n_D=0; 7500c7d97c5SJed Brown PetscInt n_B=0; 7510c7d97c5SJed Brown PetscMPIInt totprocs; 7520c7d97c5SJed Brown PetscScalar zero=0.0; 7530c7d97c5SJed Brown PetscScalar one=1.0; 7540c7d97c5SJed Brown PetscScalar m_one=-1.0; 7550c7d97c5SJed Brown PetscScalar* array; 7560c7d97c5SJed Brown PetscScalar *coarse_submat_vals; 7570c7d97c5SJed Brown PetscInt *idx_R_local; 7580c7d97c5SJed Brown PetscInt *idx_V_B; 7590c7d97c5SJed Brown PetscScalar *coarsefunctions_errors; 7600c7d97c5SJed Brown PetscScalar *constraints_errors; 7610c7d97c5SJed Brown /* auxiliary indices */ 7620c7d97c5SJed Brown PetscInt s,i,j,k; 763e269702eSStefano Zampini /* for verbose output of bddc */ 764e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 765e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 766a0ba757dSStefano Zampini /* for counting coarse dofs */ 767a0ba757dSStefano Zampini PetscScalar coarsesum; 7680c7d97c5SJed Brown 7690c7d97c5SJed Brown PetscFunctionBegin; 7700c7d97c5SJed Brown /* Set Non-overlapping dimensions */ 7710c7d97c5SJed Brown n_B = pcis->n_B; n_D = pcis->n - n_B; 7720c7d97c5SJed Brown /* Set local primal size */ 7730c7d97c5SJed Brown pcbddc->local_primal_size = pcbddc->n_vertices + pcbddc->n_constraints; 774a0ba757dSStefano 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) */ 775a0ba757dSStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 776a0ba757dSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 777a0ba757dSStefano Zampini for(i=0;i<pcbddc->n_vertices;i++) { array[ pcbddc->vertices[i] ] = one; } 778a0ba757dSStefano Zampini for(i=0;i<pcbddc->n_constraints;i++) { 779a0ba757dSStefano Zampini for (j=0; j<pcbddc->sizes_of_constraint[i]; j++) { 780a0ba757dSStefano Zampini k = pcbddc->indices_to_constraint[i][j]; 781a0ba757dSStefano Zampini if( array[k] == zero ) { 782a0ba757dSStefano Zampini array[k] = one; 783a0ba757dSStefano Zampini break; 784a0ba757dSStefano Zampini } 785a0ba757dSStefano Zampini } 786a0ba757dSStefano Zampini } 787a0ba757dSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 788a0ba757dSStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 789a0ba757dSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 790a0ba757dSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 791a0ba757dSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 792a0ba757dSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 793a0ba757dSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 794a0ba757dSStefano Zampini for(i=0;i<pcis->n;i++) { if(array[i] > zero) array[i] = one/array[i]; } 795a0ba757dSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 796a0ba757dSStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 797a0ba757dSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 798a0ba757dSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 799a0ba757dSStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 800a0ba757dSStefano Zampini pcbddc->coarse_size = (PetscInt) coarsesum; 801a0ba757dSStefano Zampini 8020c7d97c5SJed Brown /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 8030c7d97c5SJed Brown ierr = VecSet(pcis->vec1_N,one);CHKERRQ(ierr); 8040c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8050c7d97c5SJed Brown for (i=0;i<pcbddc->n_vertices;i++) { array[ pcbddc->vertices[i] ] = zero; } 8060c7d97c5SJed Brown ierr = PetscMalloc(( pcis->n - pcbddc->n_vertices )*sizeof(PetscInt),&idx_R_local);CHKERRQ(ierr); 8070c7d97c5SJed Brown for (i=0, n_R=0; i<pcis->n; i++) { if (array[i] == one) { idx_R_local[n_R] = i; n_R++; } } 8080c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 809e269702eSStefano Zampini if(dbg_flag) { 8100c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 8110c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 8120c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 8130c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 8140c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"r_size = %d, v_size = %d, constraints = %d, local_primal_size = %d\n",n_R,pcbddc->n_vertices,pcbddc->n_constraints,pcbddc->local_primal_size);CHKERRQ(ierr); 8150c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 816a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 817a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem = %d (%f)\n",pcbddc->coarse_size,coarsesum);CHKERRQ(ierr); 818a0ba757dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 8190c7d97c5SJed Brown } 8200c7d97c5SJed Brown /* Allocate needed vectors */ 8210c7d97c5SJed Brown /* Set Mat type for local matrices needed by BDDC precondtioner */ 8220c7d97c5SJed Brown impMatType = MATSEQDENSE; 8230c7d97c5SJed Brown impVecType = VECSEQ; 8240c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_D,&pcbddc->vec4_D);CHKERRQ(ierr); 8250c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_N,&pcis->vec2_N);CHKERRQ(ierr); 8260c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_R);CHKERRQ(ierr); 8270c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_R,n_R,n_R);CHKERRQ(ierr); 8280c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 829d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 8300c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_P);CHKERRQ(ierr); 8310c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_P,pcbddc->local_primal_size,pcbddc->local_primal_size);CHKERRQ(ierr); 8320c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 8330c7d97c5SJed Brown 8340c7d97c5SJed Brown /* Creating some index sets needed */ 8350c7d97c5SJed Brown /* For submatrices */ 8360c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,n_R,idx_R_local,PETSC_COPY_VALUES,&is_R_local);CHKERRQ(ierr); 8370c7d97c5SJed Brown if(pcbddc->n_vertices) { ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->vertices,PETSC_COPY_VALUES,&is_V_local);CHKERRQ(ierr); } 8380c7d97c5SJed Brown if(pcbddc->n_constraints) { ierr = ISCreateStride (PETSC_COMM_SELF,pcbddc->n_constraints,pcbddc->n_vertices,1,&is_C_local);CHKERRQ(ierr); } 8390c7d97c5SJed Brown /* For VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 8400c7d97c5SJed Brown { 8410c7d97c5SJed Brown PetscInt *aux_array1; 8420c7d97c5SJed Brown PetscInt *aux_array2; 8430c7d97c5SJed Brown PetscScalar value; 8440c7d97c5SJed Brown 8450c7d97c5SJed Brown ierr = PetscMalloc( (pcis->n_B-pcbddc->n_vertices)*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 8460c7d97c5SJed Brown ierr = PetscMalloc( (pcis->n_B-pcbddc->n_vertices)*sizeof(PetscInt),&aux_array2);CHKERRQ(ierr); 8470c7d97c5SJed Brown 848d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 8490c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8500c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8510c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8520c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8530c7d97c5SJed Brown ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8540c7d97c5SJed Brown ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8550c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8560c7d97c5SJed Brown for (i=0, s=0; i<n_R; i++) { if (array[idx_R_local[i]] > one) { aux_array1[s] = i; s++; } } 8570c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8580c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 8590c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 8600c7d97c5SJed Brown for (i=0, s=0; i<n_B; i++) { if (array[i] > one) { aux_array2[s] = i; s++; } } 8613828260eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 8620c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array2,PETSC_COPY_VALUES,&is_aux2);CHKERRQ(ierr); 8630c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 8640c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 8650c7d97c5SJed Brown ierr = PetscFree(aux_array2);CHKERRQ(ierr); 8660c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 8670c7d97c5SJed Brown ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 8680c7d97c5SJed Brown 869e269702eSStefano Zampini if(pcbddc->prec_type || dbg_flag ) { 8700c7d97c5SJed Brown ierr = PetscMalloc(n_D*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 8710c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8720c7d97c5SJed Brown for (i=0, s=0; i<n_R; i++) { if (array[idx_R_local[i]] == one) { aux_array1[s] = i; s++; } } 8730c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8740c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 8750c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 8760c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 8770c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 8780c7d97c5SJed Brown } 8790c7d97c5SJed Brown 8800c7d97c5SJed Brown /* Check scatters */ 881e269702eSStefano Zampini if(dbg_flag) { 8820c7d97c5SJed Brown 8830c7d97c5SJed Brown Vec vec_aux; 8840c7d97c5SJed Brown 8850c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 8860c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Checking pcbddc->R_to_B scatter\n");CHKERRQ(ierr); 8870c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 888d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 889d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_B,PETSC_NULL);CHKERRQ(ierr); 890d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&vec_aux);CHKERRQ(ierr); 891d49ef151SStefano Zampini ierr = VecCopy(pcbddc->vec1_R,vec_aux);CHKERRQ(ierr); 892d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 893d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 894d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 895d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 896d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 897d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 8980c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_B FORWARD error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 899d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 9000c7d97c5SJed Brown 901d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 902d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_B,PETSC_NULL);CHKERRQ(ierr); 903d49ef151SStefano Zampini ierr = VecDuplicate(pcis->vec1_B,&vec_aux);CHKERRQ(ierr); 904d49ef151SStefano Zampini ierr = VecCopy(pcis->vec1_B,vec_aux);CHKERRQ(ierr); 905d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 906d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 907d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 908d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 909d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcis->vec1_B);CHKERRQ(ierr); 910d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 9110c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_B REVERSE error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 912d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 9130c7d97c5SJed Brown 9140c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 9150c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Checking pcbddc->R_to_D scatter\n");CHKERRQ(ierr); 9160c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 9170c7d97c5SJed Brown 918d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 919d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL);CHKERRQ(ierr); 920d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&vec_aux);CHKERRQ(ierr); 921d49ef151SStefano Zampini ierr = VecCopy(pcbddc->vec1_R,vec_aux);CHKERRQ(ierr); 922d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 923d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 924d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 925d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 926d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 927d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 9280c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_D FORWARD error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 929d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 9300c7d97c5SJed Brown 931d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 932d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL);CHKERRQ(ierr); 933d49ef151SStefano Zampini ierr = VecDuplicate(pcis->vec1_D,&vec_aux);CHKERRQ(ierr); 934d49ef151SStefano Zampini ierr = VecCopy(pcis->vec1_D,vec_aux);CHKERRQ(ierr); 935d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 936d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 937d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 938d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 939d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcis->vec1_D);CHKERRQ(ierr); 940d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 9410c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_D REVERSE error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 942d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 9430c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 9440c7d97c5SJed Brown 9450c7d97c5SJed Brown } 9460c7d97c5SJed Brown } 9470c7d97c5SJed Brown 9480c7d97c5SJed Brown /* vertices in boundary numbering */ 9490c7d97c5SJed Brown if(pcbddc->n_vertices) { 950d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,m_one);CHKERRQ(ierr); 9510c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 9520c7d97c5SJed Brown for (i=0; i<pcbddc->n_vertices; i++) { array[ pcbddc->vertices[i] ] = i; } 9530c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 954d49ef151SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 955d49ef151SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9560c7d97c5SJed Brown ierr = PetscMalloc(pcbddc->n_vertices*sizeof(PetscInt),&idx_V_B);CHKERRQ(ierr); 9570c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 9580c7d97c5SJed Brown //printf("vertices in boundary numbering\n"); 9590c7d97c5SJed Brown for (i=0; i<pcbddc->n_vertices; i++) { 9600c7d97c5SJed Brown s=0; 9610c7d97c5SJed Brown while (array[s] != i ) {s++;} 9620c7d97c5SJed Brown idx_V_B[i]=s; 9630c7d97c5SJed Brown //printf("idx_V_B[%d]=%d\n",i,s); 9640c7d97c5SJed Brown } 9650c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 9660c7d97c5SJed Brown } 9670c7d97c5SJed Brown 9680c7d97c5SJed Brown 9690c7d97c5SJed Brown /* Creating PC contexts for local Dirichlet and Neumann problems */ 9700c7d97c5SJed Brown { 9710c7d97c5SJed Brown Mat A_RR; 97253cdbc3dSStefano Zampini PC pc_temp; 9730c7d97c5SJed Brown /* Matrix for Dirichlet problem is A_II -> we already have it from pcis.c code */ 97453cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 97553cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 97653cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II,SAME_PRECONDITIONER);CHKERRQ(ierr); 97753cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 978a0ba757dSStefano Zampini //ierr = KSPSetOptionsPrefix();CHKERRQ(ierr); 9790c7d97c5SJed Brown /* default */ 98053cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 98153cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 9820c7d97c5SJed Brown /* Allow user's customization */ 98353cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 98453cdbc3dSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 98553cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 9860c7d97c5SJed Brown /* Matrix for Neumann problem is A_RR -> we need to create it */ 9870c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_R_local,is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 98853cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 98953cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 99053cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR,SAME_PRECONDITIONER);CHKERRQ(ierr); 99153cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 992a0ba757dSStefano Zampini //ierr = KSPSetOptionsPrefix();CHKERRQ(ierr); 9930c7d97c5SJed Brown /* default */ 99453cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 99553cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 9960c7d97c5SJed Brown /* Allow user's customization */ 99753cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 99853cdbc3dSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 99953cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 1000a0ba757dSStefano Zampini /* check Dirichlet and Neumann solvers */ 1001e269702eSStefano Zampini if(pcbddc->dbg_flag) { 10020c7d97c5SJed Brown Vec temp_vec; 10030c7d97c5SJed Brown PetscScalar value; 10040c7d97c5SJed Brown 1005a0ba757dSStefano Zampini ierr = VecDuplicate(pcis->vec1_D,&temp_vec);CHKERRQ(ierr); 1006a0ba757dSStefano Zampini ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL);CHKERRQ(ierr); 1007a0ba757dSStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 1008a0ba757dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,temp_vec);CHKERRQ(ierr); 1009a0ba757dSStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcis->vec1_D);CHKERRQ(ierr); 1010a0ba757dSStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 1011a0ba757dSStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1012a0ba757dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1013a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1014a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Checking solution of Dirichlet and Neumann problems\n");CHKERRQ(ierr); 1015a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Dirichlet solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 1016d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&temp_vec);CHKERRQ(ierr); 1017d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 1018d49ef151SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 1019d49ef151SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,temp_vec);CHKERRQ(ierr); 1020d49ef151SStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 1021d49ef151SStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 1022e269702eSStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 10230c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Neumann solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 1024d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 10250c7d97c5SJed Brown } 10260c7d97c5SJed Brown /* free Neumann problem's matrix */ 10270c7d97c5SJed Brown ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 10280c7d97c5SJed Brown } 10290c7d97c5SJed Brown 10300c7d97c5SJed Brown /* Assemble all remaining stuff needed to apply BDDC */ 10310c7d97c5SJed Brown { 10320c7d97c5SJed Brown Mat A_RV,A_VR,A_VV; 10330c7d97c5SJed Brown Mat M1,M2; 10340c7d97c5SJed Brown Mat C_CR; 10350c7d97c5SJed Brown Mat CMAT,AUXMAT; 10360c7d97c5SJed Brown Vec vec1_C; 10370c7d97c5SJed Brown Vec vec2_C; 10380c7d97c5SJed Brown Vec vec1_V; 10390c7d97c5SJed Brown Vec vec2_V; 10400c7d97c5SJed Brown PetscInt *nnz; 10410c7d97c5SJed Brown PetscInt *auxindices; 104253cdbc3dSStefano Zampini PetscInt index; 10430c7d97c5SJed Brown PetscScalar* array2; 10440c7d97c5SJed Brown MatFactorInfo matinfo; 10450c7d97c5SJed Brown 10460c7d97c5SJed Brown /* Allocating some extra storage just to be safe */ 10470c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 10480c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&auxindices);CHKERRQ(ierr); 10490c7d97c5SJed Brown for(i=0;i<pcis->n;i++) {auxindices[i]=i;} 10500c7d97c5SJed Brown 10510c7d97c5SJed Brown /* some work vectors on vertices and/or constraints */ 10520c7d97c5SJed Brown if(pcbddc->n_vertices) { 10530c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_V);CHKERRQ(ierr); 10540c7d97c5SJed Brown ierr = VecSetSizes(vec1_V,pcbddc->n_vertices,pcbddc->n_vertices);CHKERRQ(ierr); 10550c7d97c5SJed Brown ierr = VecSetType(vec1_V,impVecType);CHKERRQ(ierr); 10560c7d97c5SJed Brown ierr = VecDuplicate(vec1_V,&vec2_V);CHKERRQ(ierr); 10570c7d97c5SJed Brown } 10580c7d97c5SJed Brown if(pcbddc->n_constraints) { 10590c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_C);CHKERRQ(ierr); 10600c7d97c5SJed Brown ierr = VecSetSizes(vec1_C,pcbddc->n_constraints,pcbddc->n_constraints);CHKERRQ(ierr); 10610c7d97c5SJed Brown ierr = VecSetType(vec1_C,impVecType);CHKERRQ(ierr); 10620c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&vec2_C);CHKERRQ(ierr); 10630c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&pcbddc->vec1_C);CHKERRQ(ierr); 10640c7d97c5SJed Brown } 10650c7d97c5SJed Brown /* Create C matrix [I 0; 0 const] */ 1066d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&CMAT);CHKERRQ(ierr); 10670c7d97c5SJed Brown ierr = MatSetType(CMAT,MATSEQAIJ);CHKERRQ(ierr); 10680c7d97c5SJed Brown ierr = MatSetSizes(CMAT,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 10690c7d97c5SJed Brown /* nonzeros */ 10700c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++) { nnz[i]= 1; } 10710c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++) { nnz[i+pcbddc->n_vertices]=pcbddc->sizes_of_constraint[i];} 10720c7d97c5SJed Brown ierr = MatSeqAIJSetPreallocation(CMAT,0,nnz);CHKERRQ(ierr); 10730c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++) { 10740c7d97c5SJed Brown ierr = MatSetValue(CMAT,i,pcbddc->vertices[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 10750c7d97c5SJed Brown } 10760c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++) { 107753cdbc3dSStefano Zampini index=i+pcbddc->n_vertices; 107853cdbc3dSStefano Zampini ierr = MatSetValues(CMAT,1,&index,pcbddc->sizes_of_constraint[i],pcbddc->indices_to_constraint[i],pcbddc->quadrature_constraint[i],INSERT_VALUES);CHKERRQ(ierr); 10790c7d97c5SJed Brown } 10800c7d97c5SJed Brown ierr = MatAssemblyBegin(CMAT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10810c7d97c5SJed Brown ierr = MatAssemblyEnd(CMAT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10820c7d97c5SJed Brown 10830c7d97c5SJed Brown /* Precompute stuffs needed for preprocessing and application of BDDC*/ 10840c7d97c5SJed Brown 10850c7d97c5SJed Brown if(pcbddc->n_constraints) { 10860c7d97c5SJed Brown /* some work vectors */ 10870c7d97c5SJed Brown ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->local_auxmat2);CHKERRQ(ierr); 10880c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->local_auxmat2,n_R,pcbddc->n_constraints,n_R,pcbddc->n_constraints);CHKERRQ(ierr); 10890c7d97c5SJed Brown ierr = MatSetType(pcbddc->local_auxmat2,impMatType);CHKERRQ(ierr); 10900c7d97c5SJed Brown 10910c7d97c5SJed Brown /* Assemble local_auxmat2 = - A_{RR}^{-1} C^T_{CR} needed by BDDC application */ 10920c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++) { 1093d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 10940c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 10950c7d97c5SJed Brown for(j=0;j<pcbddc->sizes_of_constraint[i];j++) { array[ pcbddc->indices_to_constraint[i][j] ] = - pcbddc->quadrature_constraint[i][j]; } 10960c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 10970c7d97c5SJed Brown for(j=0;j<n_R;j++) { array2[j] = array[ idx_R_local[j] ]; } 10980c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 10990c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 110053cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 11010c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 110253cdbc3dSStefano Zampini index=i; 110353cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->local_auxmat2,n_R,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 11040c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 11050c7d97c5SJed Brown } 11060c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11070c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11080c7d97c5SJed Brown 11090c7d97c5SJed Brown /* Create Constraint matrix on R nodes: C_{CR} */ 11100c7d97c5SJed Brown ierr = MatGetSubMatrix(CMAT,is_C_local,is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 11110c7d97c5SJed Brown ierr = ISDestroy(&is_C_local);CHKERRQ(ierr); 11120c7d97c5SJed Brown 11130c7d97c5SJed Brown /* Assemble AUXMAT = ( LUFactor )( -C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 11140c7d97c5SJed Brown ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AUXMAT);CHKERRQ(ierr); 1115d49ef151SStefano Zampini ierr = MatFactorInfoInitialize(&matinfo);CHKERRQ(ierr); 11160c7d97c5SJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->n_constraints,0,1,&is_aux1);CHKERRQ(ierr); 11170c7d97c5SJed Brown ierr = MatLUFactor(AUXMAT,is_aux1,is_aux1,&matinfo);CHKERRQ(ierr); 11180c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 11190c7d97c5SJed Brown 11200c7d97c5SJed Brown /* Assemble explicitly M1 = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} needed in preproc (should be dense) */ 1121d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M1);CHKERRQ(ierr); 11220c7d97c5SJed Brown ierr = MatSetSizes(M1,pcbddc->n_constraints,pcbddc->n_constraints,pcbddc->n_constraints,pcbddc->n_constraints);CHKERRQ(ierr); 11230c7d97c5SJed Brown ierr = MatSetType(M1,impMatType);CHKERRQ(ierr); 11240c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++) { 11250c7d97c5SJed Brown ierr = VecSet(vec1_C,zero);CHKERRQ(ierr); 11260c7d97c5SJed Brown ierr = VecSetValue(vec1_C,i,one,INSERT_VALUES);CHKERRQ(ierr); 11270c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_C);CHKERRQ(ierr); 11280c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_C);CHKERRQ(ierr); 11290c7d97c5SJed Brown ierr = MatSolve(AUXMAT,vec1_C,vec2_C);CHKERRQ(ierr); 11300c7d97c5SJed Brown ierr = VecScale(vec2_C,m_one);CHKERRQ(ierr); 11310c7d97c5SJed Brown ierr = VecGetArray(vec2_C,&array);CHKERRQ(ierr); 113253cdbc3dSStefano Zampini index=i; 113353cdbc3dSStefano Zampini ierr = MatSetValues(M1,pcbddc->n_constraints,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 11340c7d97c5SJed Brown ierr = VecRestoreArray(vec2_C,&array);CHKERRQ(ierr); 11350c7d97c5SJed Brown } 11360c7d97c5SJed Brown ierr = MatAssemblyBegin(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11370c7d97c5SJed Brown ierr = MatAssemblyEnd (M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11380c7d97c5SJed Brown ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 11390c7d97c5SJed Brown /* Assemble local_auxmat1 = M1*C_{CR} needed by BDDC application in KSP and in preproc */ 11400c7d97c5SJed Brown ierr = MatMatMult(M1,C_CR,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 11410c7d97c5SJed Brown 11420c7d97c5SJed Brown } 11430c7d97c5SJed Brown 11440c7d97c5SJed Brown /* Get submatrices from subdomain matrix */ 11450c7d97c5SJed Brown if(pcbddc->n_vertices){ 11460c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_R_local,is_V_local,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 11470c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_V_local,is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 11480c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_V_local,is_V_local,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 11490c7d97c5SJed Brown /* Assemble M2 = A_RR^{-1}A_RV */ 1150d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M2);CHKERRQ(ierr); 11510c7d97c5SJed Brown ierr = MatSetSizes(M2,n_R,pcbddc->n_vertices,n_R,pcbddc->n_vertices);CHKERRQ(ierr); 11520c7d97c5SJed Brown ierr = MatSetType(M2,impMatType);CHKERRQ(ierr); 11530c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++) { 11540c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 11550c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 11560c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 11570c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 11580c7d97c5SJed Brown ierr = MatMult(A_RV,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 115953cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 116053cdbc3dSStefano Zampini index=i; 11610c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 116253cdbc3dSStefano Zampini ierr = MatSetValues(M2,n_R,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 11630c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 11640c7d97c5SJed Brown } 11650c7d97c5SJed Brown ierr = MatAssemblyBegin(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11660c7d97c5SJed Brown ierr = MatAssemblyEnd (M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11670c7d97c5SJed Brown } 11680c7d97c5SJed Brown 11690c7d97c5SJed Brown /* Matrix of coarse basis functions (local) */ 1170d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 11710c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 11720c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_B,impMatType);CHKERRQ(ierr); 1173e269702eSStefano Zampini if(pcbddc->prec_type || dbg_flag ) { 1174d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 11750c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 11760c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_D,impMatType);CHKERRQ(ierr); 11770c7d97c5SJed Brown } 11780c7d97c5SJed Brown 11790c7d97c5SJed Brown /* Subdomain contribution (Non-overlapping) to coarse matrix */ 1180e269702eSStefano Zampini if(dbg_flag) { 11810c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&coarsefunctions_errors);CHKERRQ(ierr); 11820c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&constraints_errors);CHKERRQ(ierr); 11830c7d97c5SJed Brown } 11840c7d97c5SJed Brown ierr = PetscMalloc ((pcbddc->local_primal_size)*(pcbddc->local_primal_size)*sizeof(PetscScalar),&coarse_submat_vals);CHKERRQ(ierr); 11850c7d97c5SJed Brown 11860c7d97c5SJed Brown /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 11870c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++){ 11880c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 11890c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 11900c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 11910c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 11920c7d97c5SJed Brown /* solution of saddle point problem */ 11930c7d97c5SJed Brown ierr = MatMult(M2,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 11940c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_R,m_one);CHKERRQ(ierr); 11950c7d97c5SJed Brown if(pcbddc->n_constraints) { 11960c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec1_R,vec1_C);CHKERRQ(ierr); 11970c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 11980c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 11990c7d97c5SJed Brown } 12000c7d97c5SJed Brown ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); 12010c7d97c5SJed Brown ierr = MatMultAdd(A_VV,vec1_V,vec2_V,vec2_V);CHKERRQ(ierr); 12020c7d97c5SJed Brown 12030c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 12040c7d97c5SJed Brown /* coarse basis functions */ 120553cdbc3dSStefano Zampini index=i; 12060c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 12070c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12080c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12090c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 121053cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 12110c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 12120c7d97c5SJed Brown ierr = MatSetValue(pcbddc->coarse_phi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 1213e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 12140c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12150c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12160c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 121753cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 12180c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 12190c7d97c5SJed Brown } 12200c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 12210c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 12220c7d97c5SJed Brown for(j=0;j<pcbddc->n_vertices;j++) {coarse_submat_vals[i*pcbddc->local_primal_size+j]=array[j];} //WARNING -> column major ordering 12230c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 12240c7d97c5SJed Brown if( pcbddc->n_constraints) { 12250c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 12260c7d97c5SJed Brown for(j=0;j<pcbddc->n_constraints;j++) {coarse_submat_vals[i*pcbddc->local_primal_size+j+pcbddc->n_vertices]=array[j];} //WARNING -> column major ordering 12270c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 12280c7d97c5SJed Brown } 12290c7d97c5SJed Brown 1230e269702eSStefano Zampini if( dbg_flag ) { 12310c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 1232d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 12330c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 12340c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 12350c7d97c5SJed Brown for(j=0;j<n_R;j++) { array[idx_R_local[j]] = array2[j]; } 12360c7d97c5SJed Brown array[ pcbddc->vertices[i] ] = one; 12370c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 12380c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 12390c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers (i.e. primal nodes) */ 1240d49ef151SStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 12410c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 12420c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 12430c7d97c5SJed Brown for(j=0;j<pcbddc->n_vertices;j++) { array2[j]=array[j]; } 12440c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 12450c7d97c5SJed Brown if(pcbddc->n_constraints) { 12460c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 12470c7d97c5SJed Brown for(j=0;j<pcbddc->n_constraints;j++) { array2[j+pcbddc->n_vertices]=array[j]; } 12480c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 12490c7d97c5SJed Brown } 12500c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 12510c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_P,m_one);CHKERRQ(ierr); 12520c7d97c5SJed Brown /* check saddle point solution */ 12530c7d97c5SJed Brown ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 125453cdbc3dSStefano Zampini ierr = MatMultTransposeAdd(CMAT,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 125553cdbc3dSStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[index]);CHKERRQ(ierr); 12560c7d97c5SJed Brown ierr = MatMult(CMAT,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 12570c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 125853cdbc3dSStefano Zampini array[index]=array[index]+m_one; /* shift by the identity matrix */ 12590c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 126053cdbc3dSStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[index]);CHKERRQ(ierr); 12610c7d97c5SJed Brown } 12620c7d97c5SJed Brown } 12630c7d97c5SJed Brown 12640c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++){ 1265d49ef151SStefano Zampini ierr = VecSet(vec2_C,zero);CHKERRQ(ierr); 12660c7d97c5SJed Brown ierr = VecSetValue(vec2_C,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 12670c7d97c5SJed Brown ierr = VecAssemblyBegin(vec2_C);CHKERRQ(ierr); 12680c7d97c5SJed Brown ierr = VecAssemblyEnd(vec2_C);CHKERRQ(ierr); 12690c7d97c5SJed Brown /* solution of saddle point problem */ 12700c7d97c5SJed Brown ierr = MatMult(M1,vec2_C,vec1_C);CHKERRQ(ierr); 12710c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 12720c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 12730c7d97c5SJed Brown if(pcbddc->n_vertices) { ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); } 12740c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 12750c7d97c5SJed Brown /* coarse basis functions */ 127653cdbc3dSStefano Zampini index=i+pcbddc->n_vertices; 12770c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 12780c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12790c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12800c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 128153cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 12820c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1283e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 12840c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12850c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12860c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 128753cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 12880c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 12890c7d97c5SJed Brown } 12900c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 12910c7d97c5SJed Brown if(pcbddc->n_vertices) { 12920c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 129353cdbc3dSStefano Zampini for(j=0;j<pcbddc->n_vertices;j++) {coarse_submat_vals[index*pcbddc->local_primal_size+j]=array[j];} //WARNING -> column major ordering 12940c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 12950c7d97c5SJed Brown } 12960c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 129753cdbc3dSStefano Zampini for(j=0;j<pcbddc->n_constraints;j++) {coarse_submat_vals[index*pcbddc->local_primal_size+j+pcbddc->n_vertices]=array[j];} //WARNING -> column major ordering 12980c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 12990c7d97c5SJed Brown 1300e269702eSStefano Zampini if( dbg_flag ) { 13010c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 130253cdbc3dSStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 13030c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 13040c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 13050c7d97c5SJed Brown for(j=0;j<n_R;j++){ array[ idx_R_local[j] ] = array2[j]; } 13060c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 13070c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 13080c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers */ 130953cdbc3dSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 13100c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 13110c7d97c5SJed Brown if( pcbddc->n_vertices) { 13120c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 13130c7d97c5SJed Brown for(j=0;j<pcbddc->n_vertices;j++) {array2[j]=-array[j];} 13140c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 13150c7d97c5SJed Brown } 13160c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 13170c7d97c5SJed Brown for(j=0;j<pcbddc->n_constraints;j++) {array2[j+pcbddc->n_vertices]=-array[j];} 13180c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 13190c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 13200c7d97c5SJed Brown /* check saddle point solution */ 13210c7d97c5SJed Brown ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 1322d49ef151SStefano Zampini ierr = MatMultTransposeAdd(CMAT,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 132353cdbc3dSStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[index]);CHKERRQ(ierr); 13240c7d97c5SJed Brown ierr = MatMult(CMAT,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 13250c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 132653cdbc3dSStefano Zampini array[index]=array[index]+m_one; /* shift by the identity matrix */ 13270c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 132853cdbc3dSStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[index]);CHKERRQ(ierr); 13290c7d97c5SJed Brown } 13300c7d97c5SJed Brown } 13310c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13320c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1333e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 13340c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13350c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13360c7d97c5SJed Brown } 13370c7d97c5SJed Brown /* Checking coarse_sub_mat and coarse basis functios */ 13380c7d97c5SJed Brown /* It shuld be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 13399d2fce94SStefano Zampini if(dbg_flag) { 13400c7d97c5SJed Brown 13410c7d97c5SJed Brown Mat coarse_sub_mat; 13420c7d97c5SJed Brown Mat TM1,TM2,TM3,TM4; 13430c7d97c5SJed Brown Mat coarse_phi_D,coarse_phi_B,A_II,A_BB,A_IB,A_BI; 1344a0ba757dSStefano Zampini const MatType checkmattype=MATSEQAIJ; 13450c7d97c5SJed Brown PetscScalar value; 13460c7d97c5SJed Brown 1347c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 1348c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 1349c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 1350c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 1351c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 1352c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 1353c042a7c3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 1354c042a7c3SStefano Zampini ierr = MatConvert(coarse_sub_mat,checkmattype,MAT_REUSE_MATRIX,&coarse_sub_mat);CHKERRQ(ierr); 13550c7d97c5SJed Brown 13560c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 13570c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Check coarse sub mat and local basis functions\n");CHKERRQ(ierr); 13580c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 135953cdbc3dSStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 136053cdbc3dSStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 136153cdbc3dSStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1362c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 136353cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 136453cdbc3dSStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1365c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 136653cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 136753cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 136853cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 136953cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 137053cdbc3dSStefano Zampini ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 137153cdbc3dSStefano Zampini ierr = MatNorm(TM1,NORM_INFINITY,&value);CHKERRQ(ierr); 13720c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"----------------------------------\n");CHKERRQ(ierr); 13730c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d \n",PetscGlobalRank);CHKERRQ(ierr); 13740c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"matrix error = % 1.14e\n",value);CHKERRQ(ierr); 13750c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"coarse functions errors\n");CHKERRQ(ierr); 137653cdbc3dSStefano 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); } 13770c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"constraints errors\n");CHKERRQ(ierr); 137853cdbc3dSStefano 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); } 13790c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 138053cdbc3dSStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 138153cdbc3dSStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 138253cdbc3dSStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 138353cdbc3dSStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 138453cdbc3dSStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 138553cdbc3dSStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 138653cdbc3dSStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 138753cdbc3dSStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 138853cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 138953cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 139053cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 13910c7d97c5SJed Brown ierr = PetscFree(coarsefunctions_errors);CHKERRQ(ierr); 13920c7d97c5SJed Brown ierr = PetscFree(constraints_errors);CHKERRQ(ierr); 13930c7d97c5SJed Brown } 13940c7d97c5SJed Brown 13950c7d97c5SJed Brown /* create coarse matrix and data structures for message passing associated actual choice of coarse problem type */ 13960c7d97c5SJed Brown ierr = PCBDDCSetupCoarseEnvironment(pc,coarse_submat_vals);CHKERRQ(ierr); 13970c7d97c5SJed Brown /* free memory */ 13980c7d97c5SJed Brown ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 13990c7d97c5SJed Brown ierr = PetscFree(auxindices);CHKERRQ(ierr); 14000c7d97c5SJed Brown ierr = PetscFree(nnz);CHKERRQ(ierr); 14010c7d97c5SJed Brown if(pcbddc->n_vertices) { 14020c7d97c5SJed Brown ierr = VecDestroy(&vec1_V);CHKERRQ(ierr); 14030c7d97c5SJed Brown ierr = VecDestroy(&vec2_V);CHKERRQ(ierr); 14040c7d97c5SJed Brown ierr = MatDestroy(&M2);CHKERRQ(ierr); 14050c7d97c5SJed Brown ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 14060c7d97c5SJed Brown ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 14070c7d97c5SJed Brown ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 14080c7d97c5SJed Brown } 14090c7d97c5SJed Brown if(pcbddc->n_constraints) { 14100c7d97c5SJed Brown ierr = VecDestroy(&vec1_C);CHKERRQ(ierr); 14110c7d97c5SJed Brown ierr = VecDestroy(&vec2_C);CHKERRQ(ierr); 14120c7d97c5SJed Brown ierr = MatDestroy(&M1);CHKERRQ(ierr); 14130c7d97c5SJed Brown ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 14140c7d97c5SJed Brown } 14150c7d97c5SJed Brown ierr = MatDestroy(&CMAT);CHKERRQ(ierr); 14160c7d97c5SJed Brown } 14170c7d97c5SJed Brown /* free memory */ 14180c7d97c5SJed Brown if(pcbddc->n_vertices) { 14190c7d97c5SJed Brown ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 14200c7d97c5SJed Brown ierr = ISDestroy(&is_V_local);CHKERRQ(ierr); 14210c7d97c5SJed Brown } 14220c7d97c5SJed Brown ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 14230c7d97c5SJed Brown ierr = ISDestroy(&is_R_local);CHKERRQ(ierr); 14240c7d97c5SJed Brown 14250c7d97c5SJed Brown PetscFunctionReturn(0); 14260c7d97c5SJed Brown } 14270c7d97c5SJed Brown 14280c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 14290c7d97c5SJed Brown 14300c7d97c5SJed Brown #undef __FUNCT__ 14310c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetupCoarseEnvironment" 143253cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetupCoarseEnvironment(PC pc,PetscScalar* coarse_submat_vals) 14330c7d97c5SJed Brown { 14340c7d97c5SJed Brown 14350c7d97c5SJed Brown 14360c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 14370c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 14380c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 14390c7d97c5SJed Brown MPI_Comm prec_comm = ((PetscObject)pc)->comm; 14400c7d97c5SJed Brown MPI_Comm coarse_comm; 14410c7d97c5SJed Brown 14420c7d97c5SJed Brown /* common to all choiches */ 14430c7d97c5SJed Brown PetscScalar *temp_coarse_mat_vals; 14440c7d97c5SJed Brown PetscScalar *ins_coarse_mat_vals; 14450c7d97c5SJed Brown PetscInt *ins_local_primal_indices; 14460c7d97c5SJed Brown PetscMPIInt *localsizes2,*localdispl2; 14470c7d97c5SJed Brown PetscMPIInt size_prec_comm; 14480c7d97c5SJed Brown PetscMPIInt rank_prec_comm; 14490c7d97c5SJed Brown PetscMPIInt active_rank=MPI_PROC_NULL; 14500c7d97c5SJed Brown PetscMPIInt master_proc=0; 14510c7d97c5SJed Brown PetscInt ins_local_primal_size; 14520c7d97c5SJed Brown /* specific to MULTILEVEL_BDDC */ 14530c7d97c5SJed Brown PetscMPIInt *ranks_recv; 14540c7d97c5SJed Brown PetscMPIInt count_recv=0; 14550c7d97c5SJed Brown PetscMPIInt rank_coarse_proc_send_to; 14560c7d97c5SJed Brown PetscMPIInt coarse_color = MPI_UNDEFINED; 14570c7d97c5SJed Brown ISLocalToGlobalMapping coarse_ISLG; 14580c7d97c5SJed Brown /* some other variables */ 14590c7d97c5SJed Brown PetscErrorCode ierr; 14600c7d97c5SJed Brown const MatType coarse_mat_type; 14610c7d97c5SJed Brown const PCType coarse_pc_type; 146253cdbc3dSStefano Zampini const KSPType coarse_ksp_type; 146353cdbc3dSStefano Zampini PC pc_temp; 14640c7d97c5SJed Brown PetscInt i,j,k,bs; 1465e269702eSStefano Zampini /* verbose output viewer */ 1466e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 1467e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 14680c7d97c5SJed Brown 14690c7d97c5SJed Brown PetscFunctionBegin; 14700c7d97c5SJed Brown 14710c7d97c5SJed Brown ins_local_primal_indices = 0; 14720c7d97c5SJed Brown ins_coarse_mat_vals = 0; 14730c7d97c5SJed Brown localsizes2 = 0; 14740c7d97c5SJed Brown localdispl2 = 0; 14750c7d97c5SJed Brown temp_coarse_mat_vals = 0; 14760c7d97c5SJed Brown coarse_ISLG = 0; 14770c7d97c5SJed Brown 147853cdbc3dSStefano Zampini ierr = MPI_Comm_size(prec_comm,&size_prec_comm);CHKERRQ(ierr); 147953cdbc3dSStefano Zampini ierr = MPI_Comm_rank(prec_comm,&rank_prec_comm);CHKERRQ(ierr); 14800c7d97c5SJed Brown ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 14810c7d97c5SJed Brown 1482beed3852SStefano Zampini /* Assign global numbering to coarse dofs */ 1483beed3852SStefano Zampini { 1484a0ba757dSStefano Zampini PetscScalar one=1.,zero=0.; 1485beed3852SStefano Zampini PetscScalar *array; 1486beed3852SStefano Zampini PetscMPIInt *auxlocal_primal; 1487beed3852SStefano Zampini PetscMPIInt *auxglobal_primal; 1488beed3852SStefano Zampini PetscMPIInt *all_auxglobal_primal; 1489beed3852SStefano Zampini PetscMPIInt *all_auxglobal_primal_dummy; 1490beed3852SStefano Zampini PetscMPIInt mpi_local_primal_size = (PetscMPIInt)pcbddc->local_primal_size; 1491beed3852SStefano Zampini 1492beed3852SStefano Zampini /* Construct needed data structures for message passing */ 1493beed3852SStefano Zampini ierr = PetscMalloc(mpi_local_primal_size*sizeof(PetscMPIInt),&pcbddc->local_primal_indices);CHKERRQ(ierr); 1494beed3852SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&pcbddc->local_primal_sizes);CHKERRQ(ierr); 1495beed3852SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 1496beed3852SStefano Zampini /* Gather local_primal_size information for all processes */ 14975619798eSStefano Zampini ierr = MPI_Allgather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,prec_comm);CHKERRQ(ierr); 1498beed3852SStefano Zampini pcbddc->replicated_primal_size = 0; 1499beed3852SStefano Zampini for (i=0; i<size_prec_comm; i++) { 1500beed3852SStefano Zampini pcbddc->local_primal_displacements[i] = pcbddc->replicated_primal_size ; 1501beed3852SStefano Zampini pcbddc->replicated_primal_size += pcbddc->local_primal_sizes[i]; 1502beed3852SStefano Zampini } 15035619798eSStefano Zampini if(rank_prec_comm == 0) { 1504beed3852SStefano Zampini /* allocate some auxiliary space */ 1505beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->replicated_primal_size*sizeof(*all_auxglobal_primal),&all_auxglobal_primal);CHKERRQ(ierr); 1506beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->replicated_primal_size*sizeof(*all_auxglobal_primal_dummy),&all_auxglobal_primal_dummy);CHKERRQ(ierr); 1507beed3852SStefano Zampini } 1508beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscMPIInt),&auxlocal_primal);CHKERRQ(ierr); 1509beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscMPIInt),&auxglobal_primal);CHKERRQ(ierr); 1510beed3852SStefano Zampini 1511beed3852SStefano 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) 1512beed3852SStefano Zampini This code fragment assumes that the number of local constraints per connected component 1513beed3852SStefano Zampini is not greater than the number of nodes defined for the connected component 1514beed3852SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 1515beed3852SStefano Zampini /* auxlocal_primal : primal indices in local nodes numbering (internal and interface) */ 1516beed3852SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 1517beed3852SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1518beed3852SStefano Zampini for(i=0;i<pcbddc->n_vertices;i++) { 1519beed3852SStefano Zampini array[ pcbddc->vertices[i] ] = one; 1520beed3852SStefano Zampini auxlocal_primal[i] = pcbddc->vertices[i]; 1521beed3852SStefano Zampini } 1522beed3852SStefano Zampini for(i=0;i<pcbddc->n_constraints;i++) { 1523beed3852SStefano Zampini for (j=0; j<pcbddc->sizes_of_constraint[i]; j++) { 1524beed3852SStefano Zampini k = pcbddc->indices_to_constraint[i][j]; 1525beed3852SStefano Zampini if( array[k] == zero ) { 1526beed3852SStefano Zampini array[k] = one; 1527beed3852SStefano Zampini auxlocal_primal[i+pcbddc->n_vertices] = k; 1528beed3852SStefano Zampini break; 1529beed3852SStefano Zampini } 1530beed3852SStefano Zampini } 1531beed3852SStefano Zampini } 1532beed3852SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1533a0ba757dSStefano Zampini 1534a0ba757dSStefano Zampini /*ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 1535beed3852SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1536beed3852SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1537beed3852SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1538beed3852SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1539beed3852SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1540d49ef151SStefano Zampini for(i=0;i<pcis->n;i++) { if(array[i] > 0.0) array[i] = one/array[i]; } 1541beed3852SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1542beed3852SStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 1543beed3852SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1544beed3852SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1545beed3852SStefano Zampini 1546beed3852SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 1547beed3852SStefano Zampini pcbddc->coarse_size = (PetscInt) coarsesum; 1548e269702eSStefano Zampini if(dbg_flag) { 1549e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 15503828260eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem = %d (%f)\n",pcbddc->coarse_size,coarsesum);CHKERRQ(ierr); 1551e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1552a0ba757dSStefano Zampini }*/ 1553a0ba757dSStefano Zampini 1554beed3852SStefano Zampini /* Now assign them a global numbering */ 1555beed3852SStefano Zampini /* auxglobal_primal contains indices in global nodes numbering (internal and interface) */ 1556beed3852SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,pcbddc->local_primal_size,auxlocal_primal,auxglobal_primal);CHKERRQ(ierr); 1557beed3852SStefano Zampini /* all_auxglobal_primal contains all primal nodes indices in global nodes numbering (internal and interface) */ 1558beed3852SStefano 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); 1559beed3852SStefano Zampini 1560beed3852SStefano Zampini /* After this block all_auxglobal_primal should contains one copy of each primal node's indices in global nodes numbering */ 1561beed3852SStefano Zampini /* It implements a function similar to PetscSortRemoveDupsInt */ 1562beed3852SStefano Zampini if(rank_prec_comm==0) { 1563beed3852SStefano Zampini /* dummy argument since PetscSortMPIInt doesn't exist! */ 1564beed3852SStefano Zampini ierr = PetscSortMPIIntWithArray(pcbddc->replicated_primal_size,all_auxglobal_primal,all_auxglobal_primal_dummy);CHKERRQ(ierr); 1565beed3852SStefano Zampini k=1; 1566beed3852SStefano Zampini j=all_auxglobal_primal[0]; /* first dof in global numbering */ 1567beed3852SStefano Zampini for(i=1;i< pcbddc->replicated_primal_size ;i++) { 1568beed3852SStefano Zampini if(j != all_auxglobal_primal[i] ) { 1569beed3852SStefano Zampini all_auxglobal_primal[k]=all_auxglobal_primal[i]; 1570beed3852SStefano Zampini k++; 1571beed3852SStefano Zampini j=all_auxglobal_primal[i]; 1572beed3852SStefano Zampini } 1573beed3852SStefano Zampini } 1574beed3852SStefano Zampini } else { 1575beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscMPIInt),&all_auxglobal_primal);CHKERRQ(ierr); 1576beed3852SStefano Zampini } 15775619798eSStefano Zampini /* We only need to broadcast the indices from 0 to pcbddc->coarse_size. Remaning elements of array all_aux_global_primal are garbage. */ 1578beed3852SStefano Zampini ierr = MPI_Bcast(all_auxglobal_primal,pcbddc->coarse_size,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 1579beed3852SStefano Zampini 1580beed3852SStefano Zampini /* Now get global coarse numbering of local primal nodes */ 1581beed3852SStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) { 1582beed3852SStefano Zampini k=0; 1583beed3852SStefano Zampini while( all_auxglobal_primal[k] != auxglobal_primal[i] ) { k++;} 1584beed3852SStefano Zampini pcbddc->local_primal_indices[i]=k; 1585beed3852SStefano Zampini } 1586e269702eSStefano Zampini if(dbg_flag) { 1587e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1588e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 1589e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1590e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 1591e269702eSStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) { 1592e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_primal_indices[%d]=%d \n",i,pcbddc->local_primal_indices[i]); 1593e269702eSStefano Zampini } 1594e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1595e269702eSStefano Zampini } 1596beed3852SStefano Zampini /* free allocated memory */ 1597beed3852SStefano Zampini ierr = PetscFree(auxlocal_primal);CHKERRQ(ierr); 1598beed3852SStefano Zampini ierr = PetscFree(auxglobal_primal);CHKERRQ(ierr); 1599beed3852SStefano Zampini ierr = PetscFree(all_auxglobal_primal);CHKERRQ(ierr); 1600e269702eSStefano Zampini if(rank_prec_comm == 0) { 1601beed3852SStefano Zampini ierr = PetscFree(all_auxglobal_primal_dummy);CHKERRQ(ierr); 1602beed3852SStefano Zampini } 1603e269702eSStefano Zampini } 1604beed3852SStefano Zampini 16050c7d97c5SJed Brown /* adapt coarse problem type */ 16060c7d97c5SJed Brown if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC && pcbddc->active_procs < MIN_PROCS_FOR_BDDC ) 16070c7d97c5SJed Brown pcbddc->coarse_problem_type = PARALLEL_BDDC; 16080c7d97c5SJed Brown 16090c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 16100c7d97c5SJed Brown 16110c7d97c5SJed Brown case(MULTILEVEL_BDDC): //we define a coarse mesh where subdomains are elements 16120c7d97c5SJed Brown { 16130c7d97c5SJed Brown /* we need additional variables */ 16140c7d97c5SJed Brown MetisInt n_subdomains,n_parts,objval,ncon,faces_nvtxs; 16150c7d97c5SJed Brown MetisInt *metis_coarse_subdivision; 16160c7d97c5SJed Brown MetisInt options[METIS_NOPTIONS]; 16170c7d97c5SJed Brown PetscMPIInt size_coarse_comm,rank_coarse_comm; 16180c7d97c5SJed Brown PetscMPIInt procs_jumps_coarse_comm; 16190c7d97c5SJed Brown PetscMPIInt *coarse_subdivision; 16200c7d97c5SJed Brown PetscMPIInt *total_count_recv; 16210c7d97c5SJed Brown PetscMPIInt *total_ranks_recv; 16220c7d97c5SJed Brown PetscMPIInt *displacements_recv; 16230c7d97c5SJed Brown PetscMPIInt *my_faces_connectivity; 16240c7d97c5SJed Brown PetscMPIInt *petsc_faces_adjncy; 16250c7d97c5SJed Brown MetisInt *faces_adjncy; 16260c7d97c5SJed Brown MetisInt *faces_xadj; 16270c7d97c5SJed Brown PetscMPIInt *number_of_faces; 16280c7d97c5SJed Brown PetscMPIInt *faces_displacements; 16290c7d97c5SJed Brown PetscInt *array_int; 16300c7d97c5SJed Brown PetscMPIInt my_faces=0; 16310c7d97c5SJed Brown PetscMPIInt total_faces=0; 16323828260eSStefano Zampini PetscInt ranks_stretching_ratio; 16330c7d97c5SJed Brown 16340c7d97c5SJed Brown /* define some quantities */ 16350c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 16360c7d97c5SJed Brown coarse_mat_type = MATIS; 16370c7d97c5SJed Brown coarse_pc_type = PCBDDC; 163853cdbc3dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 16390c7d97c5SJed Brown 16400c7d97c5SJed Brown /* details of coarse decomposition */ 16410c7d97c5SJed Brown n_subdomains = pcbddc->active_procs; 16420c7d97c5SJed Brown n_parts = n_subdomains/pcbddc->coarsening_ratio; 16433828260eSStefano Zampini ranks_stretching_ratio = size_prec_comm/pcbddc->active_procs; 16443828260eSStefano Zampini procs_jumps_coarse_comm = pcbddc->coarsening_ratio*ranks_stretching_ratio; 16453828260eSStefano Zampini 16463828260eSStefano Zampini printf("Coarse algorithm details: \n"); 1647a0ba757dSStefano 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)); 16480c7d97c5SJed Brown 16490c7d97c5SJed Brown /* build CSR graph of subdomains' connectivity through faces */ 16500c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&array_int);CHKERRQ(ierr); 16513828260eSStefano Zampini ierr = PetscMemzero(array_int,pcis->n*sizeof(PetscInt));CHKERRQ(ierr); 16520c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){/* i=1 so I don't count myself -> faces nodes counts to 1 */ 16530c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 16540c7d97c5SJed Brown array_int[ pcis->shared[i][j] ]+=1; 16550c7d97c5SJed Brown } 16560c7d97c5SJed Brown } 16570c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){ 16580c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 16590c7d97c5SJed Brown if(array_int[ pcis->shared[i][j] ] == 1 ){ 16600c7d97c5SJed Brown my_faces++; 16610c7d97c5SJed Brown break; 16620c7d97c5SJed Brown } 16630c7d97c5SJed Brown } 16640c7d97c5SJed Brown } 16650c7d97c5SJed Brown //printf("I found %d faces.\n",my_faces); 16660c7d97c5SJed Brown 166753cdbc3dSStefano Zampini ierr = MPI_Reduce(&my_faces,&total_faces,1,MPIU_INT,MPI_SUM,master_proc,prec_comm);CHKERRQ(ierr); 16680c7d97c5SJed Brown ierr = PetscMalloc (my_faces*sizeof(PetscInt),&my_faces_connectivity);CHKERRQ(ierr); 16690c7d97c5SJed Brown my_faces=0; 16700c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){ 16710c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 16720c7d97c5SJed Brown if(array_int[ pcis->shared[i][j] ] == 1 ){ 16730c7d97c5SJed Brown my_faces_connectivity[my_faces]=pcis->neigh[i]; 16740c7d97c5SJed Brown my_faces++; 16750c7d97c5SJed Brown break; 16760c7d97c5SJed Brown } 16770c7d97c5SJed Brown } 16780c7d97c5SJed Brown } 16790c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 16800c7d97c5SJed Brown //printf("I found %d total faces.\n",total_faces); 16810c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(PetscMPIInt),&petsc_faces_adjncy);CHKERRQ(ierr); 16820c7d97c5SJed Brown ierr = PetscMalloc (size_prec_comm*sizeof(PetscMPIInt),&number_of_faces);CHKERRQ(ierr); 16830c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(MetisInt),&faces_adjncy);CHKERRQ(ierr); 16840c7d97c5SJed Brown ierr = PetscMalloc ((n_subdomains+1)*sizeof(MetisInt),&faces_xadj);CHKERRQ(ierr); 16850c7d97c5SJed Brown ierr = PetscMalloc ((size_prec_comm+1)*sizeof(PetscMPIInt),&faces_displacements);CHKERRQ(ierr); 16860c7d97c5SJed Brown } 168753cdbc3dSStefano Zampini ierr = MPI_Gather(&my_faces,1,MPIU_INT,&number_of_faces[0],1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 16880c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 16890c7d97c5SJed Brown faces_xadj[0]=0; 16900c7d97c5SJed Brown faces_displacements[0]=0; 16910c7d97c5SJed Brown j=0; 16920c7d97c5SJed Brown for(i=1;i<size_prec_comm+1;i++) { 16930c7d97c5SJed Brown faces_displacements[i]=faces_displacements[i-1]+number_of_faces[i-1]; 16940c7d97c5SJed Brown if(number_of_faces[i-1]) { 16950c7d97c5SJed Brown j++; 16960c7d97c5SJed Brown faces_xadj[j]=faces_xadj[j-1]+number_of_faces[i-1]; 16970c7d97c5SJed Brown } 16980c7d97c5SJed Brown } 16990c7d97c5SJed Brown printf("The J I count is %d and should be %d\n",j,n_subdomains); 17000c7d97c5SJed Brown printf("Total faces seem %d and should be %d\n",faces_xadj[j],total_faces); 17010c7d97c5SJed Brown } 170253cdbc3dSStefano 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); 17030c7d97c5SJed Brown ierr = PetscFree(my_faces_connectivity);CHKERRQ(ierr); 17040c7d97c5SJed Brown ierr = PetscFree(array_int);CHKERRQ(ierr); 17050c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 17063828260eSStefano Zampini for(i=0;i<total_faces;i++) faces_adjncy[i]=(MetisInt)(petsc_faces_adjncy[i]/ranks_stretching_ratio); /* cast to MetisInt */ 17073828260eSStefano Zampini printf("This is the face connectivity (actual ranks)\n"); 17080c7d97c5SJed Brown for(i=0;i<n_subdomains;i++){ 17090c7d97c5SJed Brown printf("proc %d is connected with \n",i); 17100c7d97c5SJed Brown for(j=faces_xadj[i];j<faces_xadj[i+1];j++) 17110c7d97c5SJed Brown printf("%d ",faces_adjncy[j]); 17120c7d97c5SJed Brown printf("\n"); 17130c7d97c5SJed Brown } 17140c7d97c5SJed Brown ierr = PetscFree(faces_displacements);CHKERRQ(ierr); 17150c7d97c5SJed Brown ierr = PetscFree(number_of_faces);CHKERRQ(ierr); 17160c7d97c5SJed Brown ierr = PetscFree(petsc_faces_adjncy);CHKERRQ(ierr); 17170c7d97c5SJed Brown } 17180c7d97c5SJed Brown 17190c7d97c5SJed Brown if( rank_prec_comm == master_proc ) { 17200c7d97c5SJed Brown 17213828260eSStefano Zampini PetscInt heuristic_for_metis=3; 17223828260eSStefano Zampini 17230c7d97c5SJed Brown ncon=1; 17240c7d97c5SJed Brown faces_nvtxs=n_subdomains; 17250c7d97c5SJed Brown /* partition graoh induced by face connectivity */ 17260c7d97c5SJed Brown ierr = PetscMalloc (n_subdomains*sizeof(MetisInt),&metis_coarse_subdivision);CHKERRQ(ierr); 17270c7d97c5SJed Brown ierr = METIS_SetDefaultOptions(options); 17280c7d97c5SJed Brown /* we need a contiguous partition of the coarse mesh */ 17290c7d97c5SJed Brown options[METIS_OPTION_CONTIG]=1; 17300c7d97c5SJed Brown options[METIS_OPTION_DBGLVL]=1; 17310c7d97c5SJed Brown options[METIS_OPTION_NITER]=30; 17320c7d97c5SJed Brown //options[METIS_OPTION_NCUTS]=1; 17333828260eSStefano Zampini printf("METIS PART GRAPH\n"); 17343828260eSStefano Zampini if(n_subdomains>n_parts*heuristic_for_metis) { 17353828260eSStefano Zampini printf("Using Kway\n"); 17363828260eSStefano Zampini options[METIS_OPTION_IPTYPE]=METIS_IPTYPE_EDGE; 17373828260eSStefano Zampini options[METIS_OPTION_OBJTYPE]=METIS_OBJTYPE_CUT; 17380c7d97c5SJed Brown ierr = METIS_PartGraphKway(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 17393828260eSStefano Zampini } else { 17403828260eSStefano Zampini printf("Using Recursive\n"); 17413828260eSStefano Zampini ierr = METIS_PartGraphRecursive(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 17423828260eSStefano Zampini } 17430c7d97c5SJed 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); 17443828260eSStefano Zampini printf("Partition done!\n"); 17450c7d97c5SJed Brown ierr = PetscFree(faces_xadj);CHKERRQ(ierr); 17460c7d97c5SJed Brown ierr = PetscFree(faces_adjncy);CHKERRQ(ierr); 17470c7d97c5SJed Brown coarse_subdivision = (PetscMPIInt*)calloc(size_prec_comm,sizeof(PetscMPIInt)); /* calloc for contiguous memory since we need to scatter these values later */ 17480c7d97c5SJed Brown /* copy/cast values avoiding possible type conflicts between PETSc, MPI and METIS */ 17493828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) coarse_subdivision[i]=MPI_PROC_NULL; 17503828260eSStefano Zampini for(i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=(PetscInt)(metis_coarse_subdivision[i]); 17510c7d97c5SJed Brown ierr = PetscFree(metis_coarse_subdivision);CHKERRQ(ierr); 17520c7d97c5SJed Brown } 17530c7d97c5SJed Brown 17540c7d97c5SJed Brown /* Create new communicator for coarse problem splitting the old one */ 17550c7d97c5SJed Brown if( !(rank_prec_comm%procs_jumps_coarse_comm) && rank_prec_comm < procs_jumps_coarse_comm*n_parts ){ 17560c7d97c5SJed Brown coarse_color=0; //for communicator splitting 17570c7d97c5SJed Brown active_rank=rank_prec_comm; //for insertion of matrix values 17580c7d97c5SJed Brown } 17590c7d97c5SJed Brown // procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 17600c7d97c5SJed Brown // key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator 176153cdbc3dSStefano Zampini ierr = MPI_Comm_split(prec_comm,coarse_color,rank_prec_comm,&coarse_comm);CHKERRQ(ierr); 17620c7d97c5SJed Brown 17630c7d97c5SJed Brown if( coarse_color == 0 ) { 176453cdbc3dSStefano Zampini ierr = MPI_Comm_size(coarse_comm,&size_coarse_comm);CHKERRQ(ierr); 176553cdbc3dSStefano Zampini ierr = MPI_Comm_rank(coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 17663828260eSStefano Zampini printf("Details of coarse comm\n"); 17673828260eSStefano Zampini printf("size = %d, myrank = %d\n",size_coarse_comm,rank_coarse_comm); 17683828260eSStefano Zampini printf("jumps = %d, coarse_color = %d, n_parts = %d\n",procs_jumps_coarse_comm,coarse_color,n_parts); 17690c7d97c5SJed Brown } else { 17700c7d97c5SJed Brown rank_coarse_comm = MPI_PROC_NULL; 17710c7d97c5SJed Brown } 17720c7d97c5SJed Brown 17730c7d97c5SJed Brown /* master proc take care of arranging and distributing coarse informations */ 17740c7d97c5SJed Brown if(rank_coarse_comm == master_proc) { 17750c7d97c5SJed Brown ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&displacements_recv);CHKERRQ(ierr); 17760c7d97c5SJed Brown //ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&total_count_recv);CHKERRQ(ierr); 17770c7d97c5SJed Brown //ierr = PetscMalloc (n_subdomains*sizeof(PetscMPIInt),&total_ranks_recv);CHKERRQ(ierr); 17780c7d97c5SJed Brown total_count_recv = (PetscMPIInt*)calloc(size_prec_comm,sizeof(PetscMPIInt)); 17790c7d97c5SJed Brown total_ranks_recv = (PetscMPIInt*)calloc(n_subdomains,sizeof(PetscMPIInt)); 17800c7d97c5SJed Brown /* some initializations */ 17810c7d97c5SJed Brown displacements_recv[0]=0; 17820c7d97c5SJed Brown //PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt)); not needed -> calloc initializes to zero 17830c7d97c5SJed Brown /* count from how many processes the j-th process of the coarse decomposition will receive data */ 17840c7d97c5SJed Brown for(j=0;j<size_coarse_comm;j++) 17853828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) 17860c7d97c5SJed Brown if(coarse_subdivision[i]==j) 17870c7d97c5SJed Brown total_count_recv[j]++; 17880c7d97c5SJed Brown /* displacements needed for scatterv of total_ranks_recv */ 17890c7d97c5SJed Brown for(i=1;i<size_coarse_comm;i++) displacements_recv[i]=displacements_recv[i-1]+total_count_recv[i-1]; 17900c7d97c5SJed Brown /* Now fill properly total_ranks_recv -> each coarse process will receive the ranks (in prec_comm communicator) of its friend (sending) processes */ 17910c7d97c5SJed Brown ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 17920c7d97c5SJed Brown for(j=0;j<size_coarse_comm;j++) { 17933828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) { 17940c7d97c5SJed Brown if(coarse_subdivision[i]==j) { 17950c7d97c5SJed Brown total_ranks_recv[displacements_recv[j]+total_count_recv[j]]=i; 17963828260eSStefano Zampini total_count_recv[j]+=1; 17970c7d97c5SJed Brown } 17980c7d97c5SJed Brown } 17990c7d97c5SJed Brown } 18003828260eSStefano Zampini for(j=0;j<size_coarse_comm;j++) { 18013828260eSStefano Zampini printf("process %d in new rank will receive from %d processes (original ranks follows)\n",j,total_count_recv[j]); 18023828260eSStefano Zampini for(i=0;i<total_count_recv[j];i++) { 18033828260eSStefano Zampini printf("%d ",total_ranks_recv[displacements_recv[j]+i]); 18043828260eSStefano Zampini } 18053828260eSStefano Zampini printf("\n"); 18063828260eSStefano Zampini } 18070c7d97c5SJed Brown 18080c7d97c5SJed Brown /* identify new decomposition in terms of ranks in the old communicator */ 18093828260eSStefano Zampini for(i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=coarse_subdivision[ranks_stretching_ratio*i]*procs_jumps_coarse_comm; 18100c7d97c5SJed Brown printf("coarse_subdivision in old end new ranks\n"); 18110c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) 18123828260eSStefano Zampini if(coarse_subdivision[i]!=MPI_PROC_NULL) { 18133828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]/procs_jumps_coarse_comm); 18143828260eSStefano Zampini } else { 18153828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]); 18163828260eSStefano Zampini } 18170c7d97c5SJed Brown printf("\n"); 18180c7d97c5SJed Brown } 18190c7d97c5SJed Brown 18200c7d97c5SJed Brown /* Scatter new decomposition for send details */ 182153cdbc3dSStefano Zampini ierr = MPI_Scatter(&coarse_subdivision[0],1,MPIU_INT,&rank_coarse_proc_send_to,1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 18220c7d97c5SJed Brown /* Scatter receiving details to members of coarse decomposition */ 18230c7d97c5SJed Brown if( coarse_color == 0) { 182453cdbc3dSStefano Zampini ierr = MPI_Scatter(&total_count_recv[0],1,MPIU_INT,&count_recv,1,MPIU_INT,master_proc,coarse_comm);CHKERRQ(ierr); 18250c7d97c5SJed Brown ierr = PetscMalloc (count_recv*sizeof(PetscMPIInt),&ranks_recv);CHKERRQ(ierr); 182653cdbc3dSStefano 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); 18270c7d97c5SJed Brown } 18280c7d97c5SJed Brown 18290c7d97c5SJed Brown //printf("I will send my matrix data to proc %d\n",rank_coarse_proc_send_to); 18300c7d97c5SJed Brown //if(coarse_color == 0) { 18310c7d97c5SJed Brown // printf("I will receive some matrix data from %d processes (ranks follows)\n",count_recv); 18320c7d97c5SJed Brown // for(i=0;i<count_recv;i++) 18330c7d97c5SJed Brown // printf("%d ",ranks_recv[i]); 18340c7d97c5SJed Brown // printf("\n"); 18350c7d97c5SJed Brown //} 18360c7d97c5SJed Brown 18370c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 18380c7d97c5SJed Brown //ierr = PetscFree(coarse_subdivision);CHKERRQ(ierr); 18390c7d97c5SJed Brown //ierr = PetscFree(total_count_recv);CHKERRQ(ierr); 18400c7d97c5SJed Brown //ierr = PetscFree(total_ranks_recv);CHKERRQ(ierr); 18410c7d97c5SJed Brown free(coarse_subdivision); 18420c7d97c5SJed Brown free(total_count_recv); 18430c7d97c5SJed Brown free(total_ranks_recv); 18440c7d97c5SJed Brown ierr = PetscFree(displacements_recv);CHKERRQ(ierr); 18450c7d97c5SJed Brown } 18460c7d97c5SJed Brown break; 18470c7d97c5SJed Brown } 18480c7d97c5SJed Brown 18490c7d97c5SJed Brown case(REPLICATED_BDDC): 18500c7d97c5SJed Brown 18510c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 18520c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 18530c7d97c5SJed Brown coarse_pc_type = PCLU; 185453cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 18550c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 18560c7d97c5SJed Brown active_rank = rank_prec_comm; 18570c7d97c5SJed Brown break; 18580c7d97c5SJed Brown 18590c7d97c5SJed Brown case(PARALLEL_BDDC): 18600c7d97c5SJed Brown 18610c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 18620c7d97c5SJed Brown coarse_mat_type = MATMPIAIJ; 18630c7d97c5SJed Brown coarse_pc_type = PCREDUNDANT; 186453cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 18650c7d97c5SJed Brown coarse_comm = prec_comm; 18660c7d97c5SJed Brown active_rank = rank_prec_comm; 18670c7d97c5SJed Brown break; 18680c7d97c5SJed Brown 18690c7d97c5SJed Brown case(SEQUENTIAL_BDDC): 18700c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 18710c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 18720c7d97c5SJed Brown coarse_pc_type = PCLU; 187353cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 18740c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 18750c7d97c5SJed Brown active_rank = master_proc; 18760c7d97c5SJed Brown break; 18770c7d97c5SJed Brown } 18780c7d97c5SJed Brown 18790c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 18800c7d97c5SJed Brown 18810c7d97c5SJed Brown case(SCATTERS_BDDC): 18820c7d97c5SJed Brown { 18830c7d97c5SJed Brown if(pcbddc->coarse_problem_type==MULTILEVEL_BDDC) { 18840c7d97c5SJed Brown 18850c7d97c5SJed Brown PetscMPIInt send_size; 18860c7d97c5SJed Brown PetscInt *aux_ins_indices; 18870c7d97c5SJed Brown PetscInt ii,jj; 18880c7d97c5SJed Brown MPI_Request *requests; 18890c7d97c5SJed Brown 18900c7d97c5SJed Brown /* allocate auxiliary space */ 18915619798eSStefano Zampini ierr = PetscMalloc (pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 18925619798eSStefano 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); 18930c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->coarse_size*sizeof(PetscInt),&aux_ins_indices);CHKERRQ(ierr); 18940c7d97c5SJed Brown ierr = PetscMemzero(aux_ins_indices,pcbddc->coarse_size*sizeof(PetscInt));CHKERRQ(ierr); 18950c7d97c5SJed Brown /* allocate stuffs for message massing */ 18960c7d97c5SJed Brown ierr = PetscMalloc ( (count_recv+1)*sizeof(MPI_Request),&requests);CHKERRQ(ierr); 18970c7d97c5SJed Brown for(i=0;i<count_recv+1;i++) requests[i]=MPI_REQUEST_NULL; 18980c7d97c5SJed Brown ierr = PetscMalloc ( count_recv*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 18990c7d97c5SJed Brown ierr = PetscMalloc ( count_recv*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 19000c7d97c5SJed Brown /* fill up quantities */ 19010c7d97c5SJed Brown j=0; 19020c7d97c5SJed Brown for(i=0;i<count_recv;i++){ 19030c7d97c5SJed Brown ii = ranks_recv[i]; 19040c7d97c5SJed Brown localsizes2[i]=pcbddc->local_primal_sizes[ii]*pcbddc->local_primal_sizes[ii]; 19050c7d97c5SJed Brown localdispl2[i]=j; 19060c7d97c5SJed Brown j+=localsizes2[i]; 19070c7d97c5SJed Brown jj = pcbddc->local_primal_displacements[ii]; 19080c7d97c5SJed 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 19090c7d97c5SJed Brown } 19100c7d97c5SJed Brown //printf("aux_ins_indices 1\n"); 19110c7d97c5SJed Brown //for(i=0;i<pcbddc->coarse_size;i++) 19120c7d97c5SJed Brown // printf("%d ",aux_ins_indices[i]); 19130c7d97c5SJed Brown //printf("\n"); 19140c7d97c5SJed Brown /* temp_coarse_mat_vals used to store temporarly received matrix values */ 19150c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 19160c7d97c5SJed Brown /* evaluate how many values I will insert in coarse mat */ 19170c7d97c5SJed Brown ins_local_primal_size=0; 19180c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++) 19190c7d97c5SJed Brown if(aux_ins_indices[i]) 19200c7d97c5SJed Brown ins_local_primal_size++; 19210c7d97c5SJed Brown /* evaluate indices I will insert in coarse mat */ 19220c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 19230c7d97c5SJed Brown j=0; 19240c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++) 19250c7d97c5SJed Brown if(aux_ins_indices[i]) 19260c7d97c5SJed Brown ins_local_primal_indices[j++]=i; 19270c7d97c5SJed Brown /* use aux_ins_indices to realize a global to local mapping */ 19280c7d97c5SJed Brown j=0; 19290c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++){ 19300c7d97c5SJed Brown if(aux_ins_indices[i]==0){ 19310c7d97c5SJed Brown aux_ins_indices[i]=-1; 19320c7d97c5SJed Brown } else { 19330c7d97c5SJed Brown aux_ins_indices[i]=j; 19340c7d97c5SJed Brown j++; 19350c7d97c5SJed Brown } 19360c7d97c5SJed Brown } 19370c7d97c5SJed Brown 19380c7d97c5SJed Brown //printf("New details localsizes2 localdispl2\n"); 19390c7d97c5SJed Brown //for(i=0;i<count_recv;i++) 19400c7d97c5SJed Brown // printf("(%d %d) ",localsizes2[i],localdispl2[i]); 19410c7d97c5SJed Brown //printf("\n"); 19420c7d97c5SJed Brown //printf("aux_ins_indices 2\n"); 19430c7d97c5SJed Brown //for(i=0;i<pcbddc->coarse_size;i++) 19440c7d97c5SJed Brown // printf("%d ",aux_ins_indices[i]); 19450c7d97c5SJed Brown //printf("\n"); 19460c7d97c5SJed Brown //printf("ins_local_primal_indices\n"); 19470c7d97c5SJed Brown //for(i=0;i<ins_local_primal_size;i++) 19480c7d97c5SJed Brown // printf("%d ",ins_local_primal_indices[i]); 19490c7d97c5SJed Brown //printf("\n"); 19500c7d97c5SJed Brown //printf("coarse_submat_vals\n"); 19510c7d97c5SJed Brown //for(i=0;i<pcbddc->local_primal_size;i++) 19520c7d97c5SJed Brown // for(j=0;j<pcbddc->local_primal_size;j++) 19530c7d97c5SJed 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]); 19540c7d97c5SJed Brown //printf("\n"); 19550c7d97c5SJed Brown 19560c7d97c5SJed Brown /* processes partecipating in coarse problem receive matrix data from their friends */ 195753cdbc3dSStefano 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); 19580c7d97c5SJed Brown if(rank_coarse_proc_send_to != MPI_PROC_NULL ) { 19590c7d97c5SJed Brown send_size=pcbddc->local_primal_size*pcbddc->local_primal_size; 196053cdbc3dSStefano 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); 19610c7d97c5SJed Brown } 196253cdbc3dSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 19630c7d97c5SJed Brown 19640c7d97c5SJed Brown //if(coarse_color == 0) { 19650c7d97c5SJed Brown // printf("temp_coarse_mat_vals\n"); 19660c7d97c5SJed Brown // for(k=0;k<count_recv;k++){ 19670c7d97c5SJed Brown // printf("---- %d ----\n",ranks_recv[k]); 19680c7d97c5SJed Brown // for(i=0;i<pcbddc->local_primal_sizes[ranks_recv[k]];i++) 19690c7d97c5SJed Brown // for(j=0;j<pcbddc->local_primal_sizes[ranks_recv[k]];j++) 19700c7d97c5SJed 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]); 19710c7d97c5SJed Brown // printf("\n"); 19720c7d97c5SJed Brown // } 19730c7d97c5SJed Brown //} 19740c7d97c5SJed Brown /* calculate data to insert in coarse mat */ 19750c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 19760c7d97c5SJed Brown PetscMemzero(ins_coarse_mat_vals,ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar)); 19770c7d97c5SJed Brown 19780c7d97c5SJed Brown PetscMPIInt rr,kk,lps,lpd; 19790c7d97c5SJed Brown PetscInt row_ind,col_ind; 19800c7d97c5SJed Brown for(k=0;k<count_recv;k++){ 19810c7d97c5SJed Brown rr = ranks_recv[k]; 19820c7d97c5SJed Brown kk = localdispl2[k]; 19830c7d97c5SJed Brown lps = pcbddc->local_primal_sizes[rr]; 19840c7d97c5SJed Brown lpd = pcbddc->local_primal_displacements[rr]; 19850c7d97c5SJed Brown //printf("Inserting the following indices (received from %d)\n",rr); 19860c7d97c5SJed Brown for(j=0;j<lps;j++){ 19870c7d97c5SJed Brown col_ind=aux_ins_indices[pcbddc->replicated_local_primal_indices[lpd+j]]; 19880c7d97c5SJed Brown for(i=0;i<lps;i++){ 19890c7d97c5SJed Brown row_ind=aux_ins_indices[pcbddc->replicated_local_primal_indices[lpd+i]]; 19900c7d97c5SJed Brown //printf("%d %d\n",row_ind,col_ind); 19910c7d97c5SJed Brown ins_coarse_mat_vals[col_ind*ins_local_primal_size+row_ind]+=temp_coarse_mat_vals[kk+j*lps+i]; 19920c7d97c5SJed Brown } 19930c7d97c5SJed Brown } 19940c7d97c5SJed Brown } 19950c7d97c5SJed Brown ierr = PetscFree(requests);CHKERRQ(ierr); 19960c7d97c5SJed Brown ierr = PetscFree(aux_ins_indices);CHKERRQ(ierr); 19970c7d97c5SJed Brown ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr); 19980c7d97c5SJed Brown if(coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 19990c7d97c5SJed Brown 20000c7d97c5SJed Brown /* create local to global mapping needed by coarse MATIS */ 20010c7d97c5SJed Brown { 20020c7d97c5SJed Brown IS coarse_IS; 200353cdbc3dSStefano Zampini if(coarse_comm != MPI_COMM_NULL ) ierr = MPI_Comm_free(&coarse_comm);CHKERRQ(ierr); 20040c7d97c5SJed Brown coarse_comm = prec_comm; 20050c7d97c5SJed Brown active_rank=rank_prec_comm; 20060c7d97c5SJed Brown ierr = ISCreateGeneral(coarse_comm,ins_local_primal_size,ins_local_primal_indices,PETSC_COPY_VALUES,&coarse_IS);CHKERRQ(ierr); 20070c7d97c5SJed Brown ierr = ISLocalToGlobalMappingCreateIS(coarse_IS,&coarse_ISLG);CHKERRQ(ierr); 20080c7d97c5SJed Brown ierr = ISDestroy(&coarse_IS);CHKERRQ(ierr); 20090c7d97c5SJed Brown } 20100c7d97c5SJed Brown } 20110c7d97c5SJed Brown if(pcbddc->coarse_problem_type==PARALLEL_BDDC) { 20120c7d97c5SJed Brown /* arrays for values insertion */ 20130c7d97c5SJed Brown ins_local_primal_size = pcbddc->local_primal_size; 20140c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscMPIInt),&ins_local_primal_indices);CHKERRQ(ierr); 20150c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 20160c7d97c5SJed Brown for(j=0;j<ins_local_primal_size;j++){ 20170c7d97c5SJed Brown ins_local_primal_indices[j]=pcbddc->local_primal_indices[j]; 20180c7d97c5SJed 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]; 20190c7d97c5SJed Brown } 20200c7d97c5SJed Brown } 20210c7d97c5SJed Brown break; 20220c7d97c5SJed Brown 20230c7d97c5SJed Brown } 20240c7d97c5SJed Brown 20250c7d97c5SJed Brown case(GATHERS_BDDC): 20260c7d97c5SJed Brown { 20270c7d97c5SJed Brown 20280c7d97c5SJed Brown PetscMPIInt mysize,mysize2; 20290c7d97c5SJed Brown 20300c7d97c5SJed Brown if(rank_prec_comm==active_rank) { 20310c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 20320c7d97c5SJed Brown pcbddc->replicated_local_primal_values = (PetscScalar*)calloc(pcbddc->replicated_primal_size,sizeof(PetscScalar)); 20330c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 20340c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 20350c7d97c5SJed Brown /* arrays for values insertion */ 20360c7d97c5SJed Brown ins_local_primal_size = pcbddc->coarse_size; 20370c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscMPIInt),&ins_local_primal_indices);CHKERRQ(ierr); 20380c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 20390c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) localsizes2[i]=pcbddc->local_primal_sizes[i]*pcbddc->local_primal_sizes[i]; 20400c7d97c5SJed Brown localdispl2[0]=0; 20410c7d97c5SJed Brown for(i=1;i<size_prec_comm;i++) localdispl2[i]=localsizes2[i-1]+localdispl2[i-1]; 20420c7d97c5SJed Brown j=0; 20430c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) j+=localsizes2[i]; 20440c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 20450c7d97c5SJed Brown } 20460c7d97c5SJed Brown 20470c7d97c5SJed Brown mysize=pcbddc->local_primal_size; 20480c7d97c5SJed Brown mysize2=pcbddc->local_primal_size*pcbddc->local_primal_size; 20490c7d97c5SJed Brown if(pcbddc->coarse_problem_type == SEQUENTIAL_BDDC){ 205053cdbc3dSStefano 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); 205153cdbc3dSStefano 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); 20520c7d97c5SJed Brown } else { 205353cdbc3dSStefano 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); 205453cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,prec_comm);CHKERRQ(ierr); 20550c7d97c5SJed Brown } 20560c7d97c5SJed Brown 20570c7d97c5SJed Brown /* free data structures no longer needed and allocate some space which will be needed in BDDC application */ 20580c7d97c5SJed Brown if(rank_prec_comm==active_rank) { 20590c7d97c5SJed Brown PetscInt offset,offset2,row_ind,col_ind; 20600c7d97c5SJed Brown for(j=0;j<ins_local_primal_size;j++){ 20610c7d97c5SJed Brown ins_local_primal_indices[j]=j; 20620c7d97c5SJed Brown for(i=0;i<ins_local_primal_size;i++) ins_coarse_mat_vals[j*ins_local_primal_size+i]=0.0; 20630c7d97c5SJed Brown } 20640c7d97c5SJed Brown for(k=0;k<size_prec_comm;k++){ 20650c7d97c5SJed Brown offset=pcbddc->local_primal_displacements[k]; 20660c7d97c5SJed Brown offset2=localdispl2[k]; 20670c7d97c5SJed Brown for(j=0;j<pcbddc->local_primal_sizes[k];j++){ 20680c7d97c5SJed Brown col_ind=pcbddc->replicated_local_primal_indices[offset+j]; 20690c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_sizes[k];i++){ 20700c7d97c5SJed Brown row_ind=pcbddc->replicated_local_primal_indices[offset+i]; 20710c7d97c5SJed Brown ins_coarse_mat_vals[col_ind*pcbddc->coarse_size+row_ind]+=temp_coarse_mat_vals[offset2+j*pcbddc->local_primal_sizes[k]+i]; 20720c7d97c5SJed Brown } 20730c7d97c5SJed Brown } 20740c7d97c5SJed Brown } 20750c7d97c5SJed Brown } 20760c7d97c5SJed Brown break; 20770c7d97c5SJed Brown }//switch on coarse problem and communications associated with finished 20780c7d97c5SJed Brown } 20790c7d97c5SJed Brown 20800c7d97c5SJed Brown /* Now create and fill up coarse matrix */ 20810c7d97c5SJed Brown if( rank_prec_comm == active_rank ) { 20820c7d97c5SJed Brown if(pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 20830c7d97c5SJed Brown ierr = MatCreate(coarse_comm,&pcbddc->coarse_mat);CHKERRQ(ierr); 20840c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_mat,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size);CHKERRQ(ierr); 20850c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_mat,coarse_mat_type);CHKERRQ(ierr); 20860c7d97c5SJed Brown ierr = MatSetOption(pcbddc->coarse_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 20870c7d97c5SJed Brown ierr = MatSetOption(pcbddc->coarse_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); //local values stored in column major 20880c7d97c5SJed Brown } else { 20890c7d97c5SJed Brown Mat matis_coarse_local_mat; 20900c7d97c5SJed Brown ierr = MatCreateIS(coarse_comm,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_ISLG,&pcbddc->coarse_mat);CHKERRQ(ierr); 20910c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 20920c7d97c5SJed Brown ierr = MatSetOption(matis_coarse_local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); //local values stored in column major 2093a0ba757dSStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 20940c7d97c5SJed Brown } 2095a0ba757dSStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 20960c7d97c5SJed 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); 20970c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20980c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20990c7d97c5SJed Brown if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 21000c7d97c5SJed Brown Mat matis_coarse_local_mat; 21010c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 21020c7d97c5SJed Brown ierr = MatSetBlockSize(matis_coarse_local_mat,bs);CHKERRQ(ierr); 21030c7d97c5SJed Brown } 21040c7d97c5SJed Brown 21050c7d97c5SJed Brown ierr = MatGetVecs(pcbddc->coarse_mat,&pcbddc->coarse_vec,&pcbddc->coarse_rhs);CHKERRQ(ierr); 21060c7d97c5SJed Brown /* Preconditioner for coarse problem */ 210753cdbc3dSStefano Zampini ierr = KSPCreate(coarse_comm,&pcbddc->coarse_ksp);CHKERRQ(ierr); 210853cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 210953cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 21105619798eSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 211153cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 211253cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 211353cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 21140c7d97c5SJed Brown /* Allow user's customization */ 211553cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 21160c7d97c5SJed Brown /* Set Up PC for coarse problem BDDC */ 211753cdbc3dSStefano Zampini if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2118e269702eSStefano Zampini if(dbg_flag) { 2119e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------Setting up a new level---------------\n");CHKERRQ(ierr); 2120e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2121e269702eSStefano Zampini } 212253cdbc3dSStefano Zampini ierr = PCBDDCSetCoarseProblemType(pc_temp,MULTILEVEL_BDDC);CHKERRQ(ierr); 212353cdbc3dSStefano Zampini } 212453cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 21255619798eSStefano Zampini if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 21265619798eSStefano Zampini if(dbg_flag) { 21275619798eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------New level set------------------------\n");CHKERRQ(ierr); 21285619798eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 21295619798eSStefano Zampini } 21305619798eSStefano Zampini } 21310c7d97c5SJed Brown } 21320c7d97c5SJed Brown if(pcbddc->coarse_communications_type == SCATTERS_BDDC) { 21330c7d97c5SJed Brown IS local_IS,global_IS; 21340c7d97c5SJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&local_IS);CHKERRQ(ierr); 21350c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_indices,PETSC_COPY_VALUES,&global_IS);CHKERRQ(ierr); 21360c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_P,local_IS,pcbddc->coarse_vec,global_IS,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 21370c7d97c5SJed Brown ierr = ISDestroy(&local_IS);CHKERRQ(ierr); 21380c7d97c5SJed Brown ierr = ISDestroy(&global_IS);CHKERRQ(ierr); 21390c7d97c5SJed Brown } 21400c7d97c5SJed Brown 21410c7d97c5SJed Brown 21420c7d97c5SJed Brown /* Check condition number of coarse problem */ 2143e269702eSStefano Zampini if( pcbddc->coarse_problem_type == MULTILEVEL_BDDC && dbg_flag && rank_prec_comm == active_rank ) { 21440c7d97c5SJed Brown PetscScalar m_one=-1.0; 21455619798eSStefano Zampini PetscReal infty_error,lambda_min,lambda_max,kappa_2; 21460c7d97c5SJed Brown 21475619798eSStefano Zampini /* change coarse ksp object to an iterative method suitable for extreme eigenvalues' estimation */ 2148d49ef151SStefano Zampini ierr = KSPSetComputeSingularValues(pcbddc->coarse_ksp,PETSC_TRUE);CHKERRQ(ierr); 21495619798eSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,KSPGMRES);CHKERRQ(ierr); 21505619798eSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,1.e-8,1.e-8,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 21515619798eSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 2152d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->coarse_rhs,PETSC_NULL);CHKERRQ(ierr); 2153d49ef151SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 2154d49ef151SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,pcbddc->coarse_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 2155d49ef151SStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,pcbddc->coarse_rhs,pcbddc->coarse_rhs);CHKERRQ(ierr); 2156d49ef151SStefano Zampini ierr = KSPComputeExtremeSingularValues(pcbddc->coarse_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); 21575619798eSStefano Zampini kappa_2=lambda_max/lambda_min; 21585619798eSStefano Zampini ierr = KSPGetIterationNumber(pcbddc->coarse_ksp,&k);CHKERRQ(ierr); 2159d49ef151SStefano Zampini ierr = VecAXPY(pcbddc->coarse_rhs,m_one,pcbddc->coarse_vec);CHKERRQ(ierr); 2160d49ef151SStefano Zampini ierr = VecNorm(pcbddc->coarse_rhs,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 21615619798eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem condition number estimated with %d iterations of gmres is: % 1.14e\n",k,kappa_2);CHKERRQ(ierr); 2162e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues: % 1.14e %1.14e\n",lambda_min,lambda_max);CHKERRQ(ierr); 2163e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem infty_error: %1.14e\n",infty_error);CHKERRQ(ierr); 21645619798eSStefano Zampini /* restore coarse ksp to default values */ 2165d49ef151SStefano Zampini ierr = KSPSetComputeSingularValues(pcbddc->coarse_ksp,PETSC_FALSE);CHKERRQ(ierr); 21665619798eSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 21675619798eSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 21685619798eSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 21695619798eSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 217053cdbc3dSStefano Zampini } 21710c7d97c5SJed Brown 21720c7d97c5SJed Brown /* free data structures no longer needed */ 21730c7d97c5SJed Brown if(coarse_ISLG) { ierr = ISLocalToGlobalMappingDestroy(&coarse_ISLG);CHKERRQ(ierr); } 21740c7d97c5SJed Brown if(ins_local_primal_indices) { ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); } 21750c7d97c5SJed Brown if(ins_coarse_mat_vals) { ierr = PetscFree(ins_coarse_mat_vals);CHKERRQ(ierr);} 21760c7d97c5SJed Brown if(localsizes2) { ierr = PetscFree(localsizes2);CHKERRQ(ierr);} 21770c7d97c5SJed Brown if(localdispl2) { ierr = PetscFree(localdispl2);CHKERRQ(ierr);} 21780c7d97c5SJed Brown if(temp_coarse_mat_vals) { ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr);} 21790c7d97c5SJed Brown 21800c7d97c5SJed Brown PetscFunctionReturn(0); 21810c7d97c5SJed Brown } 21820c7d97c5SJed Brown 21830c7d97c5SJed Brown #undef __FUNCT__ 21840c7d97c5SJed Brown #define __FUNCT__ "PCBDDCManageLocalBoundaries" 218553cdbc3dSStefano Zampini static PetscErrorCode PCBDDCManageLocalBoundaries(PC pc) 21860c7d97c5SJed Brown { 21870c7d97c5SJed Brown 21880c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 21890c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 21900c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 219153cdbc3dSStefano Zampini PetscInt **neighbours_set; 219253cdbc3dSStefano Zampini PetscInt bs,ierr,i,j,s,k,iindex; 21930c7d97c5SJed Brown PetscInt total_counts; 21940c7d97c5SJed Brown PetscBool flg_row; 21950c7d97c5SJed Brown PCBDDCGraph mat_graph; 219653cdbc3dSStefano Zampini PetscInt neumann_bsize; 219753cdbc3dSStefano Zampini const PetscInt* neumann_nodes; 21980c7d97c5SJed Brown Mat mat_adj; 2199a0ba757dSStefano Zampini PetscBool symmetrize_rowij=PETSC_TRUE,compressed_rowij=PETSC_FALSE; 2200a0ba757dSStefano Zampini PetscMPIInt adapt_interface=0,adapt_interface_reduced=0; 2201a0ba757dSStefano Zampini PetscInt* queue_in_global_numbering; 2202a0ba757dSStefano Zampini MPI_Comm interface_comm=((PetscObject)pc)->comm; 22030c7d97c5SJed Brown 22040c7d97c5SJed Brown PetscFunctionBegin; 22050c7d97c5SJed Brown 2206a0ba757dSStefano Zampini /* allocate and initialize needed graph structure */ 22070c7d97c5SJed Brown ierr = PetscMalloc(sizeof(*mat_graph),&mat_graph);CHKERRQ(ierr); 22080c7d97c5SJed Brown ierr = MatConvert(matis->A,MATMPIADJ,MAT_INITIAL_MATRIX,&mat_adj);CHKERRQ(ierr); 2209a0ba757dSStefano Zampini /* ierr = MatDuplicate(matis->A,MAT_COPY_VALUES,&mat_adj);CHKERRQ(ierr); */ 2210a0ba757dSStefano Zampini ierr = MatGetRowIJ(mat_adj,0,symmetrize_rowij,compressed_rowij,&mat_graph->nvtxs,&mat_graph->xadj,&mat_graph->adjncy,&flg_row);CHKERRQ(ierr); 22110c7d97c5SJed Brown if(!flg_row) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatGetRowIJ called from PCBDDCManageLocalBoundaries.\n"); 2212a0ba757dSStefano Zampini i = mat_graph->nvtxs; 2213a0ba757dSStefano 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); 2214a0ba757dSStefano Zampini ierr = PetscMalloc3(i,PetscInt,&mat_graph->which_dof,i,PetscBool,&mat_graph->touched,i,PetscInt,&queue_in_global_numbering);CHKERRQ(ierr); 2215a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->where,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2216a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->count,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2217a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->which_dof,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2218a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->queue,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 22193828260eSStefano Zampini ierr = PetscMemzero(mat_graph->cptr,(mat_graph->nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 22203828260eSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){mat_graph->touched[i]=PETSC_FALSE;} 2221a0ba757dSStefano Zampini 2222*9c0446d6SStefano Zampini /* Setting dofs splitting in mat_graph->which_dof */ 2223*9c0446d6SStefano Zampini if(pcbddc->n_ISForDofs) { /* get information about dofs' splitting if provided by the user */ 2224*9c0446d6SStefano Zampini PetscInt *is_indices; 2225*9c0446d6SStefano Zampini PetscInt is_size; 2226*9c0446d6SStefano Zampini for(i=0;i<pcbddc->n_ISForDofs;i++) { 2227*9c0446d6SStefano Zampini ierr = ISGetSize(pcbddc->ISForDofs[i],&is_size);CHKERRQ(ierr); 2228*9c0446d6SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofs[i],(const PetscInt**)&is_indices);CHKERRQ(ierr); 2229*9c0446d6SStefano Zampini for(j=0;j<is_size;j++) { 2230*9c0446d6SStefano Zampini mat_graph->which_dof[is_indices[j]]=i; 2231*9c0446d6SStefano Zampini } 2232*9c0446d6SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofs[i],(const PetscInt**)&is_indices);CHKERRQ(ierr); 2233*9c0446d6SStefano Zampini } 2234*9c0446d6SStefano Zampini } else { /* otherwise assume constant block size */ 2235a0ba757dSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 22360c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs/bs;i++) { 22370c7d97c5SJed Brown for(s=0;s<bs;s++) { 22380c7d97c5SJed Brown mat_graph->which_dof[i*bs+s]=s; 22390c7d97c5SJed Brown } 22400c7d97c5SJed Brown } 2241*9c0446d6SStefano Zampini } 22420c7d97c5SJed Brown 22430c7d97c5SJed Brown total_counts=0; 22440c7d97c5SJed Brown for(i=0;i<pcis->n_neigh;i++){ 22450c7d97c5SJed Brown s=pcis->n_shared[i]; 22460c7d97c5SJed Brown total_counts+=s; 224753cdbc3dSStefano Zampini for(j=0;j<s;j++){ 22480c7d97c5SJed Brown mat_graph->count[pcis->shared[i][j]] += 1; 22490c7d97c5SJed Brown } 22500c7d97c5SJed Brown } 22510c7d97c5SJed Brown /* Take into account Neumann data incrementing number of sharing subdomains for all but faces nodes lying on the interface */ 225253cdbc3dSStefano Zampini if(pcbddc->NeumannBoundaries) { 2253*9c0446d6SStefano Zampini ierr = ISGetSize(pcbddc->NeumannBoundaries,&neumann_bsize);CHKERRQ(ierr); 225453cdbc3dSStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundaries,&neumann_nodes);CHKERRQ(ierr); 225553cdbc3dSStefano Zampini for(i=0;i<neumann_bsize;i++){ 225653cdbc3dSStefano Zampini iindex = neumann_nodes[i]; 225753cdbc3dSStefano Zampini if(mat_graph->count[iindex] > 2){ 225853cdbc3dSStefano Zampini mat_graph->count[iindex]+=1; 22590c7d97c5SJed Brown total_counts++; 22600c7d97c5SJed Brown } 22610c7d97c5SJed Brown } 22620c7d97c5SJed Brown } 22630c7d97c5SJed Brown 2264a0ba757dSStefano Zampini /* allocate space for storing neighbours' set */ 226553cdbc3dSStefano Zampini ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt*),&neighbours_set);CHKERRQ(ierr); 226653cdbc3dSStefano Zampini if(mat_graph->nvtxs) ierr = PetscMalloc(total_counts*sizeof(PetscInt),&neighbours_set[0]);CHKERRQ(ierr); 226753cdbc3dSStefano Zampini for(i=1;i<mat_graph->nvtxs;i++) neighbours_set[i]=neighbours_set[i-1]+mat_graph->count[i-1]; 2268a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->count,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 22690c7d97c5SJed Brown for(i=0;i<pcis->n_neigh;i++){ 22700c7d97c5SJed Brown s=pcis->n_shared[i]; 22710c7d97c5SJed Brown for(j=0;j<s;j++) { 22720c7d97c5SJed Brown k=pcis->shared[i][j]; 227353cdbc3dSStefano Zampini neighbours_set[k][mat_graph->count[k]] = pcis->neigh[i]; 22740c7d97c5SJed Brown mat_graph->count[k]+=1; 22750c7d97c5SJed Brown } 22760c7d97c5SJed Brown } 22770c7d97c5SJed Brown /* set -1 fake neighbour */ 227853cdbc3dSStefano Zampini if(pcbddc->NeumannBoundaries) { 227953cdbc3dSStefano Zampini for(i=0;i<neumann_bsize;i++){ 228053cdbc3dSStefano Zampini iindex = neumann_nodes[i]; 228153cdbc3dSStefano Zampini if( mat_graph->count[iindex] > 2){ 2282a0ba757dSStefano Zampini neighbours_set[iindex][mat_graph->count[iindex]] = -1; /* An additional fake neighbour (with rank -1) */ 228353cdbc3dSStefano Zampini mat_graph->count[iindex]+=1; 22840c7d97c5SJed Brown } 22850c7d97c5SJed Brown } 228653cdbc3dSStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundaries,&neumann_nodes);CHKERRQ(ierr); 22870c7d97c5SJed Brown } 2288a0ba757dSStefano Zampini /* sort set of sharing subdomains for comparison */ 228953cdbc3dSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++) { ierr = PetscSortInt(mat_graph->count[i],neighbours_set[i]);CHKERRQ(ierr); } 2290a0ba757dSStefano Zampini /* start analyzing local interface */ 22910c7d97c5SJed Brown PetscInt nodes_touched=0; 22920c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs;i++){ 2293a0ba757dSStefano Zampini if(!mat_graph->count[i]){ /* internal nodes */ 22940c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 22950c7d97c5SJed Brown mat_graph->where[i]=0; 22960c7d97c5SJed Brown nodes_touched++; 22970c7d97c5SJed Brown } 22980c7d97c5SJed Brown } 2299a0ba757dSStefano Zampini PetscInt where_values=1; 23000c7d97c5SJed Brown PetscBool same_set; 23010c7d97c5SJed Brown mat_graph->ncmps = 0; 23020c7d97c5SJed Brown while(nodes_touched<mat_graph->nvtxs) { 2303a0ba757dSStefano Zampini /* find first untouched node in local ordering */ 23040c7d97c5SJed Brown i=0; 23050c7d97c5SJed Brown while(mat_graph->touched[i]) i++; 23060c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 2307a0ba757dSStefano Zampini mat_graph->where[i]=where_values; 23080c7d97c5SJed Brown nodes_touched++; 2309a0ba757dSStefano Zampini /* now find all other nodes having the same set of sharing subdomains */ 23100c7d97c5SJed Brown for(j=i+1;j<mat_graph->nvtxs;j++){ 2311a0ba757dSStefano Zampini /* check for same number of sharing subdomains and dof number */ 23120c7d97c5SJed Brown if(mat_graph->count[i]==mat_graph->count[j] && mat_graph->which_dof[i] == mat_graph->which_dof[j] ){ 2313a0ba757dSStefano Zampini /* check for same set of sharing subdomains */ 23140c7d97c5SJed Brown same_set=PETSC_TRUE; 23150c7d97c5SJed Brown for(k=0;k<mat_graph->count[j];k++){ 231653cdbc3dSStefano Zampini if(neighbours_set[i][k]!=neighbours_set[j][k]) { 23170c7d97c5SJed Brown same_set=PETSC_FALSE; 23180c7d97c5SJed Brown } 23190c7d97c5SJed Brown } 2320a0ba757dSStefano Zampini /* I found a friend of mine */ 23210c7d97c5SJed Brown if(same_set) { 2322a0ba757dSStefano Zampini mat_graph->where[j]=where_values; 23230c7d97c5SJed Brown mat_graph->touched[j]=PETSC_TRUE; 23240c7d97c5SJed Brown nodes_touched++; 23250c7d97c5SJed Brown } 23260c7d97c5SJed Brown } 23270c7d97c5SJed Brown } 2328a0ba757dSStefano Zampini where_values++; 23290c7d97c5SJed Brown } 2330a0ba757dSStefano Zampini where_values--; if(where_values<0) where_values=0; 2331a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscMPIInt),&mat_graph->where_ncmps);CHKERRQ(ierr); 2332a0ba757dSStefano Zampini /* Find connected components defined on the shared interface */ 2333a0ba757dSStefano Zampini if(where_values) { 2334a0ba757dSStefano Zampini ierr = PCBDDCFindConnectedComponents(mat_graph, where_values); 2335a0ba757dSStefano Zampini /* For consistency among neughbouring procs, I need to sort (by global ordering) each connected component contained in the global queue (and carring together the local queue) */ 2336a0ba757dSStefano Zampini for(i=0;i<mat_graph->ncmps;i++) { 2337a0ba757dSStefano 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); 2338a0ba757dSStefano 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); 2339a0ba757dSStefano Zampini } 2340a0ba757dSStefano Zampini /* for(i=0;i<mat_graph->ncmps;i++) { 2341a0ba757dSStefano Zampini printf("[queue num %d] ptr %d, length %d: global node (local node)\n",i,mat_graph->cptr[i],mat_graph->cptr[i+1]-mat_graph->cptr[i]); 2342a0ba757dSStefano Zampini for(j=0;j<mat_graph->cptr[i+1]-mat_graph->cptr[i];j++){ 2343a0ba757dSStefano Zampini printf("%d (%d) ",queue_in_global_numbering[mat_graph->cptr[i]+j],mat_graph->queue[mat_graph->cptr[i]+j]); 2344a0ba757dSStefano Zampini } 2345a0ba757dSStefano Zampini printf("\n"); 2346a0ba757dSStefano Zampini } */ 2347a0ba757dSStefano Zampini } 2348a0ba757dSStefano Zampini /* check consistency of connected components among neighbouring subdomains -> it adapt them in case it is needed */ 2349a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 2350a0ba757dSStefano Zampini if(mat_graph->where_ncmps[i]>1) { /* We are not sure that two connected components will be the same among subdomains sharing a subset of local interface */ 2351a0ba757dSStefano Zampini adapt_interface=1; 2352a0ba757dSStefano Zampini break; 2353a0ba757dSStefano Zampini } 2354a0ba757dSStefano Zampini } 2355a0ba757dSStefano Zampini ierr = MPI_Allreduce(&adapt_interface,&adapt_interface_reduced,1,MPIU_INT,MPI_LOR,interface_comm);CHKERRQ(ierr); 2356a0ba757dSStefano Zampini if(where_values && adapt_interface_reduced) { 23570c7d97c5SJed Brown 2358a0ba757dSStefano Zampini PetscInt sum_requests=0,my_rank; 2359a0ba757dSStefano Zampini PetscInt buffer_size,start_of_recv,size_of_recv,start_of_send; 2360a0ba757dSStefano Zampini PetscInt temp_buffer_size,ins_val,global_where_counter; 2361a0ba757dSStefano Zampini PetscInt *cum_recv_counts; 2362a0ba757dSStefano Zampini PetscInt *where_to_nodes_indices; 2363a0ba757dSStefano Zampini PetscInt *petsc_buffer; 2364a0ba757dSStefano Zampini PetscMPIInt *recv_buffer; 2365a0ba757dSStefano Zampini PetscMPIInt *recv_buffer_where; 2366a0ba757dSStefano Zampini PetscMPIInt *send_buffer; 2367a0ba757dSStefano Zampini PetscMPIInt size_of_send; 2368a0ba757dSStefano Zampini PetscInt *sizes_of_sends; 2369a0ba757dSStefano Zampini MPI_Request *send_requests; 2370a0ba757dSStefano Zampini MPI_Request *recv_requests; 2371a0ba757dSStefano Zampini PetscInt *where_cc_adapt; 2372a0ba757dSStefano Zampini PetscInt **temp_buffer; 2373a0ba757dSStefano Zampini PetscInt *nodes_to_temp_buffer_indices; 2374a0ba757dSStefano Zampini PetscInt *add_to_where; 2375a0ba757dSStefano Zampini 2376a0ba757dSStefano Zampini ierr = MPI_Comm_rank(interface_comm,&my_rank);CHKERRQ(ierr); 2377a0ba757dSStefano Zampini ierr = PetscMalloc((where_values+1)*sizeof(PetscInt),&cum_recv_counts);CHKERRQ(ierr); 2378a0ba757dSStefano Zampini ierr = PetscMemzero(cum_recv_counts,(where_values+1)*sizeof(PetscInt));CHKERRQ(ierr); 2379a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&where_to_nodes_indices);CHKERRQ(ierr); 2380a0ba757dSStefano Zampini /* first count how many neighbours per connected component I will receive from */ 2381a0ba757dSStefano Zampini cum_recv_counts[0]=0; 2382a0ba757dSStefano Zampini for(i=1;i<where_values+1;i++){ 2383a0ba757dSStefano Zampini j=0; 2384a0ba757dSStefano Zampini while(mat_graph->where[j] != i) j++; 2385a0ba757dSStefano Zampini where_to_nodes_indices[i-1]=j; 2386a0ba757dSStefano Zampini if(neighbours_set[j][0]!=-1) { cum_recv_counts[i]=cum_recv_counts[i-1]+mat_graph->count[j]-1; } /* We don't want sends/recvs_to/from_self -> here I don't count myself */ 2387a0ba757dSStefano Zampini else { cum_recv_counts[i]=cum_recv_counts[i-1]+mat_graph->count[j]-2; } 2388a0ba757dSStefano Zampini } 2389a0ba757dSStefano Zampini buffer_size=2*cum_recv_counts[where_values]+mat_graph->nvtxs; 2390a0ba757dSStefano Zampini ierr = PetscMalloc(2*cum_recv_counts[where_values]*sizeof(PetscMPIInt),&recv_buffer_where);CHKERRQ(ierr); 2391a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 2392a0ba757dSStefano Zampini ierr = PetscMalloc(cum_recv_counts[where_values]*sizeof(MPI_Request),&send_requests);CHKERRQ(ierr); 2393a0ba757dSStefano Zampini ierr = PetscMalloc(cum_recv_counts[where_values]*sizeof(MPI_Request),&recv_requests);CHKERRQ(ierr); 2394a0ba757dSStefano Zampini for(i=0;i<cum_recv_counts[where_values];i++) { 2395a0ba757dSStefano Zampini send_requests[i]=MPI_REQUEST_NULL; 2396a0ba757dSStefano Zampini recv_requests[i]=MPI_REQUEST_NULL; 2397a0ba757dSStefano Zampini } 2398a0ba757dSStefano Zampini /* printf("MPI sizes: buffer size for send %d, number of requests %d\n",buffer_size,cum_recv_counts[where_values]); */ 2399a0ba757dSStefano Zampini 2400a0ba757dSStefano Zampini /* exchange with my neighbours the number of my connected components on the shared interface */ 2401a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2402a0ba757dSStefano Zampini j=where_to_nodes_indices[i]; 2403a0ba757dSStefano Zampini k = (neighbours_set[j][0] == -1 ? 1 : 0); 2404a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2405a0ba757dSStefano Zampini if(neighbours_set[j][k] != my_rank) { 2406a0ba757dSStefano 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); 2407a0ba757dSStefano 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); 2408a0ba757dSStefano Zampini /*printf("SENDREQ[%d]: to %d (tag %d) the value %d\n",sum_requests,neighbours_set[j][k],(my_rank+1)*mat_graph->count[j],mat_graph->where_ncmps[i]); 2409a0ba757dSStefano Zampini printf("RECVREQ[%d]: from %d (tag %d) at buffer address %d\n",sum_requests,neighbours_set[j][k],(neighbours_set[j][k]+1)*mat_graph->count[j],sum_requests);*/ 2410a0ba757dSStefano Zampini sum_requests++; 2411a0ba757dSStefano Zampini } 2412a0ba757dSStefano Zampini } 2413a0ba757dSStefano Zampini } 2414a0ba757dSStefano Zampini /* printf("Final number of request: s=r=%d (should be equal to %d)\n",sum_requests,cum_recv_counts[where_values]); */ 2415a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2416a0ba757dSStefano Zampini /*for(i=0;i<where_values;i++){ 2417a0ba757dSStefano Zampini printf("my where_ncmps[%d]=%d\n",i,mat_graph->where_ncmps[i]); 2418a0ba757dSStefano Zampini for(j=cum_recv_counts[i];j<cum_recv_counts[i+1];j++){ 2419a0ba757dSStefano Zampini printf(" recv where_ncmps[%d]=%d\n",j,recv_buffer_where[j]); 2420a0ba757dSStefano Zampini } 2421a0ba757dSStefano Zampini }*/ 2422a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2423a0ba757dSStefano Zampini 2424a0ba757dSStefano Zampini /* determine the connected component I need to adapt */ 2425a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&where_cc_adapt);CHKERRQ(ierr); 2426a0ba757dSStefano Zampini ierr = PetscMemzero(where_cc_adapt,where_values*sizeof(PetscInt));CHKERRQ(ierr); 2427a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2428a0ba757dSStefano Zampini for(j=cum_recv_counts[i];j<cum_recv_counts[i+1];j++){ 2429a0ba757dSStefano Zampini if( mat_graph->where_ncmps[i]!=recv_buffer_where[j] || mat_graph->where_ncmps[i] > 1 ) { /* The first condition is natural (i.e someone has a different number of cc than me), the second one is just to be safe */ 2430a0ba757dSStefano Zampini where_cc_adapt[i]=PETSC_TRUE; 2431a0ba757dSStefano Zampini break; 2432a0ba757dSStefano Zampini } 2433a0ba757dSStefano Zampini } 2434a0ba757dSStefano Zampini } 2435a0ba757dSStefano Zampini /* now get from neighbours their ccs (in global numbering) and adapt them (in case it is needed) */ 2436a0ba757dSStefano Zampini /* first determine how much data to send (size of each queue plus the global indices) and communicate it to neighbours */ 2437a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&sizes_of_sends);CHKERRQ(ierr); 2438a0ba757dSStefano Zampini ierr = PetscMemzero(sizes_of_sends,where_values*sizeof(PetscInt));CHKERRQ(ierr); 2439a0ba757dSStefano Zampini sum_requests=0; 2440a0ba757dSStefano Zampini start_of_send=0; 2441a0ba757dSStefano Zampini start_of_recv=cum_recv_counts[where_values]; 2442a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 2443a0ba757dSStefano Zampini if(where_cc_adapt[i]) { 2444a0ba757dSStefano Zampini size_of_send=0; 2445a0ba757dSStefano Zampini for(j=i;j<mat_graph->ncmps;j++) { 2446a0ba757dSStefano Zampini if(mat_graph->where[mat_graph->queue[mat_graph->cptr[j]]] == i+1) { /* WARNING -> where values goes from 1 to where_values included */ 2447a0ba757dSStefano Zampini send_buffer[start_of_send+size_of_send]=mat_graph->cptr[j+1]-mat_graph->cptr[j]; 2448a0ba757dSStefano Zampini size_of_send+=1; 2449a0ba757dSStefano Zampini for(k=0;k<mat_graph->cptr[j+1]-mat_graph->cptr[j];k++) { 2450a0ba757dSStefano Zampini send_buffer[start_of_send+size_of_send+k]=queue_in_global_numbering[mat_graph->cptr[j]+k]; 2451a0ba757dSStefano Zampini } 2452a0ba757dSStefano Zampini size_of_send=size_of_send+mat_graph->cptr[j+1]-mat_graph->cptr[j]; 2453a0ba757dSStefano Zampini } 2454a0ba757dSStefano Zampini } 2455a0ba757dSStefano Zampini j = where_to_nodes_indices[i]; 2456a0ba757dSStefano Zampini k = (neighbours_set[j][0] == -1 ? 1 : 0); 2457a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2458a0ba757dSStefano Zampini if(neighbours_set[j][k] != my_rank) { 2459a0ba757dSStefano Zampini /* printf("SENDREQ[%d]: to %d (tag %d) the value %d\n",sum_requests,neighbours_set[j][k],(my_rank+1)*mat_graph->count[j],size_of_send); 2460a0ba757dSStefano Zampini printf("RECVREQ[%d]: from %d (tag %d) at buffer address %d\n",sum_requests,neighbours_set[j][k],(neighbours_set[j][k]+1)*mat_graph->count[j],sum_requests+start_of_recv);*/ 2461a0ba757dSStefano 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); 2462a0ba757dSStefano 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); 2463a0ba757dSStefano Zampini sum_requests++; 2464a0ba757dSStefano Zampini } 2465a0ba757dSStefano Zampini } 2466a0ba757dSStefano Zampini sizes_of_sends[i]=size_of_send; 2467a0ba757dSStefano Zampini start_of_send+=size_of_send; 2468a0ba757dSStefano Zampini } 2469a0ba757dSStefano Zampini } 2470a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2471a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2472a0ba757dSStefano Zampini /*j=0; 2473a0ba757dSStefano Zampini for(k=0;k<where_values;k++) { j+=sizes_of_sends[k]; } 2474a0ba757dSStefano Zampini printf("This is the send buffer (size %d): \n",j); 2475a0ba757dSStefano Zampini for(k=0;k<j;k++) { printf("%d ",send_buffer[k]); } 2476a0ba757dSStefano Zampini printf("\n");*/ 2477a0ba757dSStefano Zampini buffer_size=0; 2478a0ba757dSStefano Zampini for(k=0;k<sum_requests;k++) { buffer_size+=recv_buffer_where[start_of_recv+k]; } 2479a0ba757dSStefano Zampini /* printf("Allocating recv buffer of size %d\n",buffer_size); */ 2480a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscMPIInt),&recv_buffer);CHKERRQ(ierr); 2481a0ba757dSStefano Zampini /* now exchange the data */ 2482a0ba757dSStefano Zampini start_of_recv=0; 2483a0ba757dSStefano Zampini start_of_send=0; 2484a0ba757dSStefano Zampini sum_requests=0; 2485a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 2486a0ba757dSStefano Zampini if(where_cc_adapt[i]) { 2487a0ba757dSStefano Zampini size_of_send = sizes_of_sends[i]; 2488a0ba757dSStefano Zampini j = where_to_nodes_indices[i]; 2489a0ba757dSStefano Zampini k = (neighbours_set[j][0] == -1 ? 1 : 0); 2490a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2491a0ba757dSStefano Zampini if(neighbours_set[j][k] != my_rank) { 2492a0ba757dSStefano Zampini /* printf("SENDREQ[%d]: to %d (tag %d) with size %d at buffer address %d\n",sum_requests,neighbours_set[j][k],(my_rank+1)*mat_graph->count[j],size_of_send,start_of_send); 2493a0ba757dSStefano Zampini printf("RECVREQ[%d]: from %d (tag %d) at buffer address %d\n",sum_requests,neighbours_set[j][k],(neighbours_set[j][k]+1)*mat_graph->count[j],start_of_recv); */ 2494a0ba757dSStefano 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); 2495a0ba757dSStefano Zampini size_of_recv=recv_buffer_where[cum_recv_counts[where_values]+sum_requests]; 2496a0ba757dSStefano 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); 2497a0ba757dSStefano Zampini start_of_recv+=size_of_recv; 2498a0ba757dSStefano Zampini sum_requests++; 2499a0ba757dSStefano Zampini } 2500a0ba757dSStefano Zampini } 2501a0ba757dSStefano Zampini start_of_send+=size_of_send; 2502a0ba757dSStefano Zampini } 2503a0ba757dSStefano Zampini } 2504a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2505a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2506a0ba757dSStefano Zampini /*printf("This is what I received (size %d): \n",start_of_recv); 2507a0ba757dSStefano Zampini for(k=0;k<start_of_recv;k++) { printf("%d ",recv_buffer[k]); } 2508a0ba757dSStefano Zampini printf("\n");*/ 2509a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscInt),&petsc_buffer);CHKERRQ(ierr); 2510a0ba757dSStefano Zampini for(k=0;k<start_of_recv;k++) { petsc_buffer[k]=(PetscInt)recv_buffer[k]; } 2511a0ba757dSStefano Zampini for(j=0;j<buffer_size;) { 2512a0ba757dSStefano Zampini ierr = ISGlobalToLocalMappingApply(matis->mapping,IS_GTOLM_MASK,petsc_buffer[j],&petsc_buffer[j+1],&petsc_buffer[j],&petsc_buffer[j+1]);CHKERRQ(ierr); 2513a0ba757dSStefano Zampini k=petsc_buffer[j]+1; 2514a0ba757dSStefano Zampini j+=k; 2515a0ba757dSStefano Zampini } 2516a0ba757dSStefano Zampini /*printf("This is what I received in local numbering (unrolled): \n"); 2517a0ba757dSStefano Zampini i=0; 2518a0ba757dSStefano Zampini for(j=0;j<buffer_size;) { 2519a0ba757dSStefano Zampini printf("queue num %d (j=%d)\n",i,j); 2520a0ba757dSStefano Zampini for(k=1;k<petsc_buffer[j]+1;k++) { printf("%d ",petsc_buffer[k+j]); } 2521a0ba757dSStefano Zampini printf("\n"); 2522a0ba757dSStefano Zampini i++;j+=k; 2523a0ba757dSStefano Zampini }*/ 2524a0ba757dSStefano Zampini sum_requests=cum_recv_counts[where_values]; 2525a0ba757dSStefano Zampini start_of_recv=0; 2526a0ba757dSStefano Zampini ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt),&nodes_to_temp_buffer_indices);CHKERRQ(ierr); 2527a0ba757dSStefano Zampini global_where_counter=0; 2528a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2529a0ba757dSStefano Zampini if(where_cc_adapt[i]){ 2530a0ba757dSStefano Zampini temp_buffer_size=0; 2531a0ba757dSStefano Zampini /* find nodes on the shared interface we need to adapt */ 2532a0ba757dSStefano Zampini for(j=0;j<mat_graph->nvtxs;j++){ 2533a0ba757dSStefano Zampini if(mat_graph->where[j]==i+1) { 2534a0ba757dSStefano Zampini nodes_to_temp_buffer_indices[j]=temp_buffer_size; 2535a0ba757dSStefano Zampini temp_buffer_size++; 2536a0ba757dSStefano Zampini } else { 2537a0ba757dSStefano Zampini nodes_to_temp_buffer_indices[j]=-1; 2538a0ba757dSStefano Zampini } 2539a0ba757dSStefano Zampini } 2540a0ba757dSStefano Zampini /* allocate some temporary space */ 2541a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*sizeof(PetscInt*),&temp_buffer);CHKERRQ(ierr); 2542a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*(cum_recv_counts[i+1]-cum_recv_counts[i])*sizeof(PetscInt),&temp_buffer[0]);CHKERRQ(ierr); 2543a0ba757dSStefano Zampini ierr = PetscMemzero(temp_buffer[0],temp_buffer_size*(cum_recv_counts[i+1]-cum_recv_counts[i])*sizeof(PetscInt));CHKERRQ(ierr); 2544a0ba757dSStefano Zampini for(j=1;j<temp_buffer_size;j++){ 2545a0ba757dSStefano Zampini temp_buffer[j]=temp_buffer[j-1]+cum_recv_counts[i+1]-cum_recv_counts[i]; 2546a0ba757dSStefano Zampini } 2547a0ba757dSStefano Zampini /* analyze contributions from neighbouring subdomains for i-th conn comp 2548a0ba757dSStefano Zampini temp buffer structure: 2549a0ba757dSStefano Zampini supposing part of the interface has dimension 5 (global nodes 0,1,2,3,4) 2550a0ba757dSStefano Zampini 3 neighs procs with structured connected components: 2551a0ba757dSStefano Zampini neigh 0: [0 1 4], [2 3]; (2 connected components) 2552a0ba757dSStefano Zampini neigh 1: [0 1], [2 3 4]; (2 connected components) 2553a0ba757dSStefano Zampini neigh 2: [0 4], [1], [2 3]; (3 connected components) 2554a0ba757dSStefano Zampini tempbuffer (row-oriented) should be filled as: 2555a0ba757dSStefano Zampini [ 0, 0, 0; 2556a0ba757dSStefano Zampini 0, 0, 1; 2557a0ba757dSStefano Zampini 1, 1, 2; 2558a0ba757dSStefano Zampini 1, 1, 2; 2559a0ba757dSStefano Zampini 0, 1, 0; ]; 2560a0ba757dSStefano Zampini This way we can simply recover the resulting structure account for possible intersections of ccs among neighs. 2561a0ba757dSStefano Zampini The mat_graph->where array will be modified to reproduce the following 4 connected components [0], [1], [2 3], [4]; 2562a0ba757dSStefano Zampini */ 2563a0ba757dSStefano Zampini for(j=0;j<cum_recv_counts[i+1]-cum_recv_counts[i];j++) { 2564a0ba757dSStefano Zampini ins_val=0; 2565a0ba757dSStefano Zampini size_of_recv=recv_buffer_where[sum_requests]; /* total size of recv from neighs */ 2566a0ba757dSStefano Zampini for(buffer_size=0;buffer_size<size_of_recv;) { /* loop until all data from neighs has been taken into account */ 2567a0ba757dSStefano Zampini for(k=1;k<petsc_buffer[buffer_size+start_of_recv]+1;k++) { /* filling properly temp_buffer using data from a single recv */ 2568a0ba757dSStefano Zampini temp_buffer[ nodes_to_temp_buffer_indices[ petsc_buffer[ start_of_recv+buffer_size+k ] ] ][j]=ins_val; 2569a0ba757dSStefano Zampini } 2570a0ba757dSStefano Zampini buffer_size+=k; 2571a0ba757dSStefano Zampini ins_val++; 2572a0ba757dSStefano Zampini } 2573a0ba757dSStefano Zampini start_of_recv+=size_of_recv; 2574a0ba757dSStefano Zampini sum_requests++; 2575a0ba757dSStefano Zampini } 2576a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*sizeof(PetscInt),&add_to_where);CHKERRQ(ierr); 2577a0ba757dSStefano Zampini ierr = PetscMemzero(add_to_where,temp_buffer_size*sizeof(PetscInt));CHKERRQ(ierr); 2578a0ba757dSStefano Zampini for(j=0;j<temp_buffer_size;j++){ 2579a0ba757dSStefano Zampini if(!add_to_where[j]){ /* found a new cc */ 2580a0ba757dSStefano Zampini global_where_counter++; 2581a0ba757dSStefano Zampini add_to_where[j]=global_where_counter; 2582a0ba757dSStefano Zampini for(k=j+1;k<temp_buffer_size;k++){ /* check for other nodes in new cc */ 2583a0ba757dSStefano Zampini same_set=PETSC_TRUE; 2584a0ba757dSStefano Zampini for(s=0;s<cum_recv_counts[i+1]-cum_recv_counts[i];s++){ 2585a0ba757dSStefano Zampini if(temp_buffer[j][s]!=temp_buffer[k][s]) { 2586a0ba757dSStefano Zampini same_set=PETSC_FALSE; 2587a0ba757dSStefano Zampini break; 2588a0ba757dSStefano Zampini } 2589a0ba757dSStefano Zampini } 2590a0ba757dSStefano Zampini if(same_set) add_to_where[k]=global_where_counter; 2591a0ba757dSStefano Zampini } 2592a0ba757dSStefano Zampini } 2593a0ba757dSStefano Zampini } 2594a0ba757dSStefano Zampini /* insert new data in where array */ 2595a0ba757dSStefano Zampini temp_buffer_size=0; 2596a0ba757dSStefano Zampini for(j=0;j<mat_graph->nvtxs;j++){ 2597a0ba757dSStefano Zampini if(mat_graph->where[j]==i+1) { 2598a0ba757dSStefano Zampini mat_graph->where[j]=where_values+add_to_where[temp_buffer_size]; 2599a0ba757dSStefano Zampini temp_buffer_size++; 2600a0ba757dSStefano Zampini } 2601a0ba757dSStefano Zampini } 2602a0ba757dSStefano Zampini ierr = PetscFree(temp_buffer[0]);CHKERRQ(ierr); 2603a0ba757dSStefano Zampini ierr = PetscFree(temp_buffer);CHKERRQ(ierr); 2604a0ba757dSStefano Zampini ierr = PetscFree(add_to_where);CHKERRQ(ierr); 2605a0ba757dSStefano Zampini } 2606a0ba757dSStefano Zampini } 2607a0ba757dSStefano Zampini ierr = PetscFree(nodes_to_temp_buffer_indices);CHKERRQ(ierr); 2608a0ba757dSStefano Zampini ierr = PetscFree(sizes_of_sends);CHKERRQ(ierr); 2609a0ba757dSStefano Zampini ierr = PetscFree(send_requests);CHKERRQ(ierr); 2610a0ba757dSStefano Zampini ierr = PetscFree(recv_requests);CHKERRQ(ierr); 2611a0ba757dSStefano Zampini ierr = PetscFree(petsc_buffer);CHKERRQ(ierr); 2612a0ba757dSStefano Zampini ierr = PetscFree(recv_buffer);CHKERRQ(ierr); 2613a0ba757dSStefano Zampini ierr = PetscFree(recv_buffer_where);CHKERRQ(ierr); 2614a0ba757dSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 2615a0ba757dSStefano Zampini ierr = PetscFree(cum_recv_counts);CHKERRQ(ierr); 2616a0ba757dSStefano Zampini ierr = PetscFree(where_to_nodes_indices);CHKERRQ(ierr); 2617a0ba757dSStefano Zampini /* We are ready to evaluate consistent connected components on each part of the shared interface */ 2618a0ba757dSStefano Zampini if(global_where_counter) { 2619a0ba757dSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){ mat_graph->touched[i]=PETSC_FALSE; } 2620a0ba757dSStefano Zampini global_where_counter=0; 2621a0ba757dSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){ 2622a0ba757dSStefano Zampini if(mat_graph->where[i] && !mat_graph->touched[i]) { 2623a0ba757dSStefano Zampini global_where_counter++; 2624a0ba757dSStefano Zampini for(j=i+1;j<mat_graph->nvtxs;j++){ 2625a0ba757dSStefano Zampini if(!mat_graph->touched[j] && mat_graph->where[j]==mat_graph->where[i]) { 2626a0ba757dSStefano Zampini mat_graph->where[j]=global_where_counter; 2627a0ba757dSStefano Zampini mat_graph->touched[j]=PETSC_TRUE; 2628a0ba757dSStefano Zampini } 2629a0ba757dSStefano Zampini } 2630a0ba757dSStefano Zampini mat_graph->where[i]=global_where_counter; 2631a0ba757dSStefano Zampini mat_graph->touched[i]=PETSC_TRUE; 2632a0ba757dSStefano Zampini } 2633a0ba757dSStefano Zampini } 2634a0ba757dSStefano Zampini where_values=global_where_counter; 2635a0ba757dSStefano Zampini } 2636a0ba757dSStefano Zampini if(global_where_counter) { 2637a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->cptr,(mat_graph->nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 2638a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->queue,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2639a0ba757dSStefano Zampini ierr = PetscFree(mat_graph->where_ncmps);CHKERRQ(ierr); 2640a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscMPIInt),&mat_graph->where_ncmps);CHKERRQ(ierr); 2641a0ba757dSStefano Zampini ierr = PCBDDCFindConnectedComponents(mat_graph, where_values); 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 } 26470c7d97c5SJed Brown } 26480c7d97c5SJed Brown 2649a0ba757dSStefano Zampini /* count vertices, edges and faces */ 26500c7d97c5SJed Brown PetscInt nfc=0; 26510c7d97c5SJed Brown PetscInt nec=0; 26520c7d97c5SJed Brown PetscInt nvc=0; 26530c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 26540c7d97c5SJed Brown if( !pcbddc->vertices_flag ) { 26550c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > 1 ){ 26560c7d97c5SJed Brown if(mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]==2){ 26570c7d97c5SJed Brown nfc++; 26580c7d97c5SJed Brown } else { 26590c7d97c5SJed Brown nec++; 26600c7d97c5SJed Brown } 26610c7d97c5SJed Brown } 26620c7d97c5SJed Brown } 26630c7d97c5SJed Brown if( !pcbddc->constraints_flag ){ 26640c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] == 1 ){ 26650c7d97c5SJed Brown nvc++; 26660c7d97c5SJed Brown } 26670c7d97c5SJed Brown } 26680c7d97c5SJed Brown } 26690c7d97c5SJed Brown 26700c7d97c5SJed Brown pcbddc->n_constraints = nec+nfc; 26710c7d97c5SJed Brown pcbddc->n_vertices = nvc; 26720c7d97c5SJed Brown 26730c7d97c5SJed Brown if(pcbddc->n_constraints){ 26740c7d97c5SJed Brown /* allocate space for local constraints of BDDC */ 26750c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->n_constraints*sizeof(PetscInt*),&pcbddc->indices_to_constraint);CHKERRQ(ierr); 26760c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->n_constraints*sizeof(PetscScalar*),&pcbddc->quadrature_constraint);CHKERRQ(ierr); 26770c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->n_constraints*sizeof(PetscInt),&pcbddc->sizes_of_constraint);CHKERRQ(ierr); 26780c7d97c5SJed Brown k=0; 26790c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 26800c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > 1 ){ 26810c7d97c5SJed Brown pcbddc->sizes_of_constraint[k] = mat_graph->cptr[i+1]-mat_graph->cptr[i]; 26820c7d97c5SJed Brown k++; 26830c7d97c5SJed Brown } 26840c7d97c5SJed Brown } 26850c7d97c5SJed Brown k=0; 26860c7d97c5SJed Brown for (i=0; i<pcbddc->n_constraints; i++) k+=pcbddc->sizes_of_constraint[i]; 26870c7d97c5SJed Brown ierr = PetscMalloc (k*sizeof(PetscInt),&pcbddc->indices_to_constraint[0]);CHKERRQ(ierr); 26880c7d97c5SJed Brown ierr = PetscMalloc (k*sizeof(PetscScalar),&pcbddc->quadrature_constraint[0]);CHKERRQ(ierr); 26890c7d97c5SJed Brown for (i=1; i<pcbddc->n_constraints; i++) { 26900c7d97c5SJed Brown pcbddc->indices_to_constraint[i] = pcbddc->indices_to_constraint[i-1] + pcbddc->sizes_of_constraint[i-1]; 26910c7d97c5SJed Brown pcbddc->quadrature_constraint[i] = pcbddc->quadrature_constraint[i-1] + pcbddc->sizes_of_constraint[i-1]; 26920c7d97c5SJed Brown } 26930c7d97c5SJed Brown k=0; 26940c7d97c5SJed Brown PetscScalar quad_value; 26950c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 26960c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > 1 ){ 2697a0ba757dSStefano Zampini quad_value=1.0/( (PetscReal) (mat_graph->cptr[i+1]-mat_graph->cptr[i]) ); 26980c7d97c5SJed Brown for(j=0;j<mat_graph->cptr[i+1]-mat_graph->cptr[i];j++) { 26990c7d97c5SJed Brown pcbddc->indices_to_constraint[k][j] = mat_graph->queue[mat_graph->cptr[i]+j]; 27000c7d97c5SJed Brown pcbddc->quadrature_constraint[k][j] = quad_value; 27010c7d97c5SJed Brown } 27020c7d97c5SJed Brown k++; 27030c7d97c5SJed Brown } 27040c7d97c5SJed Brown } 27050c7d97c5SJed Brown } 27060c7d97c5SJed Brown if(pcbddc->n_vertices){ 27070c7d97c5SJed Brown /* allocate space for local vertices of BDDC */ 27080c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->n_vertices*sizeof(PetscInt),&pcbddc->vertices);CHKERRQ(ierr); 27090c7d97c5SJed Brown k=0; 27100c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 27110c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] == 1 ){ 27120c7d97c5SJed Brown pcbddc->vertices[k] = mat_graph->queue[mat_graph->cptr[i]]; 27130c7d97c5SJed Brown k++; 27140c7d97c5SJed Brown } 27150c7d97c5SJed Brown } 2716a0ba757dSStefano Zampini /* sort vertex set (by local ordering) */ 27170c7d97c5SJed Brown ierr = PetscSortInt(pcbddc->n_vertices,pcbddc->vertices);CHKERRQ(ierr); 27180c7d97c5SJed Brown } 27190c7d97c5SJed Brown 2720e269702eSStefano Zampini if(pcbddc->dbg_flag) { 2721e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 2722e269702eSStefano Zampini 2723d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2724d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Details from PCBDDCManageLocalBoundaries for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 2725d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2726a0ba757dSStefano Zampini /* ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Graph (adjacency structure) of local Neumann mat\n");CHKERRQ(ierr); 2727a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2728e269702eSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++) { 2729a0ba757dSStefano 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); 2730e269702eSStefano Zampini for(j=mat_graph->xadj[i];j<mat_graph->xadj[i+1];j++){ 2731a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d ",mat_graph->adjncy[j]);CHKERRQ(ierr); 2732e269702eSStefano Zampini } 2733a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n--------------------------------------------------------------\n");CHKERRQ(ierr); 2734a0ba757dSStefano Zampini }*/ 2735d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Matrix graph has %d connected components", mat_graph->ncmps);CHKERRQ(ierr); 27360c7d97c5SJed Brown for(i=0;i<mat_graph->ncmps;i++) { 2737d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\nSize and count for connected component %02d : %04d %01d\n", i,mat_graph->cptr[i+1]-mat_graph->cptr[i],mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]);CHKERRQ(ierr); 27380c7d97c5SJed Brown for (j=mat_graph->cptr[i]; j<mat_graph->cptr[i+1]; j++){ 27393828260eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d (%d), ",queue_in_global_numbering[j],mat_graph->queue[j]);CHKERRQ(ierr); 27400c7d97c5SJed Brown } 27410c7d97c5SJed Brown } 2742d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n--------------------------------------------------------------\n");CHKERRQ(ierr); 2743d49ef151SStefano Zampini if( pcbddc->n_vertices ) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local vertices\n",PetscGlobalRank,pcbddc->n_vertices);CHKERRQ(ierr); } 2744d49ef151SStefano Zampini if( nfc ) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local faces\n",PetscGlobalRank,nfc);CHKERRQ(ierr); } 2745d49ef151SStefano Zampini if( nec ) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local edges\n",PetscGlobalRank,nec);CHKERRQ(ierr); } 2746a0ba757dSStefano Zampini if( pcbddc->n_vertices ) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Global indices for subdomain vertices follows\n",PetscGlobalRank,pcbddc->n_vertices);CHKERRQ(ierr); } 27473828260eSStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,pcbddc->n_vertices,pcbddc->vertices,queue_in_global_numbering);CHKERRQ(ierr); 27483828260eSStefano Zampini for(i=0;i<pcbddc->n_vertices;i++){ ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d ",queue_in_global_numbering[i]);CHKERRQ(ierr); } 2749d49ef151SStefano Zampini if( pcbddc->n_vertices ) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); } 2750d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 27510c7d97c5SJed Brown } 27520c7d97c5SJed Brown 2753a0ba757dSStefano Zampini /* Restore CSR structure into sequantial matrix and free memory space no longer needed */ 2754a0ba757dSStefano Zampini ierr = MatRestoreRowIJ(mat_adj,0,symmetrize_rowij,compressed_rowij,&mat_graph->nvtxs,&mat_graph->xadj,&mat_graph->adjncy,&flg_row);CHKERRQ(ierr); 27550c7d97c5SJed Brown if(!flg_row) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called from PCBDDCManageLocalBoundaries.\n"); 2756a0ba757dSStefano Zampini ierr = MatDestroy(&mat_adj);CHKERRQ(ierr); 2757a0ba757dSStefano Zampini /* Free graph structure */ 27580c7d97c5SJed Brown if(mat_graph->nvtxs){ 2759a0ba757dSStefano Zampini ierr = PetscFree(neighbours_set[0]);CHKERRQ(ierr); 2760a0ba757dSStefano Zampini ierr = PetscFree(neighbours_set);CHKERRQ(ierr); 2761a0ba757dSStefano Zampini ierr = PetscFree4(mat_graph->where,mat_graph->count,mat_graph->cptr,mat_graph->queue);CHKERRQ(ierr); 2762a0ba757dSStefano Zampini ierr = PetscFree3(mat_graph->which_dof,mat_graph->touched,queue_in_global_numbering);CHKERRQ(ierr); 2763a0ba757dSStefano Zampini ierr = PetscFree(mat_graph->where_ncmps);CHKERRQ(ierr); 27640c7d97c5SJed Brown } 27650c7d97c5SJed Brown ierr = PetscFree(mat_graph);CHKERRQ(ierr); 27660c7d97c5SJed Brown 27670c7d97c5SJed Brown PetscFunctionReturn(0); 27680c7d97c5SJed Brown 27690c7d97c5SJed Brown } 27700c7d97c5SJed Brown 27710c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 27720c7d97c5SJed Brown 27730c7d97c5SJed Brown /* The following code has been adapted from function IsConnectedSubdomain contained 27740c7d97c5SJed Brown in source file contig.c of METIS library (version 5.0.1) */ 27750c7d97c5SJed Brown 27760c7d97c5SJed Brown #undef __FUNCT__ 27770c7d97c5SJed Brown #define __FUNCT__ "PCBDDCFindConnectedComponents" 2778*9c0446d6SStefano Zampini static PetscErrorCode PCBDDCFindConnectedComponents(PCBDDCGraph graph, PetscInt n_dist ) 27790c7d97c5SJed Brown { 27800c7d97c5SJed Brown PetscInt i, j, k, nvtxs, first, last, nleft, ncmps,pid,cum_queue,n,ncmps_pid; 27810c7d97c5SJed Brown PetscInt *xadj, *adjncy, *where, *queue; 27820c7d97c5SJed Brown PetscInt *cptr; 27830c7d97c5SJed Brown PetscBool *touched; 27840c7d97c5SJed Brown 27850c7d97c5SJed Brown PetscFunctionBegin; 27860c7d97c5SJed Brown 27870c7d97c5SJed Brown nvtxs = graph->nvtxs; 27880c7d97c5SJed Brown xadj = graph->xadj; 27890c7d97c5SJed Brown adjncy = graph->adjncy; 27900c7d97c5SJed Brown where = graph->where; 27910c7d97c5SJed Brown touched = graph->touched; 27920c7d97c5SJed Brown queue = graph->queue; 27930c7d97c5SJed Brown cptr = graph->cptr; 27940c7d97c5SJed Brown 27950c7d97c5SJed Brown for (i=0; i<nvtxs; i++) 27960c7d97c5SJed Brown touched[i] = PETSC_FALSE; 27970c7d97c5SJed Brown 27980c7d97c5SJed Brown cum_queue=0; 27990c7d97c5SJed Brown ncmps=0; 28000c7d97c5SJed Brown 28010c7d97c5SJed Brown for(n=0; n<n_dist; n++) { 2802a0ba757dSStefano Zampini //pid = dist_vals[n]; 2803a0ba757dSStefano Zampini pid = n+1; 28040c7d97c5SJed Brown nleft = 0; 28050c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 28060c7d97c5SJed Brown if (where[i] == pid) 28070c7d97c5SJed Brown nleft++; 28080c7d97c5SJed Brown } 28090c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 28100c7d97c5SJed Brown if (where[i] == pid) 28110c7d97c5SJed Brown break; 28120c7d97c5SJed Brown } 28130c7d97c5SJed Brown touched[i] = PETSC_TRUE; 28140c7d97c5SJed Brown queue[cum_queue] = i; 28150c7d97c5SJed Brown first = 0; last = 1; 28160c7d97c5SJed Brown cptr[ncmps] = cum_queue; /* This actually points to queue */ 28170c7d97c5SJed Brown ncmps_pid = 0; 28180c7d97c5SJed Brown while (first != nleft) { 28190c7d97c5SJed Brown if (first == last) { /* Find another starting vertex */ 28200c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 28210c7d97c5SJed Brown ncmps_pid++; 28220c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 28230c7d97c5SJed Brown if (where[i] == pid && !touched[i]) 28240c7d97c5SJed Brown break; 28250c7d97c5SJed Brown } 28260c7d97c5SJed Brown queue[cum_queue+last] = i; 28270c7d97c5SJed Brown last++; 28280c7d97c5SJed Brown touched[i] = PETSC_TRUE; 28290c7d97c5SJed Brown } 28300c7d97c5SJed Brown i = queue[cum_queue+first]; 28310c7d97c5SJed Brown first++; 28320c7d97c5SJed Brown for (j=xadj[i]; j<xadj[i+1]; j++) { 28330c7d97c5SJed Brown k = adjncy[j]; 28340c7d97c5SJed Brown if (where[k] == pid && !touched[k]) { 28350c7d97c5SJed Brown queue[cum_queue+last] = k; 28360c7d97c5SJed Brown last++; 28370c7d97c5SJed Brown touched[k] = PETSC_TRUE; 28380c7d97c5SJed Brown } 28390c7d97c5SJed Brown } 28400c7d97c5SJed Brown } 28410c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 28420c7d97c5SJed Brown ncmps_pid++; 28430c7d97c5SJed Brown cum_queue=cptr[ncmps]; 2844a0ba757dSStefano Zampini graph->where_ncmps[n] = ncmps_pid; 28450c7d97c5SJed Brown } 28460c7d97c5SJed Brown graph->ncmps = ncmps; 28470c7d97c5SJed Brown 28480c7d97c5SJed Brown PetscFunctionReturn(0); 28490c7d97c5SJed Brown } 28500c7d97c5SJed Brown 2851