153cdbc3dSStefano Zampini /* TODOLIST 2d11ae9bbSstefano_zampini DofSplitting and DM attached to pc. 33b03a366Sstefano_zampini Exact solvers: Solve local saddle point directly for very hard problems 43b03a366Sstefano_zampini Inexact solvers: global preconditioner application is ready, ask to developers (Jed?) on how to best implement Dohrmann's approach (PCSHELL?) 5a0ba757dSStefano Zampini change how to deal with the coarse problem (PCBDDCSetCoarseEnvironment): 6a0ba757dSStefano Zampini - mind the problem with coarsening_factor 7a0ba757dSStefano Zampini - simplify coarse problem structure -> PCBDDC or PCREDUDANT, nothing else -> same comm for all levels? 8a0ba757dSStefano Zampini - remove coarse enums and allow use of PCBDDCGetCoarseKSP 9a0ba757dSStefano Zampini - remove metis dependency -> use MatPartitioning for multilevel -> Assemble serial adjacency in ManageLocalBoundaries? 103b03a366Sstefano_zampini - Add levels' slot to bddc data structure and associated Set/Get functions 11a0ba757dSStefano Zampini code refactoring: 12a0ba757dSStefano Zampini - pick up better names for static functions 133b03a366Sstefano_zampini check log_summary for leaking (actually: 1 Vector per level ) 14a0ba757dSStefano Zampini change options structure: 15a0ba757dSStefano Zampini - insert BDDC into MG framework? 16a0ba757dSStefano Zampini provide other ops? Ask to developers 17a0ba757dSStefano Zampini remove all unused printf 18a0ba757dSStefano Zampini remove // commments and adhere to PETSc code requirements 19a0ba757dSStefano Zampini man pages 2053cdbc3dSStefano Zampini */ 210c7d97c5SJed Brown 2253cdbc3dSStefano Zampini /* ---------------------------------------------------------------------------------------------------------------------------------------------- 230c7d97c5SJed Brown Implementation of BDDC preconditioner based on: 240c7d97c5SJed Brown C. Dohrmann "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 2553cdbc3dSStefano Zampini ---------------------------------------------------------------------------------------------------------------------------------------------- */ 2653cdbc3dSStefano Zampini 2753cdbc3dSStefano Zampini #include "bddc.h" /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 283b03a366Sstefano_zampini #include <petscblaslapack.h> 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 /*@ 759c0446d6SStefano Zampini PCBDDCSetCoarseProblemType - Set coarse problem type in PCBDDC. 7653cdbc3dSStefano Zampini 779c0446d6SStefano 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: 869c0446d6SStefano 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__ 1033b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC" 1043b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 1053b03a366Sstefano_zampini { 1063b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1073b03a366Sstefano_zampini PetscErrorCode ierr; 1083b03a366Sstefano_zampini 1093b03a366Sstefano_zampini PetscFunctionBegin; 1103b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 1113b03a366Sstefano_zampini ierr = ISDuplicate(DirichletBoundaries,&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 1123b03a366Sstefano_zampini ierr = ISCopy(DirichletBoundaries,pcbddc->DirichletBoundaries);CHKERRQ(ierr); 1133b03a366Sstefano_zampini PetscFunctionReturn(0); 1143b03a366Sstefano_zampini } 1153b03a366Sstefano_zampini EXTERN_C_END 1163b03a366Sstefano_zampini 1173b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 1183b03a366Sstefano_zampini #undef __FUNCT__ 1193b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries" 1203b03a366Sstefano_zampini /*@ 1213b03a366Sstefano_zampini PCBDDCSetDirichletBoundaries - Set index set defining subdomain part of 1223b03a366Sstefano_zampini Dirichlet boundaries for the global problem. 1233b03a366Sstefano_zampini 1243b03a366Sstefano_zampini Not collective 1253b03a366Sstefano_zampini 1263b03a366Sstefano_zampini Input Parameters: 1273b03a366Sstefano_zampini + pc - the preconditioning context 1283b03a366Sstefano_zampini - DirichletBoundaries - sequential index set defining the subdomain part of Dirichlet boundaries (can be PETSC_NULL) 1293b03a366Sstefano_zampini 1303b03a366Sstefano_zampini Level: intermediate 1313b03a366Sstefano_zampini 1323b03a366Sstefano_zampini Notes: 1333b03a366Sstefano_zampini The sequential IS is copied; the user must destroy the IS object passed in. 1343b03a366Sstefano_zampini 1353b03a366Sstefano_zampini .seealso: PCBDDC 1363b03a366Sstefano_zampini @*/ 1373b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 1383b03a366Sstefano_zampini { 1393b03a366Sstefano_zampini PetscErrorCode ierr; 1403b03a366Sstefano_zampini 1413b03a366Sstefano_zampini PetscFunctionBegin; 1423b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1433b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 1443b03a366Sstefano_zampini PetscFunctionReturn(0); 1453b03a366Sstefano_zampini } 1463b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 1473b03a366Sstefano_zampini EXTERN_C_BEGIN 1483b03a366Sstefano_zampini #undef __FUNCT__ 1490c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 15053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 1510c7d97c5SJed Brown { 1520c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15353cdbc3dSStefano Zampini PetscErrorCode ierr; 1540c7d97c5SJed Brown 1550c7d97c5SJed Brown PetscFunctionBegin; 15653cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 15753cdbc3dSStefano Zampini ierr = ISDuplicate(NeumannBoundaries,&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 15853cdbc3dSStefano Zampini ierr = ISCopy(NeumannBoundaries,pcbddc->NeumannBoundaries);CHKERRQ(ierr); 1590c7d97c5SJed Brown PetscFunctionReturn(0); 1600c7d97c5SJed Brown } 1610c7d97c5SJed Brown EXTERN_C_END 1620c7d97c5SJed Brown 1630c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1640c7d97c5SJed Brown #undef __FUNCT__ 1650c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 16657527edcSJed Brown /*@ 16753cdbc3dSStefano Zampini PCBDDCSetNeumannBoundaries - Set index set defining subdomain part of 16853cdbc3dSStefano Zampini Neumann boundaries for the global problem. 16957527edcSJed Brown 1709c0446d6SStefano Zampini Not collective 17157527edcSJed Brown 17257527edcSJed Brown Input Parameters: 17357527edcSJed Brown + pc - the preconditioning context 1749c0446d6SStefano Zampini - NeumannBoundaries - sequential index set defining the subdomain part of Neumann boundaries (can be PETSC_NULL) 17557527edcSJed Brown 17657527edcSJed Brown Level: intermediate 17757527edcSJed Brown 17857527edcSJed Brown Notes: 1799c0446d6SStefano Zampini The sequential IS is copied; the user must destroy the IS object passed in. 18057527edcSJed Brown 18157527edcSJed Brown .seealso: PCBDDC 18257527edcSJed Brown @*/ 18353cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 1840c7d97c5SJed Brown { 1850c7d97c5SJed Brown PetscErrorCode ierr; 1860c7d97c5SJed Brown 1870c7d97c5SJed Brown PetscFunctionBegin; 1880c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 18953cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 19053cdbc3dSStefano Zampini PetscFunctionReturn(0); 19153cdbc3dSStefano Zampini } 19253cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 19353cdbc3dSStefano Zampini EXTERN_C_BEGIN 19453cdbc3dSStefano Zampini #undef __FUNCT__ 19553cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 19653cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 19753cdbc3dSStefano Zampini { 19853cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 19953cdbc3dSStefano Zampini 20053cdbc3dSStefano Zampini PetscFunctionBegin; 20153cdbc3dSStefano Zampini if(pcbddc->NeumannBoundaries) { 20253cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 20353cdbc3dSStefano Zampini } else { 2049c0446d6SStefano Zampini *NeumannBoundaries = PETSC_NULL; 2059c0446d6SStefano Zampini //SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Error in %s: Neumann boundaries not set!.\n",__FUNCT__); 20653cdbc3dSStefano Zampini } 20753cdbc3dSStefano Zampini PetscFunctionReturn(0); 20853cdbc3dSStefano Zampini } 20953cdbc3dSStefano Zampini EXTERN_C_END 21053cdbc3dSStefano Zampini 21153cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 21253cdbc3dSStefano Zampini #undef __FUNCT__ 21353cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 21453cdbc3dSStefano Zampini /*@ 21553cdbc3dSStefano Zampini PCBDDCGetNeumannBoundaries - Get index set defining subdomain part of 21653cdbc3dSStefano Zampini Neumann boundaries for the global problem. 21753cdbc3dSStefano Zampini 2189c0446d6SStefano Zampini Not collective 21953cdbc3dSStefano Zampini 22053cdbc3dSStefano Zampini Input Parameters: 22153cdbc3dSStefano Zampini + pc - the preconditioning context 22253cdbc3dSStefano Zampini 22353cdbc3dSStefano Zampini Output Parameters: 22453cdbc3dSStefano Zampini + NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 22553cdbc3dSStefano Zampini 22653cdbc3dSStefano Zampini Level: intermediate 22753cdbc3dSStefano Zampini 22853cdbc3dSStefano Zampini Notes: 2299c0446d6SStefano Zampini If the user has not yet provided such information, PETSC_NULL is returned. 23053cdbc3dSStefano Zampini 23153cdbc3dSStefano Zampini .seealso: PCBDDC 23253cdbc3dSStefano Zampini @*/ 23353cdbc3dSStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 23453cdbc3dSStefano Zampini { 23553cdbc3dSStefano Zampini PetscErrorCode ierr; 23653cdbc3dSStefano Zampini 23753cdbc3dSStefano Zampini PetscFunctionBegin; 23853cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 23953cdbc3dSStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 2400c7d97c5SJed Brown PetscFunctionReturn(0); 2410c7d97c5SJed Brown } 2420c7d97c5SJed Brown 2439c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 2449c0446d6SStefano Zampini EXTERN_C_BEGIN 2459c0446d6SStefano Zampini #undef __FUNCT__ 2469c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 2479c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 2489c0446d6SStefano Zampini { 2499c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2509c0446d6SStefano Zampini PetscInt i; 2519c0446d6SStefano Zampini PetscErrorCode ierr; 2529c0446d6SStefano Zampini 2539c0446d6SStefano Zampini PetscFunctionBegin; 254d11ae9bbSstefano_zampini /* Destroy ISs if they were already set */ 2559c0446d6SStefano Zampini for(i=0;i<pcbddc->n_ISForDofs;i++) { 2569c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 2579c0446d6SStefano Zampini } 258d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 259d11ae9bbSstefano_zampini 2609c0446d6SStefano Zampini /* allocate space then copy ISs */ 2619c0446d6SStefano Zampini ierr = PetscMalloc(n_is*sizeof(IS),&pcbddc->ISForDofs);CHKERRQ(ierr); 2629c0446d6SStefano Zampini for(i=0;i<n_is;i++) { 2639c0446d6SStefano Zampini ierr = ISDuplicate(ISForDofs[i],&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 2649c0446d6SStefano Zampini ierr = ISCopy(ISForDofs[i],pcbddc->ISForDofs[i]);CHKERRQ(ierr); 2659c0446d6SStefano Zampini } 2669c0446d6SStefano Zampini pcbddc->n_ISForDofs=n_is; 267d11ae9bbSstefano_zampini 2689c0446d6SStefano Zampini PetscFunctionReturn(0); 2699c0446d6SStefano Zampini } 2709c0446d6SStefano Zampini EXTERN_C_END 2719c0446d6SStefano Zampini 2729c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 2739c0446d6SStefano Zampini #undef __FUNCT__ 2749c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 2759c0446d6SStefano Zampini /*@ 2769c0446d6SStefano Zampini PCBDDCSetDofsSplitting - Set index set defining how dofs are splitted. 2779c0446d6SStefano Zampini 2789c0446d6SStefano Zampini Not collective 2799c0446d6SStefano Zampini 2809c0446d6SStefano Zampini Input Parameters: 2819c0446d6SStefano Zampini + pc - the preconditioning context 2829c0446d6SStefano Zampini - n - number of index sets defining dofs spltting 2839c0446d6SStefano Zampini - IS[] - array of IS describing dofs splitting 2849c0446d6SStefano Zampini 2859c0446d6SStefano Zampini Level: intermediate 2869c0446d6SStefano Zampini 2879c0446d6SStefano Zampini Notes: 2889c0446d6SStefano Zampini Sequential ISs are copied, the user must destroy the array of IS passed in. 2899c0446d6SStefano Zampini 2909c0446d6SStefano Zampini .seealso: PCBDDC 2919c0446d6SStefano Zampini @*/ 2929c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 2939c0446d6SStefano Zampini { 2949c0446d6SStefano Zampini PetscErrorCode ierr; 2959c0446d6SStefano Zampini 2969c0446d6SStefano Zampini PetscFunctionBegin; 2979c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2989c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 2999c0446d6SStefano Zampini PetscFunctionReturn(0); 3009c0446d6SStefano Zampini } 3019c0446d6SStefano Zampini 30253cdbc3dSStefano Zampini #undef __FUNCT__ 30353cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 3040c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 3050c7d97c5SJed Brown /* 3060c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 3070c7d97c5SJed Brown by setting data structures and options. 3080c7d97c5SJed Brown 3090c7d97c5SJed Brown Input Parameter: 31053cdbc3dSStefano Zampini + pc - the preconditioner context 3110c7d97c5SJed Brown 3120c7d97c5SJed Brown Application Interface Routine: PCSetUp() 3130c7d97c5SJed Brown 3140c7d97c5SJed Brown Notes: 3150c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 3160c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 3170c7d97c5SJed Brown */ 31853cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 3190c7d97c5SJed Brown { 3200c7d97c5SJed Brown PetscErrorCode ierr; 3210c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3220c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 3230c7d97c5SJed Brown 3240c7d97c5SJed Brown PetscFunctionBegin; 3250c7d97c5SJed Brown if (!pc->setupcalled) { 3263b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 3279c0446d6SStefano Zampini So, we set to pcnone the Neumann problem of pcis in order to avoid unneeded computation 3280c7d97c5SJed Brown Also, we decide to directly build the (same) Dirichlet problem */ 3290c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localN_pc_type","none");CHKERRQ(ierr); 3300c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localD_pc_type","none");CHKERRQ(ierr); 3310c7d97c5SJed Brown /* Set up all the "iterative substructuring" common block */ 3320c7d97c5SJed Brown ierr = PCISSetUp(pc);CHKERRQ(ierr); 3333b03a366Sstefano_zampini /* Get stdout for dbg */ 334e269702eSStefano Zampini if(pcbddc->dbg_flag) { 335e269702eSStefano Zampini ierr = PetscViewerASCIIGetStdout(((PetscObject)pc)->comm,&pcbddc->dbg_viewer);CHKERRQ(ierr); 336e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 337e269702eSStefano Zampini } 3383b03a366Sstefano_zampini /* TODO MOVE CODE FRAGMENT */ 3390c7d97c5SJed Brown PetscInt im_active=0; 3400c7d97c5SJed Brown if(pcis->n) im_active = 1; 34153cdbc3dSStefano Zampini ierr = MPI_Allreduce(&im_active,&pcbddc->active_procs,1,MPIU_INT,MPI_SUM,((PetscObject)pc)->comm);CHKERRQ(ierr); 3423b03a366Sstefano_zampini /* Analyze local interface */ 3430c7d97c5SJed Brown ierr = PCBDDCManageLocalBoundaries(pc);CHKERRQ(ierr); 3443b03a366Sstefano_zampini /* Set up local constraint matrix */ 3453b03a366Sstefano_zampini ierr = PCBDDCCreateConstraintMatrix(pc);CHKERRQ(ierr); 3460c7d97c5SJed Brown /* Create coarse and local stuffs used for evaluating action of preconditioner */ 3470c7d97c5SJed Brown ierr = PCBDDCCoarseSetUp(pc);CHKERRQ(ierr); 3483b03a366Sstefano_zampini /* Processes fakely involved in multilevel should not call ISLocalToGlobalMappingRestoreInfo */ 3493b03a366Sstefano_zampini if ( !pcis->n_neigh ) pcis->ISLocalToGlobalMappingGetInfoWasCalled=PETSC_FALSE; 3500c7d97c5SJed Brown } 3510c7d97c5SJed Brown PetscFunctionReturn(0); 3520c7d97c5SJed Brown } 3530c7d97c5SJed Brown 3540c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 3550c7d97c5SJed Brown /* 3560c7d97c5SJed Brown PCApply_BDDC - Applies the BDDC preconditioner to a vector. 3570c7d97c5SJed Brown 3580c7d97c5SJed Brown Input Parameters: 3590c7d97c5SJed Brown . pc - the preconditioner context 3600c7d97c5SJed Brown . r - input vector (global) 3610c7d97c5SJed Brown 3620c7d97c5SJed Brown Output Parameter: 3630c7d97c5SJed Brown . z - output vector (global) 3640c7d97c5SJed Brown 3650c7d97c5SJed Brown Application Interface Routine: PCApply() 3660c7d97c5SJed Brown */ 3670c7d97c5SJed Brown #undef __FUNCT__ 3680c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 36953cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 3700c7d97c5SJed Brown { 3710c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 3720c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 3730c7d97c5SJed Brown PetscErrorCode ierr; 3743b03a366Sstefano_zampini const PetscScalar one = 1.0; 3753b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 3760c7d97c5SJed Brown 3770c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 3780c7d97c5SJed Brown NN interface preconditioner changed to BDDC 3790c7d97c5SJed Brown Added support for M_3 preconditioenr in the reference article (code is active if pcbddc->prec_type = PETSC_TRUE) */ 3800c7d97c5SJed Brown 3810c7d97c5SJed Brown PetscFunctionBegin; 3820c7d97c5SJed Brown /* First Dirichlet solve */ 3830c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3840c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 38553cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 3860c7d97c5SJed Brown /* 3870c7d97c5SJed Brown Assembling right hand side for BDDC operator 3880c7d97c5SJed Brown - vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE) 3890c7d97c5SJed Brown - the interface part of the global vector z 3900c7d97c5SJed Brown */ 3910c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 3920c7d97c5SJed Brown ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 3930c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3940c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 3950c7d97c5SJed Brown ierr = VecCopy(r,z);CHKERRQ(ierr); 3960c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3970c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3980c7d97c5SJed Brown 3990c7d97c5SJed Brown /* 4000c7d97c5SJed Brown Apply interface preconditioner 4010c7d97c5SJed Brown Results are stored in: 4020c7d97c5SJed Brown - vec1_D (if needed, i.e. with prec_type = PETSC_TRUE) 4030c7d97c5SJed Brown - the interface part of the global vector z 4040c7d97c5SJed Brown */ 4050c7d97c5SJed Brown ierr = PCBDDCApplyInterfacePreconditioner(pc,z);CHKERRQ(ierr); 4060c7d97c5SJed Brown 4073b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 4080c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4090c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4100c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 4110c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 41253cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr); 4130c7d97c5SJed Brown ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr); 4140c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); } 4150c7d97c5SJed Brown ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr); 4160c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4170c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4180c7d97c5SJed Brown 4190c7d97c5SJed Brown PetscFunctionReturn(0); 4200c7d97c5SJed Brown 4210c7d97c5SJed Brown } 4220c7d97c5SJed Brown 4230c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 4240c7d97c5SJed Brown /* 4250c7d97c5SJed Brown PCBDDCApplyInterfacePreconditioner - Apply the BDDC preconditioner at the interface. 4260c7d97c5SJed Brown 4270c7d97c5SJed Brown */ 4280c7d97c5SJed Brown #undef __FUNCT__ 4290c7d97c5SJed Brown #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 43053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, Vec z) 4310c7d97c5SJed Brown { 4320c7d97c5SJed Brown PetscErrorCode ierr; 4330c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4340c7d97c5SJed Brown PC_IS* pcis = (PC_IS*) (pc->data); 4353b03a366Sstefano_zampini const PetscScalar zero = 0.0; 4360c7d97c5SJed Brown 4370c7d97c5SJed Brown PetscFunctionBegin; 4380c7d97c5SJed Brown /* Get Local boundary and apply partition of unity */ 4390c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4400c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4410c7d97c5SJed Brown ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 4420c7d97c5SJed Brown 4430c7d97c5SJed Brown /* Application of PHI^T */ 4440c7d97c5SJed Brown ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 4450c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 4460c7d97c5SJed Brown 4470c7d97c5SJed Brown /* Scatter data of coarse_rhs */ 4480c7d97c5SJed Brown if(pcbddc->coarse_rhs) ierr = VecSet(pcbddc->coarse_rhs,zero);CHKERRQ(ierr); 4490c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4500c7d97c5SJed Brown 4510c7d97c5SJed Brown /* Local solution on R nodes */ 4520c7d97c5SJed Brown ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 4530c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4540c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4550c7d97c5SJed Brown if(pcbddc->prec_type) { 4560c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4570c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4580c7d97c5SJed Brown } 4590c7d97c5SJed Brown ierr = PCBDDCSolveSaddlePoint(pc);CHKERRQ(ierr); 4600c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 4610c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4620c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4630c7d97c5SJed Brown if(pcbddc->prec_type) { 4640c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4650c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4660c7d97c5SJed Brown } 4670c7d97c5SJed Brown 4680c7d97c5SJed Brown /* Coarse solution */ 4690c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 47053cdbc3dSStefano Zampini if(pcbddc->coarse_rhs) ierr = KSPSolve(pcbddc->coarse_ksp,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 4710c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4720c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd (pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4730c7d97c5SJed Brown 4740c7d97c5SJed Brown /* Sum contributions from two levels */ 4750c7d97c5SJed Brown /* Apply partition of unity and sum boundary values */ 4760c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 4770c7d97c5SJed Brown ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 4780c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 4790c7d97c5SJed Brown ierr = VecSet(z,zero);CHKERRQ(ierr); 4800c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4810c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4820c7d97c5SJed Brown 4830c7d97c5SJed Brown PetscFunctionReturn(0); 4840c7d97c5SJed Brown } 4850c7d97c5SJed Brown 4860c7d97c5SJed Brown 4870c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 4880c7d97c5SJed Brown /* 4890c7d97c5SJed Brown PCBDDCSolveSaddlePoint 4900c7d97c5SJed Brown 4910c7d97c5SJed Brown */ 4920c7d97c5SJed Brown #undef __FUNCT__ 4930c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSolveSaddlePoint" 49453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSolveSaddlePoint(PC pc) 4950c7d97c5SJed Brown { 4960c7d97c5SJed Brown PetscErrorCode ierr; 4970c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4980c7d97c5SJed Brown 4990c7d97c5SJed Brown PetscFunctionBegin; 5000c7d97c5SJed Brown 50153cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 5020c7d97c5SJed Brown if(pcbddc->n_constraints) { 5030c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec2_R,pcbddc->vec1_C);CHKERRQ(ierr); 5040c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 5050c7d97c5SJed Brown } 5060c7d97c5SJed Brown 5070c7d97c5SJed Brown PetscFunctionReturn(0); 5080c7d97c5SJed Brown } 5090c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 5100c7d97c5SJed Brown /* 5110c7d97c5SJed Brown PCBDDCScatterCoarseDataBegin 5120c7d97c5SJed Brown 5130c7d97c5SJed Brown */ 5140c7d97c5SJed Brown #undef __FUNCT__ 5150c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 51653cdbc3dSStefano Zampini static PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,Vec vec_from, Vec vec_to, InsertMode imode, ScatterMode smode) 5170c7d97c5SJed Brown { 5180c7d97c5SJed Brown PetscErrorCode ierr; 5190c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5200c7d97c5SJed Brown 5210c7d97c5SJed Brown PetscFunctionBegin; 5220c7d97c5SJed Brown 5230c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 5240c7d97c5SJed Brown case SCATTERS_BDDC: 5250c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 5260c7d97c5SJed Brown break; 5270c7d97c5SJed Brown case GATHERS_BDDC: 5280c7d97c5SJed Brown break; 5290c7d97c5SJed Brown } 5300c7d97c5SJed Brown PetscFunctionReturn(0); 5310c7d97c5SJed Brown 5320c7d97c5SJed Brown } 5330c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 5340c7d97c5SJed Brown /* 5350c7d97c5SJed Brown PCBDDCScatterCoarseDataEnd 5360c7d97c5SJed Brown 5370c7d97c5SJed Brown */ 5380c7d97c5SJed Brown #undef __FUNCT__ 5390c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 54053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc,Vec vec_from, Vec vec_to, InsertMode imode, ScatterMode smode) 5410c7d97c5SJed Brown { 5420c7d97c5SJed Brown PetscErrorCode ierr; 5430c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5440c7d97c5SJed Brown PetscScalar* array_to; 5450c7d97c5SJed Brown PetscScalar* array_from; 5460c7d97c5SJed Brown MPI_Comm comm=((PetscObject)pc)->comm; 5470c7d97c5SJed Brown PetscInt i; 5480c7d97c5SJed Brown 5490c7d97c5SJed Brown PetscFunctionBegin; 5500c7d97c5SJed Brown 5510c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 5520c7d97c5SJed Brown case SCATTERS_BDDC: 5530c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 5540c7d97c5SJed Brown break; 5550c7d97c5SJed Brown case GATHERS_BDDC: 5560c7d97c5SJed Brown if(vec_from) VecGetArray(vec_from,&array_from); 5570c7d97c5SJed Brown if(vec_to) VecGetArray(vec_to,&array_to); 5580c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 5590c7d97c5SJed Brown case SEQUENTIAL_BDDC: 5600c7d97c5SJed Brown if(smode == SCATTER_FORWARD) { 56153cdbc3dSStefano 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); 5620c7d97c5SJed Brown if(vec_to) { 5630c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 5640c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 5650c7d97c5SJed Brown } 5660c7d97c5SJed Brown } else { 5670c7d97c5SJed Brown if(vec_from) 5680c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 5690c7d97c5SJed Brown pcbddc->replicated_local_primal_values[i]=array_from[pcbddc->replicated_local_primal_indices[i]]; 57053cdbc3dSStefano 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); 5710c7d97c5SJed Brown } 5720c7d97c5SJed Brown break; 5730c7d97c5SJed Brown case REPLICATED_BDDC: 5740c7d97c5SJed Brown if(smode == SCATTER_FORWARD) { 57553cdbc3dSStefano 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); 5760c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 5770c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 5780c7d97c5SJed Brown } else { /* no communications needed for SCATTER_REVERSE since needed data is already present */ 5790c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_size;i++) 5800c7d97c5SJed Brown array_to[i]=array_from[pcbddc->local_primal_indices[i]]; 5810c7d97c5SJed Brown } 5820c7d97c5SJed Brown break; 58353cdbc3dSStefano Zampini case MULTILEVEL_BDDC: 58453cdbc3dSStefano Zampini break; 58553cdbc3dSStefano Zampini case PARALLEL_BDDC: 58653cdbc3dSStefano Zampini break; 5870c7d97c5SJed Brown } 5880c7d97c5SJed Brown if(vec_from) VecRestoreArray(vec_from,&array_from); 5890c7d97c5SJed Brown if(vec_to) VecRestoreArray(vec_to,&array_to); 5900c7d97c5SJed Brown break; 5910c7d97c5SJed Brown } 5920c7d97c5SJed Brown PetscFunctionReturn(0); 5930c7d97c5SJed Brown 5940c7d97c5SJed Brown } 5950c7d97c5SJed Brown 5960c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 5970c7d97c5SJed Brown /* 5980c7d97c5SJed Brown PCDestroy_BDDC - Destroys the private context for the NN preconditioner 5990c7d97c5SJed Brown that was created with PCCreate_BDDC(). 6000c7d97c5SJed Brown 6010c7d97c5SJed Brown Input Parameter: 6020c7d97c5SJed Brown . pc - the preconditioner context 6030c7d97c5SJed Brown 6040c7d97c5SJed Brown Application Interface Routine: PCDestroy() 6050c7d97c5SJed Brown */ 6060c7d97c5SJed Brown #undef __FUNCT__ 6070c7d97c5SJed Brown #define __FUNCT__ "PCDestroy_BDDC" 60853cdbc3dSStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 6090c7d97c5SJed Brown { 6100c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6110c7d97c5SJed Brown PetscErrorCode ierr; 6120c7d97c5SJed Brown 6130c7d97c5SJed Brown PetscFunctionBegin; 6140c7d97c5SJed Brown /* free data created by PCIS */ 6150c7d97c5SJed Brown ierr = PCISDestroy(pc);CHKERRQ(ierr); 6160c7d97c5SJed Brown /* free BDDC data */ 61753cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 61853cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->coarse_rhs);CHKERRQ(ierr); 61953cdbc3dSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 62053cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_mat);CHKERRQ(ierr); 62153cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 62253cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 62353cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 62453cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 62553cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 62653cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 62753cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 62853cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 62953cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec4_D);CHKERRQ(ierr); 63053cdbc3dSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 63153cdbc3dSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 63253cdbc3dSStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 63353cdbc3dSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 63453cdbc3dSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 63553cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 6363b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 6373b03a366Sstefano_zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 63853cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->local_primal_indices);CHKERRQ(ierr); 63953cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 6400c7d97c5SJed Brown if (pcbddc->replicated_local_primal_values) { free(pcbddc->replicated_local_primal_values); } 64153cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->local_primal_displacements);CHKERRQ(ierr); 64253cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->local_primal_sizes);CHKERRQ(ierr); 6439c0446d6SStefano Zampini PetscInt i; 6443b03a366Sstefano_zampini for(i=0;i<pcbddc->n_ISForDofs;i++) { ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); } 6453b03a366Sstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 6463b03a366Sstefano_zampini for(i=0;i<pcbddc->n_ISForFaces;i++) { ierr = ISDestroy(&pcbddc->ISForFaces[i]);CHKERRQ(ierr); } 6473b03a366Sstefano_zampini ierr = PetscFree(pcbddc->ISForFaces);CHKERRQ(ierr); 6483b03a366Sstefano_zampini for(i=0;i<pcbddc->n_ISForEdges;i++) { ierr = ISDestroy(&pcbddc->ISForEdges[i]);CHKERRQ(ierr); } 6493b03a366Sstefano_zampini ierr = PetscFree(pcbddc->ISForEdges);CHKERRQ(ierr); 6503b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->ISForVertices);CHKERRQ(ierr); 6510c7d97c5SJed Brown /* Free the private data structure that was hanging off the PC */ 6520c7d97c5SJed Brown ierr = PetscFree(pcbddc);CHKERRQ(ierr); 6530c7d97c5SJed Brown PetscFunctionReturn(0); 6540c7d97c5SJed Brown } 6550c7d97c5SJed Brown 6560c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 6570c7d97c5SJed Brown /*MC 6580c7d97c5SJed Brown PCBDDC - Balancing Domain Decomposition by Constraints. 6590c7d97c5SJed Brown 6600c7d97c5SJed Brown Options Database Keys: 661a0ba757dSStefano Zampini . -pcbddc ??? - 6620c7d97c5SJed Brown 6630c7d97c5SJed Brown Level: intermediate 6640c7d97c5SJed Brown 6650c7d97c5SJed Brown Notes: The matrix used with this preconditioner must be of type MATIS 6660c7d97c5SJed Brown 6670c7d97c5SJed Brown Unlike more 'conventional' interface preconditioners, this iterates over ALL the 6680c7d97c5SJed Brown degrees of freedom, NOT just those on the interface (this allows the use of approximate solvers 6690c7d97c5SJed Brown on the subdomains). 6700c7d97c5SJed Brown 671a0ba757dSStefano Zampini Options for the coarse grid preconditioner can be set with - 672a0ba757dSStefano Zampini Options for the Dirichlet subproblem can be set with - 673a0ba757dSStefano Zampini Options for the Neumann subproblem can be set with - 6740c7d97c5SJed Brown 6750c7d97c5SJed Brown Contributed by Stefano Zampini 6760c7d97c5SJed Brown 6770c7d97c5SJed Brown .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 6780c7d97c5SJed Brown M*/ 6790c7d97c5SJed Brown EXTERN_C_BEGIN 6800c7d97c5SJed Brown #undef __FUNCT__ 6810c7d97c5SJed Brown #define __FUNCT__ "PCCreate_BDDC" 6820c7d97c5SJed Brown PetscErrorCode PCCreate_BDDC(PC pc) 6830c7d97c5SJed Brown { 6840c7d97c5SJed Brown PetscErrorCode ierr; 6850c7d97c5SJed Brown PC_BDDC *pcbddc; 6860c7d97c5SJed Brown 6870c7d97c5SJed Brown PetscFunctionBegin; 6880c7d97c5SJed Brown /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 6890c7d97c5SJed Brown ierr = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr); 6900c7d97c5SJed Brown pc->data = (void*)pcbddc; 6910c7d97c5SJed Brown /* create PCIS data structure */ 6920c7d97c5SJed Brown ierr = PCISCreate(pc);CHKERRQ(ierr); 6930c7d97c5SJed Brown /* BDDC specific */ 6940c7d97c5SJed Brown pcbddc->coarse_vec = 0; 6950c7d97c5SJed Brown pcbddc->coarse_rhs = 0; 69653cdbc3dSStefano Zampini pcbddc->coarse_ksp = 0; 6970c7d97c5SJed Brown pcbddc->coarse_phi_B = 0; 6980c7d97c5SJed Brown pcbddc->coarse_phi_D = 0; 6990c7d97c5SJed Brown pcbddc->vec1_P = 0; 7000c7d97c5SJed Brown pcbddc->vec1_R = 0; 7010c7d97c5SJed Brown pcbddc->vec2_R = 0; 7020c7d97c5SJed Brown pcbddc->local_auxmat1 = 0; 7030c7d97c5SJed Brown pcbddc->local_auxmat2 = 0; 7040c7d97c5SJed Brown pcbddc->R_to_B = 0; 7050c7d97c5SJed Brown pcbddc->R_to_D = 0; 70653cdbc3dSStefano Zampini pcbddc->ksp_D = 0; 70753cdbc3dSStefano Zampini pcbddc->ksp_R = 0; 7080c7d97c5SJed Brown pcbddc->local_primal_indices = 0; 7090c7d97c5SJed Brown pcbddc->prec_type = PETSC_FALSE; 71053cdbc3dSStefano Zampini pcbddc->NeumannBoundaries = 0; 7113b03a366Sstefano_zampini pcbddc->ISForDofs = 0; 7123b03a366Sstefano_zampini pcbddc->ISForVertices = 0; 7133b03a366Sstefano_zampini pcbddc->n_ISForFaces = 0; 7143b03a366Sstefano_zampini pcbddc->n_ISForEdges = 0; 7153b03a366Sstefano_zampini pcbddc->ConstraintMatrix = 0; 7163b03a366Sstefano_zampini pcbddc->use_nnsp_true = PETSC_FALSE; 7170c7d97c5SJed Brown pcbddc->local_primal_sizes = 0; 7180c7d97c5SJed Brown pcbddc->local_primal_displacements = 0; 7190c7d97c5SJed Brown pcbddc->replicated_local_primal_indices = 0; 7200c7d97c5SJed Brown pcbddc->replicated_local_primal_values = 0; 7210c7d97c5SJed Brown pcbddc->coarse_loc_to_glob = 0; 722e269702eSStefano Zampini pcbddc->dbg_flag = PETSC_FALSE; 7230c7d97c5SJed Brown pcbddc->coarsening_ratio = 8; 7240c7d97c5SJed Brown /* function pointers */ 7250c7d97c5SJed Brown pc->ops->apply = PCApply_BDDC; 7260c7d97c5SJed Brown pc->ops->applytranspose = 0; 7270c7d97c5SJed Brown pc->ops->setup = PCSetUp_BDDC; 7280c7d97c5SJed Brown pc->ops->destroy = PCDestroy_BDDC; 7290c7d97c5SJed Brown pc->ops->setfromoptions = PCSetFromOptions_BDDC; 7300c7d97c5SJed Brown pc->ops->view = 0; 7310c7d97c5SJed Brown pc->ops->applyrichardson = 0; 7320c7d97c5SJed Brown pc->ops->applysymmetricleft = 0; 7330c7d97c5SJed Brown pc->ops->applysymmetricright = 0; 7340c7d97c5SJed Brown /* composing function */ 7353b03a366Sstefano_zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C","PCBDDCSetDirichletBoundaries_BDDC", 7363b03a366Sstefano_zampini PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 7370c7d97c5SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C","PCBDDCSetNeumannBoundaries_BDDC", 7380c7d97c5SJed Brown PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 73953cdbc3dSStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C","PCBDDCGetNeumannBoundaries_BDDC", 74053cdbc3dSStefano Zampini PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 7410c7d97c5SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetCoarseProblemType_C","PCBDDCSetCoarseProblemType_BDDC", 7420c7d97c5SJed Brown PCBDDCSetCoarseProblemType_BDDC);CHKERRQ(ierr); 7439c0446d6SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetDofsSplitting_C","PCBDDCSetDofsSplitting_BDDC", 7449c0446d6SStefano Zampini PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 7450c7d97c5SJed Brown PetscFunctionReturn(0); 7460c7d97c5SJed Brown } 7470c7d97c5SJed Brown EXTERN_C_END 7480c7d97c5SJed Brown 7490c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 7500c7d97c5SJed Brown /* 7513b03a366Sstefano_zampini Create C matrix [I 0; 0 const] 7523b03a366Sstefano_zampini */ 753*de534f79Sstefano_zampini #ifdef BDDC_USE_POD 754*de534f79Sstefano_zampini #if !defined(PETSC_MISSING_LAPACK_GESVD) 7553b03a366Sstefano_zampini #define PETSC_MISSING_LAPACK_GESVD 1 756*de534f79Sstefano_zampini #define UNDEF_PETSC_MISSING_LAPACK_GESVD 1 757*de534f79Sstefano_zampini #endif 7583b03a366Sstefano_zampini #endif 7593b03a366Sstefano_zampini 7603b03a366Sstefano_zampini #undef __FUNCT__ 7613b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCCreateConstraintMatrix" 7623b03a366Sstefano_zampini static PetscErrorCode PCBDDCCreateConstraintMatrix(PC pc) 7633b03a366Sstefano_zampini { 7643b03a366Sstefano_zampini PetscErrorCode ierr; 7653b03a366Sstefano_zampini PC_IS* pcis = (PC_IS*)(pc->data); 7663b03a366Sstefano_zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 7673b03a366Sstefano_zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 7683b03a366Sstefano_zampini PetscInt *nnz,*vertices,*is_indices; 7693b03a366Sstefano_zampini PetscScalar *temp_quadrature_constraint; 7703b03a366Sstefano_zampini PetscInt *temp_indices,*temp_indices_to_constraint; 7713b03a366Sstefano_zampini PetscInt local_primal_size,i,j,k,total_counts,max_size_of_constraint; 7723b03a366Sstefano_zampini PetscInt n_constraints,n_vertices,size_of_constraint; 7733b03a366Sstefano_zampini PetscReal quad_value; 7743b03a366Sstefano_zampini PetscBool nnsp_has_cnst=PETSC_FALSE,use_nnsp_true=pcbddc->use_nnsp_true; 7753b03a366Sstefano_zampini PetscInt nnsp_size=0,nnsp_addone=0,temp_constraints,temp_start_ptr; 7763b03a366Sstefano_zampini IS *used_IS; 7773b03a366Sstefano_zampini const MatType impMatType=MATSEQAIJ; 7783b03a366Sstefano_zampini PetscBLASInt Bs,Bt,lwork,lierr; 7793b03a366Sstefano_zampini PetscReal tol=1.0e-8; 7803b03a366Sstefano_zampini Vec *localnearnullsp; 7813b03a366Sstefano_zampini PetscScalar *work,*temp_basis,*array_vector,*correlation_mat; 7823b03a366Sstefano_zampini PetscReal *rwork,*singular_vals; 783*de534f79Sstefano_zampini PetscBLASInt Bone=1; 784*de534f79Sstefano_zampini /* some ugly conditional declarations */ 7853b03a366Sstefano_zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 7863b03a366Sstefano_zampini PetscScalar dot_result; 7873b03a366Sstefano_zampini PetscScalar one=1.0,zero=0.0; 7883b03a366Sstefano_zampini PetscInt ii; 7893b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 7903b03a366Sstefano_zampini PetscScalar val1,val2; 7913b03a366Sstefano_zampini #endif 7923b03a366Sstefano_zampini #else 7933b03a366Sstefano_zampini PetscBLASInt dummy_int; 7943b03a366Sstefano_zampini PetscScalar dummy_scalar; 7953b03a366Sstefano_zampini #endif 7963b03a366Sstefano_zampini 7973b03a366Sstefano_zampini PetscFunctionBegin; 7983b03a366Sstefano_zampini /* check if near null space is attached to global mat */ 7993b03a366Sstefano_zampini if(pc->pmat->nearnullsp) { 8003b03a366Sstefano_zampini nnsp_has_cnst = pc->pmat->nearnullsp->has_cnst; 8013b03a366Sstefano_zampini nnsp_size = pc->pmat->nearnullsp->n; 8023b03a366Sstefano_zampini } else { /* if near null space is not provided it uses constants */ 8033b03a366Sstefano_zampini nnsp_has_cnst = PETSC_TRUE; 8043b03a366Sstefano_zampini use_nnsp_true = PETSC_TRUE; 8053b03a366Sstefano_zampini } 8063b03a366Sstefano_zampini if(nnsp_has_cnst) { 8073b03a366Sstefano_zampini nnsp_addone = 1; 8083b03a366Sstefano_zampini } 8093b03a366Sstefano_zampini /* 8103b03a366Sstefano_zampini Evaluate maximum storage size needed by the procedure 8113b03a366Sstefano_zampini - temp_indices will contain start index of each constraint stored as follows 8123b03a366Sstefano_zampini - temp_indices_to_constraint[temp_indices[i],...,temp[indices[i+1]-1] will contain the indices (in local numbering) on which the constraint acts 8133b03a366Sstefano_zampini - temp_quadrature_constraint[temp_indices[i],...,temp[indices[i+1]-1] will contain the scalars representing the constraint itself 8143b03a366Sstefano_zampini */ 8153b03a366Sstefano_zampini total_counts = pcbddc->n_ISForFaces+pcbddc->n_ISForEdges; 8163b03a366Sstefano_zampini total_counts *= (nnsp_addone+nnsp_size); 8173b03a366Sstefano_zampini ierr = PetscMalloc((total_counts+1)*sizeof(PetscInt),&temp_indices);CHKERRQ(ierr); 8183b03a366Sstefano_zampini total_counts = 0; 8193b03a366Sstefano_zampini max_size_of_constraint = 0; 8203b03a366Sstefano_zampini for(i=0;i<pcbddc->n_ISForEdges+pcbddc->n_ISForFaces;i++){ 8213b03a366Sstefano_zampini if(i<pcbddc->n_ISForEdges){ 8223b03a366Sstefano_zampini used_IS = &pcbddc->ISForEdges[i]; 8233b03a366Sstefano_zampini } else { 8243b03a366Sstefano_zampini used_IS = &pcbddc->ISForFaces[i-pcbddc->n_ISForEdges]; 8253b03a366Sstefano_zampini } 8263b03a366Sstefano_zampini ierr = ISGetSize(*used_IS,&j);CHKERRQ(ierr); 8273b03a366Sstefano_zampini total_counts += j; 8283b03a366Sstefano_zampini if(j>max_size_of_constraint) max_size_of_constraint=j; 8293b03a366Sstefano_zampini } 8303b03a366Sstefano_zampini total_counts *= (nnsp_addone+nnsp_size); 8313b03a366Sstefano_zampini ierr = PetscMalloc(total_counts*sizeof(PetscScalar),&temp_quadrature_constraint);CHKERRQ(ierr); 8323b03a366Sstefano_zampini ierr = PetscMalloc(total_counts*sizeof(PetscInt),&temp_indices_to_constraint);CHKERRQ(ierr); 8333b03a366Sstefano_zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd or LAPACKsyev/LAPACKheev */ 8343b03a366Sstefano_zampini rwork = 0; 8353b03a366Sstefano_zampini work = 0; 8363b03a366Sstefano_zampini singular_vals = 0; 8373b03a366Sstefano_zampini temp_basis = 0; 8383b03a366Sstefano_zampini correlation_mat = 0; 8393b03a366Sstefano_zampini if(!pcbddc->use_nnsp_true) { 8403b03a366Sstefano_zampini PetscScalar temp_work; 8413b03a366Sstefano_zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 8423b03a366Sstefano_zampini /* POD */ 8433b03a366Sstefano_zampini PetscInt max_n; 8443b03a366Sstefano_zampini max_n = nnsp_addone+nnsp_size; 8453b03a366Sstefano_zampini /* using some techniques borrowed from Proper Orthogonal Decomposition */ 8463b03a366Sstefano_zampini ierr = PetscMalloc(max_n*max_n*sizeof(PetscScalar),&correlation_mat);CHKERRQ(ierr); 8473b03a366Sstefano_zampini ierr = PetscMalloc(max_n*sizeof(PetscReal),&singular_vals);CHKERRQ(ierr); 8483b03a366Sstefano_zampini ierr = PetscMalloc(max_size_of_constraint*(nnsp_addone+nnsp_size)*sizeof(PetscScalar),&temp_basis);CHKERRQ(ierr); 8493b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 8503b03a366Sstefano_zampini ierr = PetscMalloc(3*max_n*sizeof(PetscReal),&rwork);CHKERRQ(ierr); 8513b03a366Sstefano_zampini #endif 8523b03a366Sstefano_zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 8533b03a366Sstefano_zampini Bt = PetscBLASIntCast(max_n); 8543b03a366Sstefano_zampini lwork=-1; 8553b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 8563b03a366Sstefano_zampini LAPACKsyev_("V","U",&Bt,correlation_mat,&Bt,singular_vals,&temp_work,&lwork,&lierr); 8573b03a366Sstefano_zampini #else 8583b03a366Sstefano_zampini LAPACKsyev_("V","U",&Bt,correlation_mat,&Bt,singular_vals,&temp_work,&lwork,rwork,&lierr); 8593b03a366Sstefano_zampini #endif 8603b03a366Sstefano_zampini #else /* on missing GESVD */ 8613b03a366Sstefano_zampini /* SVD */ 8623b03a366Sstefano_zampini PetscInt max_n,min_n; 8633b03a366Sstefano_zampini max_n = max_size_of_constraint; 8643b03a366Sstefano_zampini min_n = nnsp_addone+nnsp_size; 8653b03a366Sstefano_zampini if(max_size_of_constraint < ( nnsp_addone+nnsp_size ) ) { 8663b03a366Sstefano_zampini min_n = max_size_of_constraint; 8673b03a366Sstefano_zampini max_n = nnsp_addone+nnsp_size; 8683b03a366Sstefano_zampini } 8693b03a366Sstefano_zampini ierr = PetscMalloc(min_n*sizeof(PetscReal),&singular_vals);CHKERRQ(ierr); 8703b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 8713b03a366Sstefano_zampini ierr = PetscMalloc(5*min_n*sizeof(PetscReal),&rwork);CHKERRQ(ierr); 8723b03a366Sstefano_zampini #endif 8733b03a366Sstefano_zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 8743b03a366Sstefano_zampini lwork=-1; 8753b03a366Sstefano_zampini Bs = PetscBLASIntCast(max_n); 8763b03a366Sstefano_zampini Bt = PetscBLASIntCast(min_n); 8773b03a366Sstefano_zampini dummy_int = Bs; 878670f3ff9SJed Brown ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 8793b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 8803b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[0],&Bs,singular_vals, 8813b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,&temp_work,&lwork,&lierr); 8823b03a366Sstefano_zampini #else 8833b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[0],&Bs,singular_vals, 8843b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,&temp_work,&lwork,rwork,&lierr); 8853b03a366Sstefano_zampini #endif 8863b03a366Sstefano_zampini if ( lierr ) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SVD Lapack routine %d",(int)lierr); 887670f3ff9SJed Brown ierr = PetscFPTrapPop();CHKERRQ(ierr); 8883b03a366Sstefano_zampini #endif 8893b03a366Sstefano_zampini /* Allocate optimal workspace */ 8903b03a366Sstefano_zampini lwork = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work)); 8913b03a366Sstefano_zampini total_counts = (PetscInt)lwork; 8923b03a366Sstefano_zampini ierr = PetscMalloc(total_counts*sizeof(PetscScalar),&work);CHKERRQ(ierr); 8933b03a366Sstefano_zampini } 8943b03a366Sstefano_zampini /* get local part of global near null space vectors */ 8953b03a366Sstefano_zampini ierr = PetscMalloc(nnsp_size*sizeof(Vec),&localnearnullsp);CHKERRQ(ierr); 8963b03a366Sstefano_zampini for(k=0;k<nnsp_size;k++) { 8973b03a366Sstefano_zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 8983b03a366Sstefano_zampini ierr = VecScatterBegin(matis->ctx,pc->pmat->nearnullsp->vecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8993b03a366Sstefano_zampini ierr = VecScatterEnd (matis->ctx,pc->pmat->nearnullsp->vecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9003b03a366Sstefano_zampini } 9013b03a366Sstefano_zampini /* Now we can loop on constraining sets */ 9023b03a366Sstefano_zampini total_counts=0; 9033b03a366Sstefano_zampini temp_indices[0]=0; 9043b03a366Sstefano_zampini for(i=0;i<pcbddc->n_ISForEdges+pcbddc->n_ISForFaces;i++){ 9053b03a366Sstefano_zampini if(i<pcbddc->n_ISForEdges){ 9063b03a366Sstefano_zampini used_IS = &pcbddc->ISForEdges[i]; 9073b03a366Sstefano_zampini } else { 9083b03a366Sstefano_zampini used_IS = &pcbddc->ISForFaces[i-pcbddc->n_ISForEdges]; 9093b03a366Sstefano_zampini } 9103b03a366Sstefano_zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 9113b03a366Sstefano_zampini temp_start_ptr = total_counts; /* need to know the starting index of constraints stored */ 9123b03a366Sstefano_zampini ierr = ISGetSize(*used_IS,&size_of_constraint);CHKERRQ(ierr); 9133b03a366Sstefano_zampini ierr = ISGetIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 9143b03a366Sstefano_zampini if(nnsp_has_cnst) { 9153b03a366Sstefano_zampini temp_constraints++; 9163b03a366Sstefano_zampini quad_value = 1.0/PetscSqrtReal((PetscReal)size_of_constraint); 9173b03a366Sstefano_zampini for(j=0;j<size_of_constraint;j++) { 9183b03a366Sstefano_zampini temp_indices_to_constraint[temp_indices[total_counts]+j]=is_indices[j]; 9193b03a366Sstefano_zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=quad_value; 9203b03a366Sstefano_zampini } 9213b03a366Sstefano_zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 9223b03a366Sstefano_zampini total_counts++; 9233b03a366Sstefano_zampini } 9243b03a366Sstefano_zampini for(k=0;k<nnsp_size;k++) { 9253b03a366Sstefano_zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array_vector);CHKERRQ(ierr); 9263b03a366Sstefano_zampini for(j=0;j<size_of_constraint;j++) { 9273b03a366Sstefano_zampini temp_indices_to_constraint[temp_indices[total_counts]+j]=is_indices[j]; 9283b03a366Sstefano_zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=array_vector[is_indices[j]]; 9293b03a366Sstefano_zampini } 9303b03a366Sstefano_zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array_vector);CHKERRQ(ierr); 931*de534f79Sstefano_zampini quad_value = 1.0; 932*de534f79Sstefano_zampini if( use_nnsp_true ) { /* check if array is null on the connected component in case use_nnsp_true has been requested */ 933*de534f79Sstefano_zampini Bs = PetscBLASIntCast(size_of_constraint); 934*de534f79Sstefano_zampini quad_value = BLASasum_(&Bs,&temp_quadrature_constraint[temp_indices[total_counts]],&Bone); 935*de534f79Sstefano_zampini } 936*de534f79Sstefano_zampini if ( quad_value > 0.0 ) { /* keep indices and values */ 937*de534f79Sstefano_zampini temp_constraints++; 9383b03a366Sstefano_zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 9393b03a366Sstefano_zampini total_counts++; 9403b03a366Sstefano_zampini } 941*de534f79Sstefano_zampini } 9423b03a366Sstefano_zampini ierr = ISRestoreIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 943*de534f79Sstefano_zampini /* perform SVD on the constraint if use_nnsp_true has not be requested by the user */ 9443b03a366Sstefano_zampini if(!use_nnsp_true) { 945*de534f79Sstefano_zampini 9463b03a366Sstefano_zampini Bs = PetscBLASIntCast(size_of_constraint); 9473b03a366Sstefano_zampini Bt = PetscBLASIntCast(temp_constraints); 948*de534f79Sstefano_zampini 9493b03a366Sstefano_zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 9503b03a366Sstefano_zampini ierr = PetscMemzero(correlation_mat,Bt*Bt*sizeof(PetscScalar));CHKERRQ(ierr); 9513b03a366Sstefano_zampini /* Store upper triangular part of correlation matrix */ 9523b03a366Sstefano_zampini for(j=0;j<temp_constraints;j++) { 9533b03a366Sstefano_zampini for(k=0;k<j+1;k++) { 9543b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 9553b03a366Sstefano_zampini /* hand made complex dot product */ 9563b03a366Sstefano_zampini dot_result = 0.0; 9573b03a366Sstefano_zampini for (ii=0; ii<size_of_constraint; ii++) { 9583b03a366Sstefano_zampini val1 = temp_quadrature_constraint[temp_indices[temp_start_ptr+j]+ii]; 9593b03a366Sstefano_zampini val2 = temp_quadrature_constraint[temp_indices[temp_start_ptr+k]+ii]; 9603b03a366Sstefano_zampini dot_result += val1*PetscConj(val2); 9613b03a366Sstefano_zampini } 9623b03a366Sstefano_zampini #else 9633b03a366Sstefano_zampini dot_result = BLASdot_(&Bs,&temp_quadrature_constraint[temp_indices[temp_start_ptr+j]],&Bone, 9643b03a366Sstefano_zampini &temp_quadrature_constraint[temp_indices[temp_start_ptr+k]],&Bone); 9653b03a366Sstefano_zampini #endif 9663b03a366Sstefano_zampini correlation_mat[j*temp_constraints+k]=dot_result; 9673b03a366Sstefano_zampini } 9683b03a366Sstefano_zampini } 9693b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 9703b03a366Sstefano_zampini LAPACKsyev_("V","U",&Bt,correlation_mat,&Bt,singular_vals,work,&lwork,&lierr); 9713b03a366Sstefano_zampini #else 9723b03a366Sstefano_zampini LAPACKsyev_("V","U",&Bt,correlation_mat,&Bt,singular_vals,work,&lwork,rwork,&lierr); 9733b03a366Sstefano_zampini #endif 9743b03a366Sstefano_zampini if ( lierr ) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in EV Lapack routine %d",(int)lierr); 9753b03a366Sstefano_zampini /* retain eigenvalues greater than tol: note that lapack SYEV gives eigs in ascending order */ 9763b03a366Sstefano_zampini j=0; 9773b03a366Sstefano_zampini while( j < Bt && singular_vals[j] < tol) j++; 9783b03a366Sstefano_zampini total_counts=total_counts-j; 9793b03a366Sstefano_zampini if(j<temp_constraints) { 9803b03a366Sstefano_zampini for(k=j;k<Bt;k++) { singular_vals[k]=1.0/PetscSqrtReal(singular_vals[k]); } 9813b03a366Sstefano_zampini BLASgemm_("N","N",&Bs,&Bt,&Bt,&one,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Bs,correlation_mat,&Bt,&zero,temp_basis,&Bs); 9823b03a366Sstefano_zampini /* copy POD basis into used quadrature memory */ 9833b03a366Sstefano_zampini for(k=0;k<Bt-j;k++) { 9843b03a366Sstefano_zampini for(ii=0;ii<size_of_constraint;ii++) { 9853b03a366Sstefano_zampini temp_quadrature_constraint[temp_indices[temp_start_ptr+k]+ii]=singular_vals[Bt-1-k]*temp_basis[(Bt-1-k)*size_of_constraint+ii]; 9863b03a366Sstefano_zampini } 9873b03a366Sstefano_zampini } 9883b03a366Sstefano_zampini } 989*de534f79Sstefano_zampini 9903b03a366Sstefano_zampini #else /* on missing GESVD */ 991*de534f79Sstefano_zampini 9923b03a366Sstefano_zampini PetscInt min_n = temp_constraints; 9933b03a366Sstefano_zampini if(min_n > size_of_constraint) min_n = size_of_constraint; 9943b03a366Sstefano_zampini dummy_int = Bs; 995670f3ff9SJed Brown ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 9963b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 9973b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Bs,singular_vals, 9983b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,work,&lwork,&lierr); 9993b03a366Sstefano_zampini #else 10003b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Bs,singular_vals, 10013b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,work,&lwork,rwork,&lierr); 10023b03a366Sstefano_zampini #endif 10033b03a366Sstefano_zampini if ( lierr ) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SVD Lapack routine %d",(int)lierr); 1004670f3ff9SJed Brown ierr = PetscFPTrapPop();CHKERRQ(ierr); 10053b03a366Sstefano_zampini /* retain eigenvalues greater than tol: note that lapack SVD gives eigs in descending order */ 10063b03a366Sstefano_zampini j=0; 10073b03a366Sstefano_zampini while( j < min_n && singular_vals[min_n-j-1] < tol) j++; 10083b03a366Sstefano_zampini total_counts = total_counts-(PetscInt)Bt+(min_n-j); 1009*de534f79Sstefano_zampini 10103b03a366Sstefano_zampini #endif 10113b03a366Sstefano_zampini } 10123b03a366Sstefano_zampini } 10133b03a366Sstefano_zampini n_constraints=total_counts; 10143b03a366Sstefano_zampini ierr = ISGetSize(pcbddc->ISForVertices,&n_vertices);CHKERRQ(ierr); 10153b03a366Sstefano_zampini local_primal_size = n_vertices+n_constraints; 10163b03a366Sstefano_zampini ierr = PetscMalloc(local_primal_size*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 10173b03a366Sstefano_zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 10183b03a366Sstefano_zampini ierr = MatSetType(pcbddc->ConstraintMatrix,impMatType);CHKERRQ(ierr); 10193b03a366Sstefano_zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,local_primal_size,pcis->n,local_primal_size,pcis->n);CHKERRQ(ierr); 10203b03a366Sstefano_zampini for(i=0;i<n_vertices;i++) { nnz[i]= 1; } 10213b03a366Sstefano_zampini for(i=0;i<n_constraints;i++) { nnz[i+n_vertices]=temp_indices[i+1]-temp_indices[i]; } 10223b03a366Sstefano_zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 10233b03a366Sstefano_zampini ierr = ISGetIndices(pcbddc->ISForVertices,(const PetscInt**)&vertices);CHKERRQ(ierr); 10243b03a366Sstefano_zampini for(i=0;i<n_vertices;i++) { ierr = MatSetValue(pcbddc->ConstraintMatrix,i,vertices[i],1.0,INSERT_VALUES);CHKERRQ(ierr); } 10253b03a366Sstefano_zampini ierr = ISRestoreIndices(pcbddc->ISForVertices,(const PetscInt**)&vertices);CHKERRQ(ierr); 10263b03a366Sstefano_zampini for(i=0;i<n_constraints;i++) { 10273b03a366Sstefano_zampini j=i+n_vertices; 10283b03a366Sstefano_zampini size_of_constraint=temp_indices[i+1]-temp_indices[i]; 10293b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&j,size_of_constraint,&temp_indices_to_constraint[temp_indices[i]],&temp_quadrature_constraint[temp_indices[i]],INSERT_VALUES);CHKERRQ(ierr); 10303b03a366Sstefano_zampini } 10313b03a366Sstefano_zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10323b03a366Sstefano_zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10333b03a366Sstefano_zampini /* set quantities in pcbddc data structure */ 10343b03a366Sstefano_zampini pcbddc->n_vertices = n_vertices; 10353b03a366Sstefano_zampini pcbddc->n_constraints = n_constraints; 10363b03a366Sstefano_zampini pcbddc->local_primal_size = n_vertices+n_constraints; 10373b03a366Sstefano_zampini /* free workspace no longer needed */ 10383b03a366Sstefano_zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 10393b03a366Sstefano_zampini ierr = PetscFree(work);CHKERRQ(ierr); 10403b03a366Sstefano_zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 10413b03a366Sstefano_zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 10423b03a366Sstefano_zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 10433b03a366Sstefano_zampini ierr = PetscFree(temp_indices);CHKERRQ(ierr); 10443b03a366Sstefano_zampini ierr = PetscFree(temp_indices_to_constraint);CHKERRQ(ierr); 10453b03a366Sstefano_zampini ierr = PetscFree(temp_quadrature_constraint);CHKERRQ(ierr); 10463b03a366Sstefano_zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 10473b03a366Sstefano_zampini for(k=0;k<nnsp_size;k++) { ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); } 10483b03a366Sstefano_zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 10493b03a366Sstefano_zampini PetscFunctionReturn(0); 10503b03a366Sstefano_zampini } 1051*de534f79Sstefano_zampini #ifdef UNDEF_PETSC_MISSING_LAPACK_GESVD 10523b03a366Sstefano_zampini #undef PETSC_MISSING_LAPACK_GESVD 10533b03a366Sstefano_zampini #endif 1054*de534f79Sstefano_zampini 10553b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 10563b03a366Sstefano_zampini /* 10570c7d97c5SJed Brown PCBDDCCoarseSetUp - 10580c7d97c5SJed Brown */ 10590c7d97c5SJed Brown #undef __FUNCT__ 10600c7d97c5SJed Brown #define __FUNCT__ "PCBDDCCoarseSetUp" 106153cdbc3dSStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC pc) 10620c7d97c5SJed Brown { 10630c7d97c5SJed Brown PetscErrorCode ierr; 10640c7d97c5SJed Brown 10650c7d97c5SJed Brown PC_IS* pcis = (PC_IS*)(pc->data); 10660c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 10670c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 10680c7d97c5SJed Brown IS is_R_local; 10690c7d97c5SJed Brown IS is_V_local; 10700c7d97c5SJed Brown IS is_C_local; 10710c7d97c5SJed Brown IS is_aux1; 10720c7d97c5SJed Brown IS is_aux2; 10730c7d97c5SJed Brown const VecType impVecType; 10740c7d97c5SJed Brown const MatType impMatType; 10750c7d97c5SJed Brown PetscInt n_R=0; 10760c7d97c5SJed Brown PetscInt n_D=0; 10770c7d97c5SJed Brown PetscInt n_B=0; 10780c7d97c5SJed Brown PetscScalar zero=0.0; 10790c7d97c5SJed Brown PetscScalar one=1.0; 10800c7d97c5SJed Brown PetscScalar m_one=-1.0; 10810c7d97c5SJed Brown PetscScalar* array; 10820c7d97c5SJed Brown PetscScalar *coarse_submat_vals; 10830c7d97c5SJed Brown PetscInt *idx_R_local; 10840c7d97c5SJed Brown PetscInt *idx_V_B; 10850c7d97c5SJed Brown PetscScalar *coarsefunctions_errors; 10860c7d97c5SJed Brown PetscScalar *constraints_errors; 10870c7d97c5SJed Brown /* auxiliary indices */ 10880c7d97c5SJed Brown PetscInt s,i,j,k; 1089e269702eSStefano Zampini /* for verbose output of bddc */ 1090e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 1091e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 1092a0ba757dSStefano Zampini /* for counting coarse dofs */ 1093a0ba757dSStefano Zampini PetscScalar coarsesum; 10943b03a366Sstefano_zampini PetscInt n_vertices=pcbddc->n_vertices,n_constraints=pcbddc->n_constraints; 10953b03a366Sstefano_zampini PetscInt size_of_constraint; 10963b03a366Sstefano_zampini PetscInt *row_cmat_indices; 10973b03a366Sstefano_zampini PetscScalar *row_cmat_values; 10983b03a366Sstefano_zampini const PetscInt *vertices; 10990c7d97c5SJed Brown 11000c7d97c5SJed Brown PetscFunctionBegin; 11010c7d97c5SJed Brown /* Set Non-overlapping dimensions */ 11020c7d97c5SJed Brown n_B = pcis->n_B; n_D = pcis->n - n_B; 11033b03a366Sstefano_zampini ierr = ISGetIndices(pcbddc->ISForVertices,&vertices);CHKERRQ(ierr); 1104a0ba757dSStefano 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) */ 1105a0ba757dSStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 1106a0ba757dSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 11073b03a366Sstefano_zampini for(i=0;i<n_vertices;i++) { array[ vertices[i] ] = one; } 11083b03a366Sstefano_zampini 11093b03a366Sstefano_zampini for(i=0;i<n_constraints;i++) { 11103b03a366Sstefano_zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,n_vertices+i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 11113b03a366Sstefano_zampini for (j=0; j<size_of_constraint; j++) { 11123b03a366Sstefano_zampini k = row_cmat_indices[j]; 1113a0ba757dSStefano Zampini if( array[k] == zero ) { 1114a0ba757dSStefano Zampini array[k] = one; 1115a0ba757dSStefano Zampini break; 1116a0ba757dSStefano Zampini } 1117a0ba757dSStefano Zampini } 11183b03a366Sstefano_zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,n_vertices+i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 1119a0ba757dSStefano Zampini } 1120a0ba757dSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1121a0ba757dSStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 1122a0ba757dSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1123a0ba757dSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1124a0ba757dSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1125a0ba757dSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1126a0ba757dSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1127a0ba757dSStefano Zampini for(i=0;i<pcis->n;i++) { if( array[i] > zero) array[i] = one/array[i]; } 1128a0ba757dSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1129a0ba757dSStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 1130a0ba757dSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1131a0ba757dSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1132a0ba757dSStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 1133a0ba757dSStefano Zampini pcbddc->coarse_size = (PetscInt) coarsesum; 1134a0ba757dSStefano Zampini 11350c7d97c5SJed Brown /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 11360c7d97c5SJed Brown ierr = VecSet(pcis->vec1_N,one);CHKERRQ(ierr); 11370c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 11383b03a366Sstefano_zampini for (i=0;i<n_vertices;i++) { array[ vertices[i] ] = zero; } 11393b03a366Sstefano_zampini ierr = PetscMalloc(( pcis->n - n_vertices )*sizeof(PetscInt),&idx_R_local);CHKERRQ(ierr); 11400c7d97c5SJed Brown for (i=0, n_R=0; i<pcis->n; i++) { if (array[i] == one) { idx_R_local[n_R] = i; n_R++; } } 11410c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1142e269702eSStefano Zampini if(dbg_flag) { 11430c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 11440c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 11450c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 11460c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 11473b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"r_size = %d, v_size = %d, constraints = %d, local_primal_size = %d\n",n_R,n_vertices,n_constraints,pcbddc->local_primal_size);CHKERRQ(ierr); 11480c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1149a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1150a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem = %d (%f)\n",pcbddc->coarse_size,coarsesum);CHKERRQ(ierr); 1151a0ba757dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 11520c7d97c5SJed Brown } 11530c7d97c5SJed Brown /* Allocate needed vectors */ 11540c7d97c5SJed Brown /* Set Mat type for local matrices needed by BDDC precondtioner */ 11550c7d97c5SJed Brown impMatType = MATSEQDENSE; 11560c7d97c5SJed Brown impVecType = VECSEQ; 11570c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_D,&pcbddc->vec4_D);CHKERRQ(ierr); 11580c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_N,&pcis->vec2_N);CHKERRQ(ierr); 11590c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_R);CHKERRQ(ierr); 11600c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_R,n_R,n_R);CHKERRQ(ierr); 11610c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 1162d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 11630c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_P);CHKERRQ(ierr); 11640c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_P,pcbddc->local_primal_size,pcbddc->local_primal_size);CHKERRQ(ierr); 11650c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 11660c7d97c5SJed Brown 11670c7d97c5SJed Brown /* Creating some index sets needed */ 11680c7d97c5SJed Brown /* For submatrices */ 11690c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,n_R,idx_R_local,PETSC_COPY_VALUES,&is_R_local);CHKERRQ(ierr); 11703b03a366Sstefano_zampini if(n_vertices) { 11713b03a366Sstefano_zampini ierr = ISDuplicate(pcbddc->ISForVertices,&is_V_local);CHKERRQ(ierr); 11723b03a366Sstefano_zampini ierr = ISCopy(pcbddc->ISForVertices,is_V_local);CHKERRQ(ierr); 11733b03a366Sstefano_zampini } 11743b03a366Sstefano_zampini if(n_constraints) { ierr = ISCreateStride (PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_C_local);CHKERRQ(ierr); } 11750c7d97c5SJed Brown /* For VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 11760c7d97c5SJed Brown { 11770c7d97c5SJed Brown PetscInt *aux_array1; 11780c7d97c5SJed Brown PetscInt *aux_array2; 11790c7d97c5SJed Brown PetscScalar value; 11800c7d97c5SJed Brown 11813b03a366Sstefano_zampini ierr = PetscMalloc( (pcis->n_B-n_vertices)*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 11823b03a366Sstefano_zampini ierr = PetscMalloc( (pcis->n_B-n_vertices)*sizeof(PetscInt),&aux_array2);CHKERRQ(ierr); 11830c7d97c5SJed Brown 1184d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 11850c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 11860c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 11870c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11880c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11890c7d97c5SJed Brown ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11900c7d97c5SJed Brown ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11910c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 11920c7d97c5SJed Brown for (i=0, s=0; i<n_R; i++) { if (array[idx_R_local[i]] > one) { aux_array1[s] = i; s++; } } 11930c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 11940c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 11950c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 11960c7d97c5SJed Brown for (i=0, s=0; i<n_B; i++) { if (array[i] > one) { aux_array2[s] = i; s++; } } 11973828260eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 11980c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array2,PETSC_COPY_VALUES,&is_aux2);CHKERRQ(ierr); 11990c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 12000c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 12010c7d97c5SJed Brown ierr = PetscFree(aux_array2);CHKERRQ(ierr); 12020c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 12030c7d97c5SJed Brown ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 12040c7d97c5SJed Brown 1205e269702eSStefano Zampini if(pcbddc->prec_type || dbg_flag ) { 12060c7d97c5SJed Brown ierr = PetscMalloc(n_D*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 12070c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 12080c7d97c5SJed Brown for (i=0, s=0; i<n_R; i++) { if (array[idx_R_local[i]] == one) { aux_array1[s] = i; s++; } } 12090c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 12100c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 12110c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 12120c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 12130c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 12140c7d97c5SJed Brown } 12150c7d97c5SJed Brown 12160c7d97c5SJed Brown /* Check scatters */ 1217e269702eSStefano Zampini if(dbg_flag) { 12180c7d97c5SJed Brown 12190c7d97c5SJed Brown Vec vec_aux; 12200c7d97c5SJed Brown 12210c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 12220c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Checking pcbddc->R_to_B scatter\n");CHKERRQ(ierr); 12230c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1224d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 1225d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_B,PETSC_NULL);CHKERRQ(ierr); 1226d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&vec_aux);CHKERRQ(ierr); 1227d49ef151SStefano Zampini ierr = VecCopy(pcbddc->vec1_R,vec_aux);CHKERRQ(ierr); 1228d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1229d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1230d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1231d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1232d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 1233d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 12340c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_B FORWARD error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 1235d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 12360c7d97c5SJed Brown 1237d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 1238d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_B,PETSC_NULL);CHKERRQ(ierr); 1239d49ef151SStefano Zampini ierr = VecDuplicate(pcis->vec1_B,&vec_aux);CHKERRQ(ierr); 1240d49ef151SStefano Zampini ierr = VecCopy(pcis->vec1_B,vec_aux);CHKERRQ(ierr); 1241d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1242d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1243d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1244d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1245d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcis->vec1_B);CHKERRQ(ierr); 1246d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 12470c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_B REVERSE error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 1248d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 12490c7d97c5SJed Brown 12500c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 12510c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Checking pcbddc->R_to_D scatter\n");CHKERRQ(ierr); 12520c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 12530c7d97c5SJed Brown 1254d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 1255d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL);CHKERRQ(ierr); 1256d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&vec_aux);CHKERRQ(ierr); 1257d49ef151SStefano Zampini ierr = VecCopy(pcbddc->vec1_R,vec_aux);CHKERRQ(ierr); 1258d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1259d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1260d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1261d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1262d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 1263d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 12640c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_D FORWARD error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 1265d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 12660c7d97c5SJed Brown 1267d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 1268d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL);CHKERRQ(ierr); 1269d49ef151SStefano Zampini ierr = VecDuplicate(pcis->vec1_D,&vec_aux);CHKERRQ(ierr); 1270d49ef151SStefano Zampini ierr = VecCopy(pcis->vec1_D,vec_aux);CHKERRQ(ierr); 1271d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1272d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1273d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1274d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1275d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcis->vec1_D);CHKERRQ(ierr); 1276d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 12770c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_D REVERSE error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 1278d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 12790c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 12800c7d97c5SJed Brown 12810c7d97c5SJed Brown } 12820c7d97c5SJed Brown } 12830c7d97c5SJed Brown 12840c7d97c5SJed Brown /* vertices in boundary numbering */ 12853b03a366Sstefano_zampini if(n_vertices) { 1286d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,m_one);CHKERRQ(ierr); 12870c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 12883b03a366Sstefano_zampini for (i=0; i<n_vertices; i++) { array[ vertices[i] ] = i; } 12890c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1290d49ef151SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1291d49ef151SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12923b03a366Sstefano_zampini ierr = PetscMalloc(n_vertices*sizeof(PetscInt),&idx_V_B);CHKERRQ(ierr); 12930c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 12943b03a366Sstefano_zampini for (i=0; i<n_vertices; i++) { 12950c7d97c5SJed Brown s=0; 12960c7d97c5SJed Brown while (array[s] != i ) {s++;} 12970c7d97c5SJed Brown idx_V_B[i]=s; 12980c7d97c5SJed Brown } 12990c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 13000c7d97c5SJed Brown } 13010c7d97c5SJed Brown 13020c7d97c5SJed Brown 13030c7d97c5SJed Brown /* Creating PC contexts for local Dirichlet and Neumann problems */ 13040c7d97c5SJed Brown { 13050c7d97c5SJed Brown Mat A_RR; 130653cdbc3dSStefano Zampini PC pc_temp; 13070c7d97c5SJed Brown /* Matrix for Dirichlet problem is A_II -> we already have it from pcis.c code */ 130853cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 130953cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 131053cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II,SAME_PRECONDITIONER);CHKERRQ(ierr); 131153cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 1312a0ba757dSStefano Zampini //ierr = KSPSetOptionsPrefix();CHKERRQ(ierr); 13130c7d97c5SJed Brown /* default */ 131453cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 131553cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 13160c7d97c5SJed Brown /* Allow user's customization */ 131753cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 131853cdbc3dSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 131953cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 13200c7d97c5SJed Brown /* Matrix for Neumann problem is A_RR -> we need to create it */ 13210c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_R_local,is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 132253cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 132353cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 132453cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR,SAME_PRECONDITIONER);CHKERRQ(ierr); 132553cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 1326a0ba757dSStefano Zampini //ierr = KSPSetOptionsPrefix();CHKERRQ(ierr); 13270c7d97c5SJed Brown /* default */ 132853cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 132953cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 13300c7d97c5SJed Brown /* Allow user's customization */ 133153cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 133253cdbc3dSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 133353cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 1334a0ba757dSStefano Zampini /* check Dirichlet and Neumann solvers */ 1335e269702eSStefano Zampini if(pcbddc->dbg_flag) { 13360c7d97c5SJed Brown Vec temp_vec; 13370c7d97c5SJed Brown PetscScalar value; 13380c7d97c5SJed Brown 1339a0ba757dSStefano Zampini ierr = VecDuplicate(pcis->vec1_D,&temp_vec);CHKERRQ(ierr); 1340a0ba757dSStefano Zampini ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL);CHKERRQ(ierr); 1341a0ba757dSStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 1342a0ba757dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,temp_vec);CHKERRQ(ierr); 1343a0ba757dSStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcis->vec1_D);CHKERRQ(ierr); 1344a0ba757dSStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 1345a0ba757dSStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1346a0ba757dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1347a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1348a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Checking solution of Dirichlet and Neumann problems\n");CHKERRQ(ierr); 1349a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Dirichlet solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 1350d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&temp_vec);CHKERRQ(ierr); 1351d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 1352d49ef151SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 1353d49ef151SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,temp_vec);CHKERRQ(ierr); 1354d49ef151SStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 1355d49ef151SStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 1356e269702eSStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 13570c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Neumann solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 1358d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 13590c7d97c5SJed Brown } 13600c7d97c5SJed Brown /* free Neumann problem's matrix */ 13610c7d97c5SJed Brown ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 13620c7d97c5SJed Brown } 13630c7d97c5SJed Brown 13640c7d97c5SJed Brown /* Assemble all remaining stuff needed to apply BDDC */ 13650c7d97c5SJed Brown { 13660c7d97c5SJed Brown Mat A_RV,A_VR,A_VV; 13670c7d97c5SJed Brown Mat M1,M2; 13680c7d97c5SJed Brown Mat C_CR; 13693b03a366Sstefano_zampini Mat AUXMAT; 13700c7d97c5SJed Brown Vec vec1_C; 13710c7d97c5SJed Brown Vec vec2_C; 13720c7d97c5SJed Brown Vec vec1_V; 13730c7d97c5SJed Brown Vec vec2_V; 13740c7d97c5SJed Brown PetscInt *nnz; 13750c7d97c5SJed Brown PetscInt *auxindices; 137653cdbc3dSStefano Zampini PetscInt index; 13770c7d97c5SJed Brown PetscScalar* array2; 13780c7d97c5SJed Brown MatFactorInfo matinfo; 13790c7d97c5SJed Brown 13800c7d97c5SJed Brown /* Allocating some extra storage just to be safe */ 13810c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 13820c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&auxindices);CHKERRQ(ierr); 13830c7d97c5SJed Brown for(i=0;i<pcis->n;i++) {auxindices[i]=i;} 13840c7d97c5SJed Brown 13850c7d97c5SJed Brown /* some work vectors on vertices and/or constraints */ 13863b03a366Sstefano_zampini if(n_vertices) { 13870c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_V);CHKERRQ(ierr); 13883b03a366Sstefano_zampini ierr = VecSetSizes(vec1_V,n_vertices,n_vertices);CHKERRQ(ierr); 13890c7d97c5SJed Brown ierr = VecSetType(vec1_V,impVecType);CHKERRQ(ierr); 13900c7d97c5SJed Brown ierr = VecDuplicate(vec1_V,&vec2_V);CHKERRQ(ierr); 13910c7d97c5SJed Brown } 13920c7d97c5SJed Brown if(pcbddc->n_constraints) { 13930c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_C);CHKERRQ(ierr); 13940c7d97c5SJed Brown ierr = VecSetSizes(vec1_C,pcbddc->n_constraints,pcbddc->n_constraints);CHKERRQ(ierr); 13950c7d97c5SJed Brown ierr = VecSetType(vec1_C,impVecType);CHKERRQ(ierr); 13960c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&vec2_C);CHKERRQ(ierr); 13970c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&pcbddc->vec1_C);CHKERRQ(ierr); 13980c7d97c5SJed Brown } 13990c7d97c5SJed Brown /* Precompute stuffs needed for preprocessing and application of BDDC*/ 14003b03a366Sstefano_zampini if(n_constraints) { 14010c7d97c5SJed Brown /* some work vectors */ 14020c7d97c5SJed Brown ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->local_auxmat2);CHKERRQ(ierr); 14033b03a366Sstefano_zampini ierr = MatSetSizes(pcbddc->local_auxmat2,n_R,n_constraints,n_R,n_constraints);CHKERRQ(ierr); 14040c7d97c5SJed Brown ierr = MatSetType(pcbddc->local_auxmat2,impMatType);CHKERRQ(ierr); 14053b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(pcbddc->local_auxmat2,PETSC_NULL);CHKERRQ(ierr); 14060c7d97c5SJed Brown 14070c7d97c5SJed Brown /* Assemble local_auxmat2 = - A_{RR}^{-1} C^T_{CR} needed by BDDC application */ 14083b03a366Sstefano_zampini for(i=0;i<n_constraints;i++) { 1409d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 14103b03a366Sstefano_zampini ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 14113b03a366Sstefano_zampini /* Get row of constraint matrix in R numbering */ 14120c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14133b03a366Sstefano_zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,n_vertices+i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 14143b03a366Sstefano_zampini for(j=0;j<size_of_constraint;j++) { array[ row_cmat_indices[j] ] = - row_cmat_values[j]; } 14153b03a366Sstefano_zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,n_vertices+i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 14160c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 14170c7d97c5SJed Brown for(j=0;j<n_R;j++) { array2[j] = array[ idx_R_local[j] ]; } 14180c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14190c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 14203b03a366Sstefano_zampini /* Solve for row of constraint matrix in R numbering */ 142153cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 14223b03a366Sstefano_zampini /* Set values */ 14230c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 14243b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->local_auxmat2,n_R,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 14250c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 14260c7d97c5SJed Brown } 14270c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14280c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14290c7d97c5SJed Brown 14300c7d97c5SJed Brown /* Create Constraint matrix on R nodes: C_{CR} */ 14313b03a366Sstefano_zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_C_local,is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 14320c7d97c5SJed Brown ierr = ISDestroy(&is_C_local);CHKERRQ(ierr); 14330c7d97c5SJed Brown 14340c7d97c5SJed Brown /* Assemble AUXMAT = ( LUFactor )( -C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 14350c7d97c5SJed Brown ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AUXMAT);CHKERRQ(ierr); 1436d49ef151SStefano Zampini ierr = MatFactorInfoInitialize(&matinfo);CHKERRQ(ierr); 14373b03a366Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,0,1,&is_aux1);CHKERRQ(ierr); 14380c7d97c5SJed Brown ierr = MatLUFactor(AUXMAT,is_aux1,is_aux1,&matinfo);CHKERRQ(ierr); 14390c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 14400c7d97c5SJed Brown 14413b03a366Sstefano_zampini /* Assemble explicitly M1 = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} needed in preproc */ 1442d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M1);CHKERRQ(ierr); 14433b03a366Sstefano_zampini ierr = MatSetSizes(M1,n_constraints,n_constraints,n_constraints,n_constraints);CHKERRQ(ierr); 14440c7d97c5SJed Brown ierr = MatSetType(M1,impMatType);CHKERRQ(ierr); 14453b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(M1,PETSC_NULL);CHKERRQ(ierr); 14463b03a366Sstefano_zampini for(i=0;i<n_constraints;i++) { 14470c7d97c5SJed Brown ierr = VecSet(vec1_C,zero);CHKERRQ(ierr); 14480c7d97c5SJed Brown ierr = VecSetValue(vec1_C,i,one,INSERT_VALUES);CHKERRQ(ierr); 14490c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_C);CHKERRQ(ierr); 14500c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_C);CHKERRQ(ierr); 14510c7d97c5SJed Brown ierr = MatSolve(AUXMAT,vec1_C,vec2_C);CHKERRQ(ierr); 14520c7d97c5SJed Brown ierr = VecScale(vec2_C,m_one);CHKERRQ(ierr); 14530c7d97c5SJed Brown ierr = VecGetArray(vec2_C,&array);CHKERRQ(ierr); 14543b03a366Sstefano_zampini ierr = MatSetValues(M1,n_constraints,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 14550c7d97c5SJed Brown ierr = VecRestoreArray(vec2_C,&array);CHKERRQ(ierr); 14560c7d97c5SJed Brown } 14570c7d97c5SJed Brown ierr = MatAssemblyBegin(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14580c7d97c5SJed Brown ierr = MatAssemblyEnd(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14590c7d97c5SJed Brown ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 14600c7d97c5SJed Brown /* Assemble local_auxmat1 = M1*C_{CR} needed by BDDC application in KSP and in preproc */ 14610c7d97c5SJed Brown ierr = MatMatMult(M1,C_CR,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 14620c7d97c5SJed Brown 14630c7d97c5SJed Brown } 14640c7d97c5SJed Brown 14650c7d97c5SJed Brown /* Get submatrices from subdomain matrix */ 14663b03a366Sstefano_zampini if(n_vertices){ 14670c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_R_local,is_V_local,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 14680c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_V_local,is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 14690c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_V_local,is_V_local,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 14700c7d97c5SJed Brown /* Assemble M2 = A_RR^{-1}A_RV */ 1471d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M2);CHKERRQ(ierr); 14723b03a366Sstefano_zampini ierr = MatSetSizes(M2,n_R,n_vertices,n_R,n_vertices);CHKERRQ(ierr); 14730c7d97c5SJed Brown ierr = MatSetType(M2,impMatType);CHKERRQ(ierr); 14743b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(M2,PETSC_NULL);CHKERRQ(ierr); 14753b03a366Sstefano_zampini for(i=0;i<n_vertices;i++) { 14760c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 14770c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 14780c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 14790c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 14800c7d97c5SJed Brown ierr = MatMult(A_RV,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 148153cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 14820c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 14833b03a366Sstefano_zampini ierr = MatSetValues(M2,n_R,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 14840c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 14850c7d97c5SJed Brown } 14860c7d97c5SJed Brown ierr = MatAssemblyBegin(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14870c7d97c5SJed Brown ierr = MatAssemblyEnd(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14880c7d97c5SJed Brown } 14890c7d97c5SJed Brown 14900c7d97c5SJed Brown /* Matrix of coarse basis functions (local) */ 1491d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 14920c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 14930c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_B,impMatType);CHKERRQ(ierr); 14943b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_phi_B,PETSC_NULL);CHKERRQ(ierr); 1495e269702eSStefano Zampini if(pcbddc->prec_type || dbg_flag ) { 1496d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 14970c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 14980c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_D,impMatType);CHKERRQ(ierr); 14993b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_phi_D,PETSC_NULL);CHKERRQ(ierr); 15000c7d97c5SJed Brown } 15010c7d97c5SJed Brown 1502e269702eSStefano Zampini if(dbg_flag) { 15030c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&coarsefunctions_errors);CHKERRQ(ierr); 15040c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&constraints_errors);CHKERRQ(ierr); 15050c7d97c5SJed Brown } 15063b03a366Sstefano_zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 15070c7d97c5SJed Brown ierr = PetscMalloc ((pcbddc->local_primal_size)*(pcbddc->local_primal_size)*sizeof(PetscScalar),&coarse_submat_vals);CHKERRQ(ierr); 15080c7d97c5SJed Brown 15090c7d97c5SJed Brown /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 15103b03a366Sstefano_zampini for(i=0;i<n_vertices;i++){ 15110c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 15120c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 15130c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 15140c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 15150c7d97c5SJed Brown /* solution of saddle point problem */ 15160c7d97c5SJed Brown ierr = MatMult(M2,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 15170c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_R,m_one);CHKERRQ(ierr); 15183b03a366Sstefano_zampini if(n_constraints) { 15190c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec1_R,vec1_C);CHKERRQ(ierr); 15200c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 15210c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 15220c7d97c5SJed Brown } 15230c7d97c5SJed Brown ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); 15240c7d97c5SJed Brown ierr = MatMultAdd(A_VV,vec1_V,vec2_V,vec2_V);CHKERRQ(ierr); 15250c7d97c5SJed Brown 15260c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 15270c7d97c5SJed Brown /* coarse basis functions */ 15280c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 15290c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15300c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15310c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 15323b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 15330c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 15340c7d97c5SJed Brown ierr = MatSetValue(pcbddc->coarse_phi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 1535e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 15360c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15370c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15380c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 15393b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 15400c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 15410c7d97c5SJed Brown } 15420c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 15430c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 15443b03a366Sstefano_zampini for(j=0;j<n_vertices;j++) { coarse_submat_vals[i*pcbddc->local_primal_size+j] = array[j]; } //WARNING -> column major ordering 15450c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 15463b03a366Sstefano_zampini if(n_constraints) { 15470c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 15483b03a366Sstefano_zampini for(j=0;j<n_constraints;j++) { coarse_submat_vals[i*pcbddc->local_primal_size+j+n_vertices] = array[j]; } //WARNING -> column major ordering 15490c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 15500c7d97c5SJed Brown } 15510c7d97c5SJed Brown 1552e269702eSStefano Zampini if( dbg_flag ) { 15530c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 1554d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 15550c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 15560c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 15570c7d97c5SJed Brown for(j=0;j<n_R;j++) { array[idx_R_local[j]] = array2[j]; } 15583b03a366Sstefano_zampini array[ vertices[i] ] = one; 15590c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 15600c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 15610c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers (i.e. primal nodes) */ 1562d49ef151SStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 15630c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 15640c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 15653b03a366Sstefano_zampini for(j=0;j<n_vertices;j++) { array2[j]=array[j]; } 15660c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 15673b03a366Sstefano_zampini if(n_constraints) { 15680c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 15693b03a366Sstefano_zampini for(j=0;j<n_constraints;j++) { array2[j+n_vertices]=array[j]; } 15700c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 15710c7d97c5SJed Brown } 15720c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 15730c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_P,m_one);CHKERRQ(ierr); 15740c7d97c5SJed Brown /* check saddle point solution */ 15750c7d97c5SJed Brown ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 15763b03a366Sstefano_zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 15773b03a366Sstefano_zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[i]);CHKERRQ(ierr); 15783b03a366Sstefano_zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 15790c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 15803b03a366Sstefano_zampini array[i]=array[i]+m_one; /* shift by the identity matrix */ 15810c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 15823b03a366Sstefano_zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[i]);CHKERRQ(ierr); 15830c7d97c5SJed Brown } 15840c7d97c5SJed Brown } 15850c7d97c5SJed Brown 15863b03a366Sstefano_zampini for(i=0;i<n_constraints;i++){ 1587d49ef151SStefano Zampini ierr = VecSet(vec2_C,zero);CHKERRQ(ierr); 15880c7d97c5SJed Brown ierr = VecSetValue(vec2_C,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 15890c7d97c5SJed Brown ierr = VecAssemblyBegin(vec2_C);CHKERRQ(ierr); 15900c7d97c5SJed Brown ierr = VecAssemblyEnd(vec2_C);CHKERRQ(ierr); 15910c7d97c5SJed Brown /* solution of saddle point problem */ 15920c7d97c5SJed Brown ierr = MatMult(M1,vec2_C,vec1_C);CHKERRQ(ierr); 15930c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 15940c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 15953b03a366Sstefano_zampini if(n_vertices) { ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); } 15960c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 15970c7d97c5SJed Brown /* coarse basis functions */ 15983b03a366Sstefano_zampini index=i+n_vertices; 15990c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 16000c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16010c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16020c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 160353cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 16040c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1605e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 16060c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16070c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16080c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 160953cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 16100c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 16110c7d97c5SJed Brown } 16120c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 16133b03a366Sstefano_zampini if(n_vertices) { 16140c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 16153b03a366Sstefano_zampini for(j=0;j<n_vertices;j++) {coarse_submat_vals[index*pcbddc->local_primal_size+j]=array[j];} //WARNING -> column major ordering 16160c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 16170c7d97c5SJed Brown } 16180c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 16193b03a366Sstefano_zampini for(j=0;j<n_constraints;j++) {coarse_submat_vals[index*pcbddc->local_primal_size+j+n_vertices]=array[j];} //WARNING -> column major ordering 16200c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 16210c7d97c5SJed Brown 1622e269702eSStefano Zampini if( dbg_flag ) { 16230c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 162453cdbc3dSStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 16250c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 16260c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 16270c7d97c5SJed Brown for(j=0;j<n_R;j++){ array[ idx_R_local[j] ] = array2[j]; } 16280c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 16290c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 16300c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers */ 163153cdbc3dSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 16320c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 16333b03a366Sstefano_zampini if( n_vertices) { 16340c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 16353b03a366Sstefano_zampini for(j=0;j<n_vertices;j++) {array2[j]=-array[j];} 16360c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 16370c7d97c5SJed Brown } 16380c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 16393b03a366Sstefano_zampini for(j=0;j<n_constraints;j++) {array2[j+n_vertices]=-array[j];} 16400c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 16410c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 16420c7d97c5SJed Brown /* check saddle point solution */ 16430c7d97c5SJed Brown ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 16443b03a366Sstefano_zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 164553cdbc3dSStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[index]);CHKERRQ(ierr); 16463b03a366Sstefano_zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 16470c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 164853cdbc3dSStefano Zampini array[index]=array[index]+m_one; /* shift by the identity matrix */ 16490c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 165053cdbc3dSStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[index]);CHKERRQ(ierr); 16510c7d97c5SJed Brown } 16520c7d97c5SJed Brown } 16530c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16540c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1655e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 16560c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16570c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16580c7d97c5SJed Brown } 16590c7d97c5SJed Brown /* Checking coarse_sub_mat and coarse basis functios */ 16600c7d97c5SJed Brown /* It shuld be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 16619d2fce94SStefano Zampini if(dbg_flag) { 16620c7d97c5SJed Brown 16630c7d97c5SJed Brown Mat coarse_sub_mat; 16640c7d97c5SJed Brown Mat TM1,TM2,TM3,TM4; 16650c7d97c5SJed Brown Mat coarse_phi_D,coarse_phi_B,A_II,A_BB,A_IB,A_BI; 1666a0ba757dSStefano Zampini const MatType checkmattype=MATSEQAIJ; 16670c7d97c5SJed Brown PetscScalar value; 16680c7d97c5SJed Brown 1669c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 1670c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 1671c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 1672c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 1673c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 1674c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 1675c042a7c3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 1676c042a7c3SStefano Zampini ierr = MatConvert(coarse_sub_mat,checkmattype,MAT_REUSE_MATRIX,&coarse_sub_mat);CHKERRQ(ierr); 16770c7d97c5SJed Brown 16780c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 16790c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Check coarse sub mat and local basis functions\n");CHKERRQ(ierr); 16800c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 168153cdbc3dSStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 168253cdbc3dSStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 168353cdbc3dSStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1684c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 168553cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 168653cdbc3dSStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1687c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 168853cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 168953cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 169053cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 169153cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 169253cdbc3dSStefano Zampini ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 169353cdbc3dSStefano Zampini ierr = MatNorm(TM1,NORM_INFINITY,&value);CHKERRQ(ierr); 16940c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"----------------------------------\n");CHKERRQ(ierr); 16950c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d \n",PetscGlobalRank);CHKERRQ(ierr); 16960c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"matrix error = % 1.14e\n",value);CHKERRQ(ierr); 16970c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"coarse functions errors\n");CHKERRQ(ierr); 169853cdbc3dSStefano 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); } 16990c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"constraints errors\n");CHKERRQ(ierr); 170053cdbc3dSStefano 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); } 17010c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 170253cdbc3dSStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 170353cdbc3dSStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 170453cdbc3dSStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 170553cdbc3dSStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 170653cdbc3dSStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 170753cdbc3dSStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 170853cdbc3dSStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 170953cdbc3dSStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 171053cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 171153cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 171253cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 17130c7d97c5SJed Brown ierr = PetscFree(coarsefunctions_errors);CHKERRQ(ierr); 17140c7d97c5SJed Brown ierr = PetscFree(constraints_errors);CHKERRQ(ierr); 17150c7d97c5SJed Brown } 17160c7d97c5SJed Brown 17170c7d97c5SJed Brown /* create coarse matrix and data structures for message passing associated actual choice of coarse problem type */ 17180c7d97c5SJed Brown ierr = PCBDDCSetupCoarseEnvironment(pc,coarse_submat_vals);CHKERRQ(ierr); 17190c7d97c5SJed Brown /* free memory */ 17200c7d97c5SJed Brown ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 17210c7d97c5SJed Brown ierr = PetscFree(auxindices);CHKERRQ(ierr); 17220c7d97c5SJed Brown ierr = PetscFree(nnz);CHKERRQ(ierr); 17233b03a366Sstefano_zampini if(n_vertices) { 17240c7d97c5SJed Brown ierr = VecDestroy(&vec1_V);CHKERRQ(ierr); 17250c7d97c5SJed Brown ierr = VecDestroy(&vec2_V);CHKERRQ(ierr); 17260c7d97c5SJed Brown ierr = MatDestroy(&M2);CHKERRQ(ierr); 17270c7d97c5SJed Brown ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 17280c7d97c5SJed Brown ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 17290c7d97c5SJed Brown ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 17300c7d97c5SJed Brown } 17310c7d97c5SJed Brown if(pcbddc->n_constraints) { 17320c7d97c5SJed Brown ierr = VecDestroy(&vec1_C);CHKERRQ(ierr); 17330c7d97c5SJed Brown ierr = VecDestroy(&vec2_C);CHKERRQ(ierr); 17340c7d97c5SJed Brown ierr = MatDestroy(&M1);CHKERRQ(ierr); 17350c7d97c5SJed Brown ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 17360c7d97c5SJed Brown } 17370c7d97c5SJed Brown } 17380c7d97c5SJed Brown /* free memory */ 17393b03a366Sstefano_zampini if(n_vertices) { 17400c7d97c5SJed Brown ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 17410c7d97c5SJed Brown ierr = ISDestroy(&is_V_local);CHKERRQ(ierr); 17420c7d97c5SJed Brown } 17430c7d97c5SJed Brown ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 17440c7d97c5SJed Brown ierr = ISDestroy(&is_R_local);CHKERRQ(ierr); 17453b03a366Sstefano_zampini ierr = ISRestoreIndices(pcbddc->ISForVertices,(const PetscInt**)&vertices);CHKERRQ(ierr); 17460c7d97c5SJed Brown 17470c7d97c5SJed Brown PetscFunctionReturn(0); 17480c7d97c5SJed Brown } 17490c7d97c5SJed Brown 17500c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 17510c7d97c5SJed Brown 17520c7d97c5SJed Brown #undef __FUNCT__ 17530c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetupCoarseEnvironment" 175453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetupCoarseEnvironment(PC pc,PetscScalar* coarse_submat_vals) 17550c7d97c5SJed Brown { 17560c7d97c5SJed Brown 17570c7d97c5SJed Brown 17580c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 17590c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 17600c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 17610c7d97c5SJed Brown MPI_Comm prec_comm = ((PetscObject)pc)->comm; 17620c7d97c5SJed Brown MPI_Comm coarse_comm; 17630c7d97c5SJed Brown 17640c7d97c5SJed Brown /* common to all choiches */ 17650c7d97c5SJed Brown PetscScalar *temp_coarse_mat_vals; 17660c7d97c5SJed Brown PetscScalar *ins_coarse_mat_vals; 17670c7d97c5SJed Brown PetscInt *ins_local_primal_indices; 17680c7d97c5SJed Brown PetscMPIInt *localsizes2,*localdispl2; 17690c7d97c5SJed Brown PetscMPIInt size_prec_comm; 17700c7d97c5SJed Brown PetscMPIInt rank_prec_comm; 17710c7d97c5SJed Brown PetscMPIInt active_rank=MPI_PROC_NULL; 17720c7d97c5SJed Brown PetscMPIInt master_proc=0; 17730c7d97c5SJed Brown PetscInt ins_local_primal_size; 17740c7d97c5SJed Brown /* specific to MULTILEVEL_BDDC */ 17750c7d97c5SJed Brown PetscMPIInt *ranks_recv; 17760c7d97c5SJed Brown PetscMPIInt count_recv=0; 17770c7d97c5SJed Brown PetscMPIInt rank_coarse_proc_send_to; 17780c7d97c5SJed Brown PetscMPIInt coarse_color = MPI_UNDEFINED; 17790c7d97c5SJed Brown ISLocalToGlobalMapping coarse_ISLG; 17800c7d97c5SJed Brown /* some other variables */ 17810c7d97c5SJed Brown PetscErrorCode ierr; 17820c7d97c5SJed Brown const MatType coarse_mat_type; 17830c7d97c5SJed Brown const PCType coarse_pc_type; 178453cdbc3dSStefano Zampini const KSPType coarse_ksp_type; 178553cdbc3dSStefano Zampini PC pc_temp; 17860c7d97c5SJed Brown PetscInt i,j,k,bs; 17873b03a366Sstefano_zampini PetscInt max_it_coarse_ksp=1; /* don't increase this value */ 1788e269702eSStefano Zampini /* verbose output viewer */ 1789e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 1790e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 17910c7d97c5SJed Brown 17920c7d97c5SJed Brown PetscFunctionBegin; 17930c7d97c5SJed Brown 17940c7d97c5SJed Brown ins_local_primal_indices = 0; 17950c7d97c5SJed Brown ins_coarse_mat_vals = 0; 17960c7d97c5SJed Brown localsizes2 = 0; 17970c7d97c5SJed Brown localdispl2 = 0; 17980c7d97c5SJed Brown temp_coarse_mat_vals = 0; 17990c7d97c5SJed Brown coarse_ISLG = 0; 18000c7d97c5SJed Brown 180153cdbc3dSStefano Zampini ierr = MPI_Comm_size(prec_comm,&size_prec_comm);CHKERRQ(ierr); 180253cdbc3dSStefano Zampini ierr = MPI_Comm_rank(prec_comm,&rank_prec_comm);CHKERRQ(ierr); 18030c7d97c5SJed Brown ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 18040c7d97c5SJed Brown 1805beed3852SStefano Zampini /* Assign global numbering to coarse dofs */ 1806beed3852SStefano Zampini { 1807a0ba757dSStefano Zampini PetscScalar one=1.,zero=0.; 1808beed3852SStefano Zampini PetscScalar *array; 1809beed3852SStefano Zampini PetscMPIInt *auxlocal_primal; 1810beed3852SStefano Zampini PetscMPIInt *auxglobal_primal; 1811beed3852SStefano Zampini PetscMPIInt *all_auxglobal_primal; 1812beed3852SStefano Zampini PetscMPIInt *all_auxglobal_primal_dummy; 1813beed3852SStefano Zampini PetscMPIInt mpi_local_primal_size = (PetscMPIInt)pcbddc->local_primal_size; 18143b03a366Sstefano_zampini PetscInt *vertices,*row_cmat_indices; 18153b03a366Sstefano_zampini PetscInt size_of_constraint; 1816beed3852SStefano Zampini 1817beed3852SStefano Zampini /* Construct needed data structures for message passing */ 1818beed3852SStefano Zampini ierr = PetscMalloc(mpi_local_primal_size*sizeof(PetscMPIInt),&pcbddc->local_primal_indices);CHKERRQ(ierr); 1819beed3852SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&pcbddc->local_primal_sizes);CHKERRQ(ierr); 1820beed3852SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 1821beed3852SStefano Zampini /* Gather local_primal_size information for all processes */ 18225619798eSStefano Zampini ierr = MPI_Allgather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,prec_comm);CHKERRQ(ierr); 1823beed3852SStefano Zampini pcbddc->replicated_primal_size = 0; 1824beed3852SStefano Zampini for (i=0; i<size_prec_comm; i++) { 1825beed3852SStefano Zampini pcbddc->local_primal_displacements[i] = pcbddc->replicated_primal_size ; 1826beed3852SStefano Zampini pcbddc->replicated_primal_size += pcbddc->local_primal_sizes[i]; 1827beed3852SStefano Zampini } 18285619798eSStefano Zampini if(rank_prec_comm == 0) { 1829beed3852SStefano Zampini /* allocate some auxiliary space */ 1830beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->replicated_primal_size*sizeof(*all_auxglobal_primal),&all_auxglobal_primal);CHKERRQ(ierr); 1831beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->replicated_primal_size*sizeof(*all_auxglobal_primal_dummy),&all_auxglobal_primal_dummy);CHKERRQ(ierr); 1832beed3852SStefano Zampini } 1833beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscMPIInt),&auxlocal_primal);CHKERRQ(ierr); 1834beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscMPIInt),&auxglobal_primal);CHKERRQ(ierr); 1835beed3852SStefano Zampini 1836beed3852SStefano 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) 1837beed3852SStefano Zampini This code fragment assumes that the number of local constraints per connected component 1838beed3852SStefano Zampini is not greater than the number of nodes defined for the connected component 1839beed3852SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 18403b03a366Sstefano_zampini /* auxlocal_primal : primal indices in local nodes numbering (internal and interface) with complete queue sorted by global ordering */ 1841beed3852SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 18423b03a366Sstefano_zampini ierr = ISGetIndices(pcbddc->ISForVertices,(const PetscInt**)&vertices);CHKERRQ(ierr); 1843beed3852SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 18443b03a366Sstefano_zampini for(i=0;i<pcbddc->n_vertices;i++) { /* note that pcbddc->n_vertices can be different from size of ISForVertices */ 18453b03a366Sstefano_zampini array[ vertices[i] ] = one; 18463b03a366Sstefano_zampini auxlocal_primal[i] = vertices[i]; 1847beed3852SStefano Zampini } 18483b03a366Sstefano_zampini ierr = ISRestoreIndices(pcbddc->ISForVertices,(const PetscInt**)&vertices);CHKERRQ(ierr); 1849beed3852SStefano Zampini for(i=0;i<pcbddc->n_constraints;i++) { 18503b03a366Sstefano_zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,pcbddc->n_vertices+i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 18513b03a366Sstefano_zampini for (j=0; j<size_of_constraint; j++) { 18523b03a366Sstefano_zampini k = row_cmat_indices[j]; 1853beed3852SStefano Zampini if( array[k] == zero ) { 1854beed3852SStefano Zampini array[k] = one; 1855beed3852SStefano Zampini auxlocal_primal[i+pcbddc->n_vertices] = k; 1856beed3852SStefano Zampini break; 1857beed3852SStefano Zampini } 1858beed3852SStefano Zampini } 18593b03a366Sstefano_zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,pcbddc->n_vertices+i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 1860beed3852SStefano Zampini } 1861beed3852SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1862a0ba757dSStefano Zampini 1863beed3852SStefano Zampini /* Now assign them a global numbering */ 1864beed3852SStefano Zampini /* auxglobal_primal contains indices in global nodes numbering (internal and interface) */ 1865beed3852SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,pcbddc->local_primal_size,auxlocal_primal,auxglobal_primal);CHKERRQ(ierr); 1866beed3852SStefano Zampini /* all_auxglobal_primal contains all primal nodes indices in global nodes numbering (internal and interface) */ 1867beed3852SStefano 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); 1868beed3852SStefano Zampini 1869beed3852SStefano Zampini /* After this block all_auxglobal_primal should contains one copy of each primal node's indices in global nodes numbering */ 1870beed3852SStefano Zampini /* It implements a function similar to PetscSortRemoveDupsInt */ 1871beed3852SStefano Zampini if(rank_prec_comm==0) { 1872beed3852SStefano Zampini /* dummy argument since PetscSortMPIInt doesn't exist! */ 1873beed3852SStefano Zampini ierr = PetscSortMPIIntWithArray(pcbddc->replicated_primal_size,all_auxglobal_primal,all_auxglobal_primal_dummy);CHKERRQ(ierr); 1874beed3852SStefano Zampini k=1; 1875beed3852SStefano Zampini j=all_auxglobal_primal[0]; /* first dof in global numbering */ 1876beed3852SStefano Zampini for(i=1;i< pcbddc->replicated_primal_size ;i++) { 1877beed3852SStefano Zampini if(j != all_auxglobal_primal[i] ) { 1878beed3852SStefano Zampini all_auxglobal_primal[k]=all_auxglobal_primal[i]; 1879beed3852SStefano Zampini k++; 1880beed3852SStefano Zampini j=all_auxglobal_primal[i]; 1881beed3852SStefano Zampini } 1882beed3852SStefano Zampini } 1883beed3852SStefano Zampini } else { 1884beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscMPIInt),&all_auxglobal_primal);CHKERRQ(ierr); 1885beed3852SStefano Zampini } 18865619798eSStefano Zampini /* We only need to broadcast the indices from 0 to pcbddc->coarse_size. Remaning elements of array all_aux_global_primal are garbage. */ 1887beed3852SStefano Zampini ierr = MPI_Bcast(all_auxglobal_primal,pcbddc->coarse_size,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 1888beed3852SStefano Zampini 1889beed3852SStefano Zampini /* Now get global coarse numbering of local primal nodes */ 1890beed3852SStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) { 1891beed3852SStefano Zampini k=0; 1892beed3852SStefano Zampini while( all_auxglobal_primal[k] != auxglobal_primal[i] ) { k++;} 1893beed3852SStefano Zampini pcbddc->local_primal_indices[i]=k; 1894beed3852SStefano Zampini } 1895e269702eSStefano Zampini if(dbg_flag) { 1896e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1897e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 1898e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1899e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 1900e269702eSStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) { 1901e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_primal_indices[%d]=%d \n",i,pcbddc->local_primal_indices[i]); 1902e269702eSStefano Zampini } 1903e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1904e269702eSStefano Zampini } 1905beed3852SStefano Zampini /* free allocated memory */ 1906beed3852SStefano Zampini ierr = PetscFree(auxlocal_primal);CHKERRQ(ierr); 1907beed3852SStefano Zampini ierr = PetscFree(auxglobal_primal);CHKERRQ(ierr); 1908beed3852SStefano Zampini ierr = PetscFree(all_auxglobal_primal);CHKERRQ(ierr); 1909e269702eSStefano Zampini if(rank_prec_comm == 0) { 1910beed3852SStefano Zampini ierr = PetscFree(all_auxglobal_primal_dummy);CHKERRQ(ierr); 1911beed3852SStefano Zampini } 1912e269702eSStefano Zampini } 1913beed3852SStefano Zampini 19140c7d97c5SJed Brown /* adapt coarse problem type */ 19150c7d97c5SJed Brown if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC && pcbddc->active_procs < MIN_PROCS_FOR_BDDC ) 19160c7d97c5SJed Brown pcbddc->coarse_problem_type = PARALLEL_BDDC; 19170c7d97c5SJed Brown 19180c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 19190c7d97c5SJed Brown 19200c7d97c5SJed Brown case(MULTILEVEL_BDDC): //we define a coarse mesh where subdomains are elements 19210c7d97c5SJed Brown { 19220c7d97c5SJed Brown /* we need additional variables */ 19230c7d97c5SJed Brown MetisInt n_subdomains,n_parts,objval,ncon,faces_nvtxs; 19240c7d97c5SJed Brown MetisInt *metis_coarse_subdivision; 19250c7d97c5SJed Brown MetisInt options[METIS_NOPTIONS]; 19260c7d97c5SJed Brown PetscMPIInt size_coarse_comm,rank_coarse_comm; 19270c7d97c5SJed Brown PetscMPIInt procs_jumps_coarse_comm; 19280c7d97c5SJed Brown PetscMPIInt *coarse_subdivision; 19290c7d97c5SJed Brown PetscMPIInt *total_count_recv; 19300c7d97c5SJed Brown PetscMPIInt *total_ranks_recv; 19310c7d97c5SJed Brown PetscMPIInt *displacements_recv; 19320c7d97c5SJed Brown PetscMPIInt *my_faces_connectivity; 19330c7d97c5SJed Brown PetscMPIInt *petsc_faces_adjncy; 19340c7d97c5SJed Brown MetisInt *faces_adjncy; 19350c7d97c5SJed Brown MetisInt *faces_xadj; 19360c7d97c5SJed Brown PetscMPIInt *number_of_faces; 19370c7d97c5SJed Brown PetscMPIInt *faces_displacements; 19380c7d97c5SJed Brown PetscInt *array_int; 19390c7d97c5SJed Brown PetscMPIInt my_faces=0; 19400c7d97c5SJed Brown PetscMPIInt total_faces=0; 19413828260eSStefano Zampini PetscInt ranks_stretching_ratio; 19420c7d97c5SJed Brown 19430c7d97c5SJed Brown /* define some quantities */ 19440c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 19450c7d97c5SJed Brown coarse_mat_type = MATIS; 19460c7d97c5SJed Brown coarse_pc_type = PCBDDC; 19473b03a366Sstefano_zampini coarse_ksp_type = KSPCHEBYCHEV; 19480c7d97c5SJed Brown 19490c7d97c5SJed Brown /* details of coarse decomposition */ 19500c7d97c5SJed Brown n_subdomains = pcbddc->active_procs; 19510c7d97c5SJed Brown n_parts = n_subdomains/pcbddc->coarsening_ratio; 19523828260eSStefano Zampini ranks_stretching_ratio = size_prec_comm/pcbddc->active_procs; 19533828260eSStefano Zampini procs_jumps_coarse_comm = pcbddc->coarsening_ratio*ranks_stretching_ratio; 19543828260eSStefano Zampini 19553828260eSStefano Zampini printf("Coarse algorithm details: \n"); 1956a0ba757dSStefano 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)); 19570c7d97c5SJed Brown 19580c7d97c5SJed Brown /* build CSR graph of subdomains' connectivity through faces */ 19590c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&array_int);CHKERRQ(ierr); 19603828260eSStefano Zampini ierr = PetscMemzero(array_int,pcis->n*sizeof(PetscInt));CHKERRQ(ierr); 19610c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){/* i=1 so I don't count myself -> faces nodes counts to 1 */ 19620c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 19630c7d97c5SJed Brown array_int[ pcis->shared[i][j] ]+=1; 19640c7d97c5SJed Brown } 19650c7d97c5SJed Brown } 19660c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){ 19670c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 19680c7d97c5SJed Brown if(array_int[ pcis->shared[i][j] ] == 1 ){ 19690c7d97c5SJed Brown my_faces++; 19700c7d97c5SJed Brown break; 19710c7d97c5SJed Brown } 19720c7d97c5SJed Brown } 19730c7d97c5SJed Brown } 19740c7d97c5SJed Brown //printf("I found %d faces.\n",my_faces); 19750c7d97c5SJed Brown 197653cdbc3dSStefano Zampini ierr = MPI_Reduce(&my_faces,&total_faces,1,MPIU_INT,MPI_SUM,master_proc,prec_comm);CHKERRQ(ierr); 19770c7d97c5SJed Brown ierr = PetscMalloc (my_faces*sizeof(PetscInt),&my_faces_connectivity);CHKERRQ(ierr); 19780c7d97c5SJed Brown my_faces=0; 19790c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){ 19800c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 19810c7d97c5SJed Brown if(array_int[ pcis->shared[i][j] ] == 1 ){ 19820c7d97c5SJed Brown my_faces_connectivity[my_faces]=pcis->neigh[i]; 19830c7d97c5SJed Brown my_faces++; 19840c7d97c5SJed Brown break; 19850c7d97c5SJed Brown } 19860c7d97c5SJed Brown } 19870c7d97c5SJed Brown } 19880c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 19890c7d97c5SJed Brown //printf("I found %d total faces.\n",total_faces); 19900c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(PetscMPIInt),&petsc_faces_adjncy);CHKERRQ(ierr); 19910c7d97c5SJed Brown ierr = PetscMalloc (size_prec_comm*sizeof(PetscMPIInt),&number_of_faces);CHKERRQ(ierr); 19920c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(MetisInt),&faces_adjncy);CHKERRQ(ierr); 19930c7d97c5SJed Brown ierr = PetscMalloc ((n_subdomains+1)*sizeof(MetisInt),&faces_xadj);CHKERRQ(ierr); 19940c7d97c5SJed Brown ierr = PetscMalloc ((size_prec_comm+1)*sizeof(PetscMPIInt),&faces_displacements);CHKERRQ(ierr); 19950c7d97c5SJed Brown } 199653cdbc3dSStefano Zampini ierr = MPI_Gather(&my_faces,1,MPIU_INT,&number_of_faces[0],1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 19970c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 19980c7d97c5SJed Brown faces_xadj[0]=0; 19990c7d97c5SJed Brown faces_displacements[0]=0; 20000c7d97c5SJed Brown j=0; 20010c7d97c5SJed Brown for(i=1;i<size_prec_comm+1;i++) { 20020c7d97c5SJed Brown faces_displacements[i]=faces_displacements[i-1]+number_of_faces[i-1]; 20030c7d97c5SJed Brown if(number_of_faces[i-1]) { 20040c7d97c5SJed Brown j++; 20050c7d97c5SJed Brown faces_xadj[j]=faces_xadj[j-1]+number_of_faces[i-1]; 20060c7d97c5SJed Brown } 20070c7d97c5SJed Brown } 20080c7d97c5SJed Brown printf("The J I count is %d and should be %d\n",j,n_subdomains); 20090c7d97c5SJed Brown printf("Total faces seem %d and should be %d\n",faces_xadj[j],total_faces); 20100c7d97c5SJed Brown } 201153cdbc3dSStefano 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); 20120c7d97c5SJed Brown ierr = PetscFree(my_faces_connectivity);CHKERRQ(ierr); 20130c7d97c5SJed Brown ierr = PetscFree(array_int);CHKERRQ(ierr); 20140c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 20153828260eSStefano Zampini for(i=0;i<total_faces;i++) faces_adjncy[i]=(MetisInt)(petsc_faces_adjncy[i]/ranks_stretching_ratio); /* cast to MetisInt */ 20163828260eSStefano Zampini printf("This is the face connectivity (actual ranks)\n"); 20170c7d97c5SJed Brown for(i=0;i<n_subdomains;i++){ 20180c7d97c5SJed Brown printf("proc %d is connected with \n",i); 20190c7d97c5SJed Brown for(j=faces_xadj[i];j<faces_xadj[i+1];j++) 20200c7d97c5SJed Brown printf("%d ",faces_adjncy[j]); 20210c7d97c5SJed Brown printf("\n"); 20220c7d97c5SJed Brown } 20230c7d97c5SJed Brown ierr = PetscFree(faces_displacements);CHKERRQ(ierr); 20240c7d97c5SJed Brown ierr = PetscFree(number_of_faces);CHKERRQ(ierr); 20250c7d97c5SJed Brown ierr = PetscFree(petsc_faces_adjncy);CHKERRQ(ierr); 20260c7d97c5SJed Brown } 20270c7d97c5SJed Brown 20280c7d97c5SJed Brown if( rank_prec_comm == master_proc ) { 20290c7d97c5SJed Brown 20303828260eSStefano Zampini PetscInt heuristic_for_metis=3; 20313828260eSStefano Zampini 20320c7d97c5SJed Brown ncon=1; 20330c7d97c5SJed Brown faces_nvtxs=n_subdomains; 20340c7d97c5SJed Brown /* partition graoh induced by face connectivity */ 20350c7d97c5SJed Brown ierr = PetscMalloc (n_subdomains*sizeof(MetisInt),&metis_coarse_subdivision);CHKERRQ(ierr); 20360c7d97c5SJed Brown ierr = METIS_SetDefaultOptions(options); 20370c7d97c5SJed Brown /* we need a contiguous partition of the coarse mesh */ 20380c7d97c5SJed Brown options[METIS_OPTION_CONTIG]=1; 20390c7d97c5SJed Brown options[METIS_OPTION_DBGLVL]=1; 20400c7d97c5SJed Brown options[METIS_OPTION_NITER]=30; 20410c7d97c5SJed Brown //options[METIS_OPTION_NCUTS]=1; 20423828260eSStefano Zampini printf("METIS PART GRAPH\n"); 20433828260eSStefano Zampini if(n_subdomains>n_parts*heuristic_for_metis) { 20443828260eSStefano Zampini printf("Using Kway\n"); 20453828260eSStefano Zampini options[METIS_OPTION_IPTYPE]=METIS_IPTYPE_EDGE; 20463828260eSStefano Zampini options[METIS_OPTION_OBJTYPE]=METIS_OBJTYPE_CUT; 20470c7d97c5SJed Brown ierr = METIS_PartGraphKway(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 20483828260eSStefano Zampini } else { 20493828260eSStefano Zampini printf("Using Recursive\n"); 20503828260eSStefano Zampini ierr = METIS_PartGraphRecursive(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 20513828260eSStefano Zampini } 20520c7d97c5SJed 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); 20533828260eSStefano Zampini printf("Partition done!\n"); 20540c7d97c5SJed Brown ierr = PetscFree(faces_xadj);CHKERRQ(ierr); 20550c7d97c5SJed Brown ierr = PetscFree(faces_adjncy);CHKERRQ(ierr); 20560c7d97c5SJed Brown coarse_subdivision = (PetscMPIInt*)calloc(size_prec_comm,sizeof(PetscMPIInt)); /* calloc for contiguous memory since we need to scatter these values later */ 20570c7d97c5SJed Brown /* copy/cast values avoiding possible type conflicts between PETSc, MPI and METIS */ 20583828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) coarse_subdivision[i]=MPI_PROC_NULL; 20593828260eSStefano Zampini for(i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=(PetscInt)(metis_coarse_subdivision[i]); 20600c7d97c5SJed Brown ierr = PetscFree(metis_coarse_subdivision);CHKERRQ(ierr); 20610c7d97c5SJed Brown } 20620c7d97c5SJed Brown 20630c7d97c5SJed Brown /* Create new communicator for coarse problem splitting the old one */ 20640c7d97c5SJed Brown if( !(rank_prec_comm%procs_jumps_coarse_comm) && rank_prec_comm < procs_jumps_coarse_comm*n_parts ){ 20650c7d97c5SJed Brown coarse_color=0; //for communicator splitting 20660c7d97c5SJed Brown active_rank=rank_prec_comm; //for insertion of matrix values 20670c7d97c5SJed Brown } 20680c7d97c5SJed Brown // procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 20690c7d97c5SJed Brown // key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator 207053cdbc3dSStefano Zampini ierr = MPI_Comm_split(prec_comm,coarse_color,rank_prec_comm,&coarse_comm);CHKERRQ(ierr); 20710c7d97c5SJed Brown 20720c7d97c5SJed Brown if( coarse_color == 0 ) { 207353cdbc3dSStefano Zampini ierr = MPI_Comm_size(coarse_comm,&size_coarse_comm);CHKERRQ(ierr); 207453cdbc3dSStefano Zampini ierr = MPI_Comm_rank(coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 20753828260eSStefano Zampini printf("Details of coarse comm\n"); 20763828260eSStefano Zampini printf("size = %d, myrank = %d\n",size_coarse_comm,rank_coarse_comm); 20773828260eSStefano Zampini printf("jumps = %d, coarse_color = %d, n_parts = %d\n",procs_jumps_coarse_comm,coarse_color,n_parts); 20780c7d97c5SJed Brown } else { 20790c7d97c5SJed Brown rank_coarse_comm = MPI_PROC_NULL; 20800c7d97c5SJed Brown } 20810c7d97c5SJed Brown 20820c7d97c5SJed Brown /* master proc take care of arranging and distributing coarse informations */ 20830c7d97c5SJed Brown if(rank_coarse_comm == master_proc) { 20840c7d97c5SJed Brown ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&displacements_recv);CHKERRQ(ierr); 20850c7d97c5SJed Brown //ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&total_count_recv);CHKERRQ(ierr); 20860c7d97c5SJed Brown //ierr = PetscMalloc (n_subdomains*sizeof(PetscMPIInt),&total_ranks_recv);CHKERRQ(ierr); 20870c7d97c5SJed Brown total_count_recv = (PetscMPIInt*)calloc(size_prec_comm,sizeof(PetscMPIInt)); 20880c7d97c5SJed Brown total_ranks_recv = (PetscMPIInt*)calloc(n_subdomains,sizeof(PetscMPIInt)); 20890c7d97c5SJed Brown /* some initializations */ 20900c7d97c5SJed Brown displacements_recv[0]=0; 20910c7d97c5SJed Brown //PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt)); not needed -> calloc initializes to zero 20920c7d97c5SJed Brown /* count from how many processes the j-th process of the coarse decomposition will receive data */ 20930c7d97c5SJed Brown for(j=0;j<size_coarse_comm;j++) 20943828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) 20950c7d97c5SJed Brown if(coarse_subdivision[i]==j) 20960c7d97c5SJed Brown total_count_recv[j]++; 20970c7d97c5SJed Brown /* displacements needed for scatterv of total_ranks_recv */ 20980c7d97c5SJed Brown for(i=1;i<size_coarse_comm;i++) displacements_recv[i]=displacements_recv[i-1]+total_count_recv[i-1]; 20990c7d97c5SJed Brown /* Now fill properly total_ranks_recv -> each coarse process will receive the ranks (in prec_comm communicator) of its friend (sending) processes */ 21000c7d97c5SJed Brown ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 21010c7d97c5SJed Brown for(j=0;j<size_coarse_comm;j++) { 21023828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) { 21030c7d97c5SJed Brown if(coarse_subdivision[i]==j) { 21040c7d97c5SJed Brown total_ranks_recv[displacements_recv[j]+total_count_recv[j]]=i; 21053828260eSStefano Zampini total_count_recv[j]+=1; 21060c7d97c5SJed Brown } 21070c7d97c5SJed Brown } 21080c7d97c5SJed Brown } 21093828260eSStefano Zampini for(j=0;j<size_coarse_comm;j++) { 21103828260eSStefano Zampini printf("process %d in new rank will receive from %d processes (original ranks follows)\n",j,total_count_recv[j]); 21113828260eSStefano Zampini for(i=0;i<total_count_recv[j];i++) { 21123828260eSStefano Zampini printf("%d ",total_ranks_recv[displacements_recv[j]+i]); 21133828260eSStefano Zampini } 21143828260eSStefano Zampini printf("\n"); 21153828260eSStefano Zampini } 21160c7d97c5SJed Brown 21170c7d97c5SJed Brown /* identify new decomposition in terms of ranks in the old communicator */ 21183828260eSStefano Zampini for(i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=coarse_subdivision[ranks_stretching_ratio*i]*procs_jumps_coarse_comm; 21190c7d97c5SJed Brown printf("coarse_subdivision in old end new ranks\n"); 21200c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) 21213828260eSStefano Zampini if(coarse_subdivision[i]!=MPI_PROC_NULL) { 21223828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]/procs_jumps_coarse_comm); 21233828260eSStefano Zampini } else { 21243828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]); 21253828260eSStefano Zampini } 21260c7d97c5SJed Brown printf("\n"); 21270c7d97c5SJed Brown } 21280c7d97c5SJed Brown 21290c7d97c5SJed Brown /* Scatter new decomposition for send details */ 213053cdbc3dSStefano Zampini ierr = MPI_Scatter(&coarse_subdivision[0],1,MPIU_INT,&rank_coarse_proc_send_to,1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 21310c7d97c5SJed Brown /* Scatter receiving details to members of coarse decomposition */ 21320c7d97c5SJed Brown if( coarse_color == 0) { 213353cdbc3dSStefano Zampini ierr = MPI_Scatter(&total_count_recv[0],1,MPIU_INT,&count_recv,1,MPIU_INT,master_proc,coarse_comm);CHKERRQ(ierr); 21340c7d97c5SJed Brown ierr = PetscMalloc (count_recv*sizeof(PetscMPIInt),&ranks_recv);CHKERRQ(ierr); 213553cdbc3dSStefano 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); 21360c7d97c5SJed Brown } 21370c7d97c5SJed Brown 21380c7d97c5SJed Brown //printf("I will send my matrix data to proc %d\n",rank_coarse_proc_send_to); 21390c7d97c5SJed Brown //if(coarse_color == 0) { 21400c7d97c5SJed Brown // printf("I will receive some matrix data from %d processes (ranks follows)\n",count_recv); 21410c7d97c5SJed Brown // for(i=0;i<count_recv;i++) 21420c7d97c5SJed Brown // printf("%d ",ranks_recv[i]); 21430c7d97c5SJed Brown // printf("\n"); 21440c7d97c5SJed Brown //} 21450c7d97c5SJed Brown 21460c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 21470c7d97c5SJed Brown //ierr = PetscFree(coarse_subdivision);CHKERRQ(ierr); 21480c7d97c5SJed Brown //ierr = PetscFree(total_count_recv);CHKERRQ(ierr); 21490c7d97c5SJed Brown //ierr = PetscFree(total_ranks_recv);CHKERRQ(ierr); 21500c7d97c5SJed Brown free(coarse_subdivision); 21510c7d97c5SJed Brown free(total_count_recv); 21520c7d97c5SJed Brown free(total_ranks_recv); 21530c7d97c5SJed Brown ierr = PetscFree(displacements_recv);CHKERRQ(ierr); 21540c7d97c5SJed Brown } 21550c7d97c5SJed Brown break; 21560c7d97c5SJed Brown } 21570c7d97c5SJed Brown 21580c7d97c5SJed Brown case(REPLICATED_BDDC): 21590c7d97c5SJed Brown 21600c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 21610c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 21620c7d97c5SJed Brown coarse_pc_type = PCLU; 216353cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 21640c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 21650c7d97c5SJed Brown active_rank = rank_prec_comm; 21660c7d97c5SJed Brown break; 21670c7d97c5SJed Brown 21680c7d97c5SJed Brown case(PARALLEL_BDDC): 21690c7d97c5SJed Brown 21700c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 21710c7d97c5SJed Brown coarse_mat_type = MATMPIAIJ; 21720c7d97c5SJed Brown coarse_pc_type = PCREDUNDANT; 217353cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 21740c7d97c5SJed Brown coarse_comm = prec_comm; 21750c7d97c5SJed Brown active_rank = rank_prec_comm; 21760c7d97c5SJed Brown break; 21770c7d97c5SJed Brown 21780c7d97c5SJed Brown case(SEQUENTIAL_BDDC): 21790c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 21800c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 21810c7d97c5SJed Brown coarse_pc_type = PCLU; 218253cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 21830c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 21840c7d97c5SJed Brown active_rank = master_proc; 21850c7d97c5SJed Brown break; 21860c7d97c5SJed Brown } 21870c7d97c5SJed Brown 21880c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 21890c7d97c5SJed Brown 21900c7d97c5SJed Brown case(SCATTERS_BDDC): 21910c7d97c5SJed Brown { 21920c7d97c5SJed Brown if(pcbddc->coarse_problem_type==MULTILEVEL_BDDC) { 21930c7d97c5SJed Brown 21940c7d97c5SJed Brown PetscMPIInt send_size; 21950c7d97c5SJed Brown PetscInt *aux_ins_indices; 21960c7d97c5SJed Brown PetscInt ii,jj; 21970c7d97c5SJed Brown MPI_Request *requests; 21980c7d97c5SJed Brown 21990c7d97c5SJed Brown /* allocate auxiliary space */ 22005619798eSStefano Zampini ierr = PetscMalloc (pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 22015619798eSStefano 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); 22020c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->coarse_size*sizeof(PetscInt),&aux_ins_indices);CHKERRQ(ierr); 22030c7d97c5SJed Brown ierr = PetscMemzero(aux_ins_indices,pcbddc->coarse_size*sizeof(PetscInt));CHKERRQ(ierr); 22040c7d97c5SJed Brown /* allocate stuffs for message massing */ 22050c7d97c5SJed Brown ierr = PetscMalloc ( (count_recv+1)*sizeof(MPI_Request),&requests);CHKERRQ(ierr); 22060c7d97c5SJed Brown for(i=0;i<count_recv+1;i++) requests[i]=MPI_REQUEST_NULL; 22070c7d97c5SJed Brown ierr = PetscMalloc ( count_recv*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 22080c7d97c5SJed Brown ierr = PetscMalloc ( count_recv*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 22090c7d97c5SJed Brown /* fill up quantities */ 22100c7d97c5SJed Brown j=0; 22110c7d97c5SJed Brown for(i=0;i<count_recv;i++){ 22120c7d97c5SJed Brown ii = ranks_recv[i]; 22130c7d97c5SJed Brown localsizes2[i]=pcbddc->local_primal_sizes[ii]*pcbddc->local_primal_sizes[ii]; 22140c7d97c5SJed Brown localdispl2[i]=j; 22150c7d97c5SJed Brown j+=localsizes2[i]; 22160c7d97c5SJed Brown jj = pcbddc->local_primal_displacements[ii]; 22170c7d97c5SJed 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 22180c7d97c5SJed Brown } 22190c7d97c5SJed Brown //printf("aux_ins_indices 1\n"); 22200c7d97c5SJed Brown //for(i=0;i<pcbddc->coarse_size;i++) 22210c7d97c5SJed Brown // printf("%d ",aux_ins_indices[i]); 22220c7d97c5SJed Brown //printf("\n"); 22230c7d97c5SJed Brown /* temp_coarse_mat_vals used to store temporarly received matrix values */ 22240c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 22250c7d97c5SJed Brown /* evaluate how many values I will insert in coarse mat */ 22260c7d97c5SJed Brown ins_local_primal_size=0; 22270c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++) 22280c7d97c5SJed Brown if(aux_ins_indices[i]) 22290c7d97c5SJed Brown ins_local_primal_size++; 22300c7d97c5SJed Brown /* evaluate indices I will insert in coarse mat */ 22310c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 22320c7d97c5SJed Brown j=0; 22330c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++) 22340c7d97c5SJed Brown if(aux_ins_indices[i]) 22350c7d97c5SJed Brown ins_local_primal_indices[j++]=i; 22360c7d97c5SJed Brown /* use aux_ins_indices to realize a global to local mapping */ 22370c7d97c5SJed Brown j=0; 22380c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++){ 22390c7d97c5SJed Brown if(aux_ins_indices[i]==0){ 22400c7d97c5SJed Brown aux_ins_indices[i]=-1; 22410c7d97c5SJed Brown } else { 22420c7d97c5SJed Brown aux_ins_indices[i]=j; 22430c7d97c5SJed Brown j++; 22440c7d97c5SJed Brown } 22450c7d97c5SJed Brown } 22460c7d97c5SJed Brown 22470c7d97c5SJed Brown //printf("New details localsizes2 localdispl2\n"); 22480c7d97c5SJed Brown //for(i=0;i<count_recv;i++) 22490c7d97c5SJed Brown // printf("(%d %d) ",localsizes2[i],localdispl2[i]); 22500c7d97c5SJed Brown //printf("\n"); 22510c7d97c5SJed Brown //printf("aux_ins_indices 2\n"); 22520c7d97c5SJed Brown //for(i=0;i<pcbddc->coarse_size;i++) 22530c7d97c5SJed Brown // printf("%d ",aux_ins_indices[i]); 22540c7d97c5SJed Brown //printf("\n"); 22550c7d97c5SJed Brown //printf("ins_local_primal_indices\n"); 22560c7d97c5SJed Brown //for(i=0;i<ins_local_primal_size;i++) 22570c7d97c5SJed Brown // printf("%d ",ins_local_primal_indices[i]); 22580c7d97c5SJed Brown //printf("\n"); 22590c7d97c5SJed Brown //printf("coarse_submat_vals\n"); 22600c7d97c5SJed Brown //for(i=0;i<pcbddc->local_primal_size;i++) 22610c7d97c5SJed Brown // for(j=0;j<pcbddc->local_primal_size;j++) 22620c7d97c5SJed 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]); 22630c7d97c5SJed Brown //printf("\n"); 22640c7d97c5SJed Brown 22650c7d97c5SJed Brown /* processes partecipating in coarse problem receive matrix data from their friends */ 226653cdbc3dSStefano 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); 22670c7d97c5SJed Brown if(rank_coarse_proc_send_to != MPI_PROC_NULL ) { 22680c7d97c5SJed Brown send_size=pcbddc->local_primal_size*pcbddc->local_primal_size; 226953cdbc3dSStefano 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); 22700c7d97c5SJed Brown } 227153cdbc3dSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 22720c7d97c5SJed Brown 22730c7d97c5SJed Brown //if(coarse_color == 0) { 22740c7d97c5SJed Brown // printf("temp_coarse_mat_vals\n"); 22750c7d97c5SJed Brown // for(k=0;k<count_recv;k++){ 22760c7d97c5SJed Brown // printf("---- %d ----\n",ranks_recv[k]); 22770c7d97c5SJed Brown // for(i=0;i<pcbddc->local_primal_sizes[ranks_recv[k]];i++) 22780c7d97c5SJed Brown // for(j=0;j<pcbddc->local_primal_sizes[ranks_recv[k]];j++) 22790c7d97c5SJed 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]); 22800c7d97c5SJed Brown // printf("\n"); 22810c7d97c5SJed Brown // } 22820c7d97c5SJed Brown //} 22830c7d97c5SJed Brown /* calculate data to insert in coarse mat */ 22840c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 22850c7d97c5SJed Brown PetscMemzero(ins_coarse_mat_vals,ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar)); 22860c7d97c5SJed Brown 22870c7d97c5SJed Brown PetscMPIInt rr,kk,lps,lpd; 22880c7d97c5SJed Brown PetscInt row_ind,col_ind; 22890c7d97c5SJed Brown for(k=0;k<count_recv;k++){ 22900c7d97c5SJed Brown rr = ranks_recv[k]; 22910c7d97c5SJed Brown kk = localdispl2[k]; 22920c7d97c5SJed Brown lps = pcbddc->local_primal_sizes[rr]; 22930c7d97c5SJed Brown lpd = pcbddc->local_primal_displacements[rr]; 22940c7d97c5SJed Brown //printf("Inserting the following indices (received from %d)\n",rr); 22950c7d97c5SJed Brown for(j=0;j<lps;j++){ 22960c7d97c5SJed Brown col_ind=aux_ins_indices[pcbddc->replicated_local_primal_indices[lpd+j]]; 22970c7d97c5SJed Brown for(i=0;i<lps;i++){ 22980c7d97c5SJed Brown row_ind=aux_ins_indices[pcbddc->replicated_local_primal_indices[lpd+i]]; 22990c7d97c5SJed Brown //printf("%d %d\n",row_ind,col_ind); 23000c7d97c5SJed Brown ins_coarse_mat_vals[col_ind*ins_local_primal_size+row_ind]+=temp_coarse_mat_vals[kk+j*lps+i]; 23010c7d97c5SJed Brown } 23020c7d97c5SJed Brown } 23030c7d97c5SJed Brown } 23040c7d97c5SJed Brown ierr = PetscFree(requests);CHKERRQ(ierr); 23050c7d97c5SJed Brown ierr = PetscFree(aux_ins_indices);CHKERRQ(ierr); 23060c7d97c5SJed Brown ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr); 23070c7d97c5SJed Brown if(coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 23080c7d97c5SJed Brown 23090c7d97c5SJed Brown /* create local to global mapping needed by coarse MATIS */ 23100c7d97c5SJed Brown { 23110c7d97c5SJed Brown IS coarse_IS; 231253cdbc3dSStefano Zampini if(coarse_comm != MPI_COMM_NULL ) ierr = MPI_Comm_free(&coarse_comm);CHKERRQ(ierr); 23130c7d97c5SJed Brown coarse_comm = prec_comm; 23140c7d97c5SJed Brown active_rank=rank_prec_comm; 23150c7d97c5SJed Brown ierr = ISCreateGeneral(coarse_comm,ins_local_primal_size,ins_local_primal_indices,PETSC_COPY_VALUES,&coarse_IS);CHKERRQ(ierr); 23160c7d97c5SJed Brown ierr = ISLocalToGlobalMappingCreateIS(coarse_IS,&coarse_ISLG);CHKERRQ(ierr); 23170c7d97c5SJed Brown ierr = ISDestroy(&coarse_IS);CHKERRQ(ierr); 23180c7d97c5SJed Brown } 23190c7d97c5SJed Brown } 23200c7d97c5SJed Brown if(pcbddc->coarse_problem_type==PARALLEL_BDDC) { 23210c7d97c5SJed Brown /* arrays for values insertion */ 23220c7d97c5SJed Brown ins_local_primal_size = pcbddc->local_primal_size; 23230c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscMPIInt),&ins_local_primal_indices);CHKERRQ(ierr); 23240c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 23250c7d97c5SJed Brown for(j=0;j<ins_local_primal_size;j++){ 23260c7d97c5SJed Brown ins_local_primal_indices[j]=pcbddc->local_primal_indices[j]; 23270c7d97c5SJed 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]; 23280c7d97c5SJed Brown } 23290c7d97c5SJed Brown } 23300c7d97c5SJed Brown break; 23310c7d97c5SJed Brown 23320c7d97c5SJed Brown } 23330c7d97c5SJed Brown 23340c7d97c5SJed Brown case(GATHERS_BDDC): 23350c7d97c5SJed Brown { 23360c7d97c5SJed Brown 23370c7d97c5SJed Brown PetscMPIInt mysize,mysize2; 23380c7d97c5SJed Brown 23390c7d97c5SJed Brown if(rank_prec_comm==active_rank) { 23400c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 23410c7d97c5SJed Brown pcbddc->replicated_local_primal_values = (PetscScalar*)calloc(pcbddc->replicated_primal_size,sizeof(PetscScalar)); 23420c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 23430c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 23440c7d97c5SJed Brown /* arrays for values insertion */ 23450c7d97c5SJed Brown ins_local_primal_size = pcbddc->coarse_size; 23460c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscMPIInt),&ins_local_primal_indices);CHKERRQ(ierr); 23470c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 23480c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) localsizes2[i]=pcbddc->local_primal_sizes[i]*pcbddc->local_primal_sizes[i]; 23490c7d97c5SJed Brown localdispl2[0]=0; 23500c7d97c5SJed Brown for(i=1;i<size_prec_comm;i++) localdispl2[i]=localsizes2[i-1]+localdispl2[i-1]; 23510c7d97c5SJed Brown j=0; 23520c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) j+=localsizes2[i]; 23530c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 23540c7d97c5SJed Brown } 23550c7d97c5SJed Brown 23560c7d97c5SJed Brown mysize=pcbddc->local_primal_size; 23570c7d97c5SJed Brown mysize2=pcbddc->local_primal_size*pcbddc->local_primal_size; 23580c7d97c5SJed Brown if(pcbddc->coarse_problem_type == SEQUENTIAL_BDDC){ 235953cdbc3dSStefano 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); 236053cdbc3dSStefano 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); 23610c7d97c5SJed Brown } else { 236253cdbc3dSStefano 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); 236353cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,prec_comm);CHKERRQ(ierr); 23640c7d97c5SJed Brown } 23650c7d97c5SJed Brown 23660c7d97c5SJed Brown /* free data structures no longer needed and allocate some space which will be needed in BDDC application */ 23670c7d97c5SJed Brown if(rank_prec_comm==active_rank) { 23680c7d97c5SJed Brown PetscInt offset,offset2,row_ind,col_ind; 23690c7d97c5SJed Brown for(j=0;j<ins_local_primal_size;j++){ 23700c7d97c5SJed Brown ins_local_primal_indices[j]=j; 23710c7d97c5SJed Brown for(i=0;i<ins_local_primal_size;i++) ins_coarse_mat_vals[j*ins_local_primal_size+i]=0.0; 23720c7d97c5SJed Brown } 23730c7d97c5SJed Brown for(k=0;k<size_prec_comm;k++){ 23740c7d97c5SJed Brown offset=pcbddc->local_primal_displacements[k]; 23750c7d97c5SJed Brown offset2=localdispl2[k]; 23760c7d97c5SJed Brown for(j=0;j<pcbddc->local_primal_sizes[k];j++){ 23770c7d97c5SJed Brown col_ind=pcbddc->replicated_local_primal_indices[offset+j]; 23780c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_sizes[k];i++){ 23790c7d97c5SJed Brown row_ind=pcbddc->replicated_local_primal_indices[offset+i]; 23800c7d97c5SJed Brown ins_coarse_mat_vals[col_ind*pcbddc->coarse_size+row_ind]+=temp_coarse_mat_vals[offset2+j*pcbddc->local_primal_sizes[k]+i]; 23810c7d97c5SJed Brown } 23820c7d97c5SJed Brown } 23830c7d97c5SJed Brown } 23840c7d97c5SJed Brown } 23850c7d97c5SJed Brown break; 23860c7d97c5SJed Brown }//switch on coarse problem and communications associated with finished 23870c7d97c5SJed Brown } 23880c7d97c5SJed Brown 23890c7d97c5SJed Brown /* Now create and fill up coarse matrix */ 23900c7d97c5SJed Brown if( rank_prec_comm == active_rank ) { 23910c7d97c5SJed Brown if(pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 23920c7d97c5SJed Brown ierr = MatCreate(coarse_comm,&pcbddc->coarse_mat);CHKERRQ(ierr); 23930c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_mat,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size);CHKERRQ(ierr); 23940c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_mat,coarse_mat_type);CHKERRQ(ierr); 23953b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 23960c7d97c5SJed Brown ierr = MatSetOption(pcbddc->coarse_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); //local values stored in column major 23973b03a366Sstefano_zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 23980c7d97c5SJed Brown } else { 23990c7d97c5SJed Brown Mat matis_coarse_local_mat; 24000c7d97c5SJed Brown ierr = MatCreateIS(coarse_comm,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_ISLG,&pcbddc->coarse_mat);CHKERRQ(ierr); 24013b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 24020c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 24033b03a366Sstefano_zampini ierr = MatSetUp(matis_coarse_local_mat);CHKERRQ(ierr); 24040c7d97c5SJed Brown ierr = MatSetOption(matis_coarse_local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); //local values stored in column major 2405a0ba757dSStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 24060c7d97c5SJed Brown } 2407a0ba757dSStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 24080c7d97c5SJed 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); 24090c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24100c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24110c7d97c5SJed Brown if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 24120c7d97c5SJed Brown Mat matis_coarse_local_mat; 24130c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 24140c7d97c5SJed Brown ierr = MatSetBlockSize(matis_coarse_local_mat,bs);CHKERRQ(ierr); 24150c7d97c5SJed Brown } 24160c7d97c5SJed Brown 24170c7d97c5SJed Brown ierr = MatGetVecs(pcbddc->coarse_mat,&pcbddc->coarse_vec,&pcbddc->coarse_rhs);CHKERRQ(ierr); 24180c7d97c5SJed Brown /* Preconditioner for coarse problem */ 241953cdbc3dSStefano Zampini ierr = KSPCreate(coarse_comm,&pcbddc->coarse_ksp);CHKERRQ(ierr); 242053cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 242153cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 24223b03a366Sstefano_zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,max_it_coarse_ksp);CHKERRQ(ierr); 242353cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 242453cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 242553cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 24260c7d97c5SJed Brown /* Allow user's customization */ 242753cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 24280c7d97c5SJed Brown /* Set Up PC for coarse problem BDDC */ 242953cdbc3dSStefano Zampini if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2430e269702eSStefano Zampini if(dbg_flag) { 2431e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------Setting up a new level---------------\n");CHKERRQ(ierr); 2432e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2433e269702eSStefano Zampini } 243453cdbc3dSStefano Zampini ierr = PCBDDCSetCoarseProblemType(pc_temp,MULTILEVEL_BDDC);CHKERRQ(ierr); 243553cdbc3dSStefano Zampini } 243653cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 24375619798eSStefano Zampini if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 24385619798eSStefano Zampini if(dbg_flag) { 24395619798eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------New level set------------------------\n");CHKERRQ(ierr); 24405619798eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 24415619798eSStefano Zampini } 24425619798eSStefano Zampini } 24430c7d97c5SJed Brown } 24440c7d97c5SJed Brown if(pcbddc->coarse_communications_type == SCATTERS_BDDC) { 24450c7d97c5SJed Brown IS local_IS,global_IS; 24460c7d97c5SJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&local_IS);CHKERRQ(ierr); 24470c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_indices,PETSC_COPY_VALUES,&global_IS);CHKERRQ(ierr); 24480c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_P,local_IS,pcbddc->coarse_vec,global_IS,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 24490c7d97c5SJed Brown ierr = ISDestroy(&local_IS);CHKERRQ(ierr); 24500c7d97c5SJed Brown ierr = ISDestroy(&global_IS);CHKERRQ(ierr); 24510c7d97c5SJed Brown } 24520c7d97c5SJed Brown 24530c7d97c5SJed Brown 24543b03a366Sstefano_zampini /* Evaluate condition number of coarse problem for cheby (and verbose output if requested) */ 24553b03a366Sstefano_zampini if( pcbddc->coarse_problem_type == MULTILEVEL_BDDC && rank_prec_comm == active_rank ) { 24560c7d97c5SJed Brown PetscScalar m_one=-1.0; 24575619798eSStefano Zampini PetscReal infty_error,lambda_min,lambda_max,kappa_2; 24583b03a366Sstefano_zampini const KSPType check_ksp_type=KSPGMRES; 24590c7d97c5SJed Brown 24605619798eSStefano Zampini /* change coarse ksp object to an iterative method suitable for extreme eigenvalues' estimation */ 24613b03a366Sstefano_zampini ierr = KSPSetType(pcbddc->coarse_ksp,check_ksp_type);CHKERRQ(ierr); 2462d49ef151SStefano Zampini ierr = KSPSetComputeSingularValues(pcbddc->coarse_ksp,PETSC_TRUE);CHKERRQ(ierr); 24635619798eSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,1.e-8,1.e-8,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 24645619798eSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 2465d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->coarse_rhs,PETSC_NULL);CHKERRQ(ierr); 2466d49ef151SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 2467d49ef151SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,pcbddc->coarse_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 2468d49ef151SStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,pcbddc->coarse_rhs,pcbddc->coarse_rhs);CHKERRQ(ierr); 2469d49ef151SStefano Zampini ierr = KSPComputeExtremeSingularValues(pcbddc->coarse_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); 24703b03a366Sstefano_zampini if(dbg_flag) { 24715619798eSStefano Zampini kappa_2=lambda_max/lambda_min; 24725619798eSStefano Zampini ierr = KSPGetIterationNumber(pcbddc->coarse_ksp,&k);CHKERRQ(ierr); 2473d49ef151SStefano Zampini ierr = VecAXPY(pcbddc->coarse_rhs,m_one,pcbddc->coarse_vec);CHKERRQ(ierr); 2474d49ef151SStefano Zampini ierr = VecNorm(pcbddc->coarse_rhs,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 24753b03a366Sstefano_zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem condition number estimated with %d iterations of %s is: % 1.14e\n",k,check_ksp_type,kappa_2);CHKERRQ(ierr); 2476e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues: % 1.14e %1.14e\n",lambda_min,lambda_max);CHKERRQ(ierr); 2477e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem infty_error: %1.14e\n",infty_error);CHKERRQ(ierr); 24783b03a366Sstefano_zampini } 24795619798eSStefano Zampini /* restore coarse ksp to default values */ 2480d49ef151SStefano Zampini ierr = KSPSetComputeSingularValues(pcbddc->coarse_ksp,PETSC_FALSE);CHKERRQ(ierr); 24815619798eSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 24823b03a366Sstefano_zampini ierr = KSPChebychevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 24833b03a366Sstefano_zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,max_it_coarse_ksp);CHKERRQ(ierr); 24845619798eSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 24855619798eSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 248653cdbc3dSStefano Zampini } 24870c7d97c5SJed Brown 24880c7d97c5SJed Brown /* free data structures no longer needed */ 24890c7d97c5SJed Brown if(coarse_ISLG) { ierr = ISLocalToGlobalMappingDestroy(&coarse_ISLG);CHKERRQ(ierr); } 24900c7d97c5SJed Brown if(ins_local_primal_indices) { ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); } 24910c7d97c5SJed Brown if(ins_coarse_mat_vals) { ierr = PetscFree(ins_coarse_mat_vals);CHKERRQ(ierr);} 24920c7d97c5SJed Brown if(localsizes2) { ierr = PetscFree(localsizes2);CHKERRQ(ierr);} 24930c7d97c5SJed Brown if(localdispl2) { ierr = PetscFree(localdispl2);CHKERRQ(ierr);} 24940c7d97c5SJed Brown if(temp_coarse_mat_vals) { ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr);} 24950c7d97c5SJed Brown 24960c7d97c5SJed Brown PetscFunctionReturn(0); 24970c7d97c5SJed Brown } 24980c7d97c5SJed Brown 24990c7d97c5SJed Brown #undef __FUNCT__ 25000c7d97c5SJed Brown #define __FUNCT__ "PCBDDCManageLocalBoundaries" 250153cdbc3dSStefano Zampini static PetscErrorCode PCBDDCManageLocalBoundaries(PC pc) 25020c7d97c5SJed Brown { 25030c7d97c5SJed Brown 25040c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 25050c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 25060c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 25070c7d97c5SJed Brown PCBDDCGraph mat_graph; 25080c7d97c5SJed Brown Mat mat_adj; 25093b03a366Sstefano_zampini PetscInt **neighbours_set; 2510a0ba757dSStefano Zampini PetscInt *queue_in_global_numbering; 25113b03a366Sstefano_zampini PetscInt bs,ierr,i,j,s,k,iindex,neumann_bsize,dirichlet_bsize; 25123b03a366Sstefano_zampini PetscInt total_counts,nodes_touched=0,where_values=1,vertex_size; 25133b03a366Sstefano_zampini PetscMPIInt adapt_interface=0,adapt_interface_reduced=0; 25143b03a366Sstefano_zampini PetscBool same_set,flg_row; 25153b03a366Sstefano_zampini PetscBool symmetrize_rowij=PETSC_TRUE,compressed_rowij=PETSC_FALSE; 2516a0ba757dSStefano Zampini MPI_Comm interface_comm=((PetscObject)pc)->comm; 25173b03a366Sstefano_zampini PetscBool use_faces=PETSC_FALSE,use_edges=PETSC_FALSE; 25183b03a366Sstefano_zampini const PetscInt *neumann_nodes; 25193b03a366Sstefano_zampini const PetscInt *dirichlet_nodes; 25200c7d97c5SJed Brown 25210c7d97c5SJed Brown PetscFunctionBegin; 2522a0ba757dSStefano Zampini /* allocate and initialize needed graph structure */ 25230c7d97c5SJed Brown ierr = PetscMalloc(sizeof(*mat_graph),&mat_graph);CHKERRQ(ierr); 25240c7d97c5SJed Brown ierr = MatConvert(matis->A,MATMPIADJ,MAT_INITIAL_MATRIX,&mat_adj);CHKERRQ(ierr); 2525a0ba757dSStefano Zampini /* ierr = MatDuplicate(matis->A,MAT_COPY_VALUES,&mat_adj);CHKERRQ(ierr); */ 2526a0ba757dSStefano Zampini ierr = MatGetRowIJ(mat_adj,0,symmetrize_rowij,compressed_rowij,&mat_graph->nvtxs,&mat_graph->xadj,&mat_graph->adjncy,&flg_row);CHKERRQ(ierr); 25270c7d97c5SJed Brown if(!flg_row) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatGetRowIJ called from PCBDDCManageLocalBoundaries.\n"); 2528a0ba757dSStefano Zampini i = mat_graph->nvtxs; 2529a0ba757dSStefano 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); 2530a0ba757dSStefano Zampini ierr = PetscMalloc3(i,PetscInt,&mat_graph->which_dof,i,PetscBool,&mat_graph->touched,i,PetscInt,&queue_in_global_numbering);CHKERRQ(ierr); 2531a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->where,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2532a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->count,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2533a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->which_dof,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2534a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->queue,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 25353828260eSStefano Zampini ierr = PetscMemzero(mat_graph->cptr,(mat_graph->nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 25363828260eSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){mat_graph->touched[i]=PETSC_FALSE;} 2537a0ba757dSStefano Zampini 25389c0446d6SStefano Zampini /* Setting dofs splitting in mat_graph->which_dof */ 25399c0446d6SStefano Zampini if(pcbddc->n_ISForDofs) { /* get information about dofs' splitting if provided by the user */ 25409c0446d6SStefano Zampini PetscInt *is_indices; 25419c0446d6SStefano Zampini PetscInt is_size; 25429c0446d6SStefano Zampini for(i=0;i<pcbddc->n_ISForDofs;i++) { 25439c0446d6SStefano Zampini ierr = ISGetSize(pcbddc->ISForDofs[i],&is_size);CHKERRQ(ierr); 25449c0446d6SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofs[i],(const PetscInt**)&is_indices);CHKERRQ(ierr); 25459c0446d6SStefano Zampini for(j=0;j<is_size;j++) { 25469c0446d6SStefano Zampini mat_graph->which_dof[is_indices[j]]=i; 25479c0446d6SStefano Zampini } 25489c0446d6SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofs[i],(const PetscInt**)&is_indices);CHKERRQ(ierr); 25499c0446d6SStefano Zampini } 25503b03a366Sstefano_zampini /* use mat block size as vertex size */ 25513b03a366Sstefano_zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 25523b03a366Sstefano_zampini } else { /* otherwise it assumes a constant block size */ 2553a0ba757dSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 25540c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs/bs;i++) { 25550c7d97c5SJed Brown for(s=0;s<bs;s++) { 25560c7d97c5SJed Brown mat_graph->which_dof[i*bs+s]=s; 25570c7d97c5SJed Brown } 25580c7d97c5SJed Brown } 25593b03a366Sstefano_zampini vertex_size=1; 25609c0446d6SStefano Zampini } 25613b03a366Sstefano_zampini /* count number of neigh per node */ 25620c7d97c5SJed Brown total_counts=0; 25633b03a366Sstefano_zampini for(i=1;i<pcis->n_neigh;i++){ 25640c7d97c5SJed Brown s=pcis->n_shared[i]; 25650c7d97c5SJed Brown total_counts+=s; 256653cdbc3dSStefano Zampini for(j=0;j<s;j++){ 25670c7d97c5SJed Brown mat_graph->count[pcis->shared[i][j]] += 1; 25680c7d97c5SJed Brown } 25690c7d97c5SJed Brown } 25703b03a366Sstefano_zampini /* Take into account Neumann data -> it increments number of sharing subdomains for all but faces nodes lying on the interface */ 257153cdbc3dSStefano Zampini if(pcbddc->NeumannBoundaries) { 25729c0446d6SStefano Zampini ierr = ISGetSize(pcbddc->NeumannBoundaries,&neumann_bsize);CHKERRQ(ierr); 257353cdbc3dSStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundaries,&neumann_nodes);CHKERRQ(ierr); 257453cdbc3dSStefano Zampini for(i=0;i<neumann_bsize;i++){ 257553cdbc3dSStefano Zampini iindex = neumann_nodes[i]; 25763b03a366Sstefano_zampini if(mat_graph->count[iindex] > 1){ 257753cdbc3dSStefano Zampini mat_graph->count[iindex]+=1; 25780c7d97c5SJed Brown total_counts++; 25790c7d97c5SJed Brown } 25800c7d97c5SJed Brown } 25810c7d97c5SJed Brown } 25823b03a366Sstefano_zampini /* allocate space for storing the set of neighbours of each node */ 258353cdbc3dSStefano Zampini ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt*),&neighbours_set);CHKERRQ(ierr); 25843b03a366Sstefano_zampini if(mat_graph->nvtxs) { ierr = PetscMalloc(total_counts*sizeof(PetscInt),&neighbours_set[0]);CHKERRQ(ierr); } 258553cdbc3dSStefano Zampini for(i=1;i<mat_graph->nvtxs;i++) neighbours_set[i]=neighbours_set[i-1]+mat_graph->count[i-1]; 2586a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->count,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 25873b03a366Sstefano_zampini for(i=1;i<pcis->n_neigh;i++){ 25880c7d97c5SJed Brown s=pcis->n_shared[i]; 25890c7d97c5SJed Brown for(j=0;j<s;j++) { 25900c7d97c5SJed Brown k=pcis->shared[i][j]; 259153cdbc3dSStefano Zampini neighbours_set[k][mat_graph->count[k]] = pcis->neigh[i]; 25920c7d97c5SJed Brown mat_graph->count[k]+=1; 25930c7d97c5SJed Brown } 25940c7d97c5SJed Brown } 25953b03a366Sstefano_zampini /* set -1 fake neighbour to mimic Neumann boundary */ 259653cdbc3dSStefano Zampini if(pcbddc->NeumannBoundaries) { 259753cdbc3dSStefano Zampini for(i=0;i<neumann_bsize;i++){ 259853cdbc3dSStefano Zampini iindex = neumann_nodes[i]; 25993b03a366Sstefano_zampini if(mat_graph->count[iindex] > 1){ 26003b03a366Sstefano_zampini neighbours_set[iindex][mat_graph->count[iindex]] = -1; 260153cdbc3dSStefano Zampini mat_graph->count[iindex]+=1; 26020c7d97c5SJed Brown } 26030c7d97c5SJed Brown } 260453cdbc3dSStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundaries,&neumann_nodes);CHKERRQ(ierr); 26050c7d97c5SJed Brown } 26063b03a366Sstefano_zampini /* sort set of sharing subdomains (needed for comparison below) */ 260753cdbc3dSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++) { ierr = PetscSortInt(mat_graph->count[i],neighbours_set[i]);CHKERRQ(ierr); } 26083b03a366Sstefano_zampini /* remove interior nodes and dirichlet boundary nodes from the next search into the graph */ 26093b03a366Sstefano_zampini if(pcbddc->DirichletBoundaries) { 26103b03a366Sstefano_zampini ierr = ISGetSize(pcbddc->DirichletBoundaries,&dirichlet_bsize);CHKERRQ(ierr); 26113b03a366Sstefano_zampini ierr = ISGetIndices(pcbddc->DirichletBoundaries,&dirichlet_nodes);CHKERRQ(ierr); 26123b03a366Sstefano_zampini for(i=0;i<dirichlet_bsize;i++){ 26133b03a366Sstefano_zampini mat_graph->count[dirichlet_nodes[i]]=0; 26143b03a366Sstefano_zampini } 26153b03a366Sstefano_zampini ierr = ISRestoreIndices(pcbddc->DirichletBoundaries,&dirichlet_nodes);CHKERRQ(ierr); 26163b03a366Sstefano_zampini } 26170c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs;i++){ 26183b03a366Sstefano_zampini if(!mat_graph->count[i]){ /* interior nodes */ 26190c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 26200c7d97c5SJed Brown mat_graph->where[i]=0; 26210c7d97c5SJed Brown nodes_touched++; 26220c7d97c5SJed Brown } 26230c7d97c5SJed Brown } 26240c7d97c5SJed Brown mat_graph->ncmps = 0; 26250c7d97c5SJed Brown while(nodes_touched<mat_graph->nvtxs) { 2626a0ba757dSStefano Zampini /* find first untouched node in local ordering */ 26270c7d97c5SJed Brown i=0; 26280c7d97c5SJed Brown while(mat_graph->touched[i]) i++; 26290c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 2630a0ba757dSStefano Zampini mat_graph->where[i]=where_values; 26310c7d97c5SJed Brown nodes_touched++; 2632a0ba757dSStefano Zampini /* now find all other nodes having the same set of sharing subdomains */ 26330c7d97c5SJed Brown for(j=i+1;j<mat_graph->nvtxs;j++){ 2634a0ba757dSStefano Zampini /* check for same number of sharing subdomains and dof number */ 26350c7d97c5SJed Brown if(mat_graph->count[i]==mat_graph->count[j] && mat_graph->which_dof[i] == mat_graph->which_dof[j] ){ 2636a0ba757dSStefano Zampini /* check for same set of sharing subdomains */ 26370c7d97c5SJed Brown same_set=PETSC_TRUE; 26380c7d97c5SJed Brown for(k=0;k<mat_graph->count[j];k++){ 263953cdbc3dSStefano Zampini if(neighbours_set[i][k]!=neighbours_set[j][k]) { 26400c7d97c5SJed Brown same_set=PETSC_FALSE; 26410c7d97c5SJed Brown } 26420c7d97c5SJed Brown } 2643a0ba757dSStefano Zampini /* I found a friend of mine */ 26440c7d97c5SJed Brown if(same_set) { 2645a0ba757dSStefano Zampini mat_graph->where[j]=where_values; 26460c7d97c5SJed Brown mat_graph->touched[j]=PETSC_TRUE; 26470c7d97c5SJed Brown nodes_touched++; 26480c7d97c5SJed Brown } 26490c7d97c5SJed Brown } 26500c7d97c5SJed Brown } 2651a0ba757dSStefano Zampini where_values++; 26520c7d97c5SJed Brown } 2653a0ba757dSStefano Zampini where_values--; if(where_values<0) where_values=0; 2654a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscMPIInt),&mat_graph->where_ncmps);CHKERRQ(ierr); 2655a0ba757dSStefano Zampini /* Find connected components defined on the shared interface */ 2656a0ba757dSStefano Zampini if(where_values) { 2657a0ba757dSStefano Zampini ierr = PCBDDCFindConnectedComponents(mat_graph, where_values); 26583b03a366Sstefano_zampini /* For consistency among neughbouring procs, I need to sort (by global ordering) each connected component */ 2659a0ba757dSStefano Zampini for(i=0;i<mat_graph->ncmps;i++) { 2660a0ba757dSStefano 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); 2661a0ba757dSStefano 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); 2662a0ba757dSStefano Zampini } 2663a0ba757dSStefano Zampini } 2664a0ba757dSStefano Zampini /* check consistency of connected components among neighbouring subdomains -> it adapt them in case it is needed */ 2665a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 26663b03a366Sstefano_zampini /* We are not sure that two connected components will be the same among subdomains sharing a subset of local interface */ 26673b03a366Sstefano_zampini if(mat_graph->where_ncmps[i]>1) { 2668a0ba757dSStefano Zampini adapt_interface=1; 2669a0ba757dSStefano Zampini break; 2670a0ba757dSStefano Zampini } 2671a0ba757dSStefano Zampini } 2672a0ba757dSStefano Zampini ierr = MPI_Allreduce(&adapt_interface,&adapt_interface_reduced,1,MPIU_INT,MPI_LOR,interface_comm);CHKERRQ(ierr); 2673a0ba757dSStefano Zampini if(where_values && adapt_interface_reduced) { 26740c7d97c5SJed Brown 26753b03a366Sstefano_zampini printf("Adapting Interface\n"); 26763b03a366Sstefano_zampini 2677a0ba757dSStefano Zampini PetscInt sum_requests=0,my_rank; 2678a0ba757dSStefano Zampini PetscInt buffer_size,start_of_recv,size_of_recv,start_of_send; 2679a0ba757dSStefano Zampini PetscInt temp_buffer_size,ins_val,global_where_counter; 2680a0ba757dSStefano Zampini PetscInt *cum_recv_counts; 2681a0ba757dSStefano Zampini PetscInt *where_to_nodes_indices; 2682a0ba757dSStefano Zampini PetscInt *petsc_buffer; 2683a0ba757dSStefano Zampini PetscMPIInt *recv_buffer; 2684a0ba757dSStefano Zampini PetscMPIInt *recv_buffer_where; 2685a0ba757dSStefano Zampini PetscMPIInt *send_buffer; 2686a0ba757dSStefano Zampini PetscMPIInt size_of_send; 2687a0ba757dSStefano Zampini PetscInt *sizes_of_sends; 2688a0ba757dSStefano Zampini MPI_Request *send_requests; 2689a0ba757dSStefano Zampini MPI_Request *recv_requests; 2690a0ba757dSStefano Zampini PetscInt *where_cc_adapt; 2691a0ba757dSStefano Zampini PetscInt **temp_buffer; 2692a0ba757dSStefano Zampini PetscInt *nodes_to_temp_buffer_indices; 2693a0ba757dSStefano Zampini PetscInt *add_to_where; 2694a0ba757dSStefano Zampini 2695a0ba757dSStefano Zampini ierr = MPI_Comm_rank(interface_comm,&my_rank);CHKERRQ(ierr); 2696a0ba757dSStefano Zampini ierr = PetscMalloc((where_values+1)*sizeof(PetscInt),&cum_recv_counts);CHKERRQ(ierr); 2697a0ba757dSStefano Zampini ierr = PetscMemzero(cum_recv_counts,(where_values+1)*sizeof(PetscInt));CHKERRQ(ierr); 2698a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&where_to_nodes_indices);CHKERRQ(ierr); 2699a0ba757dSStefano Zampini /* first count how many neighbours per connected component I will receive from */ 2700a0ba757dSStefano Zampini cum_recv_counts[0]=0; 2701a0ba757dSStefano Zampini for(i=1;i<where_values+1;i++){ 2702a0ba757dSStefano Zampini j=0; 2703a0ba757dSStefano Zampini while(mat_graph->where[j] != i) j++; 2704a0ba757dSStefano Zampini where_to_nodes_indices[i-1]=j; 27053b03a366Sstefano_zampini if(neighbours_set[j][0]!=-1) { cum_recv_counts[i]=cum_recv_counts[i-1]+mat_graph->count[j]; } /* We don't want sends/recvs_to/from_self -> here I don't count myself */ 27063b03a366Sstefano_zampini else { cum_recv_counts[i]=cum_recv_counts[i-1]+mat_graph->count[j]-1; } 2707a0ba757dSStefano Zampini } 2708a0ba757dSStefano Zampini buffer_size=2*cum_recv_counts[where_values]+mat_graph->nvtxs; 2709a0ba757dSStefano Zampini ierr = PetscMalloc(2*cum_recv_counts[where_values]*sizeof(PetscMPIInt),&recv_buffer_where);CHKERRQ(ierr); 2710a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 2711a0ba757dSStefano Zampini ierr = PetscMalloc(cum_recv_counts[where_values]*sizeof(MPI_Request),&send_requests);CHKERRQ(ierr); 2712a0ba757dSStefano Zampini ierr = PetscMalloc(cum_recv_counts[where_values]*sizeof(MPI_Request),&recv_requests);CHKERRQ(ierr); 2713a0ba757dSStefano Zampini for(i=0;i<cum_recv_counts[where_values];i++) { 2714a0ba757dSStefano Zampini send_requests[i]=MPI_REQUEST_NULL; 2715a0ba757dSStefano Zampini recv_requests[i]=MPI_REQUEST_NULL; 2716a0ba757dSStefano Zampini } 2717a0ba757dSStefano Zampini /* exchange with my neighbours the number of my connected components on the shared interface */ 2718a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2719a0ba757dSStefano Zampini j=where_to_nodes_indices[i]; 2720a0ba757dSStefano Zampini k = (neighbours_set[j][0] == -1 ? 1 : 0); 2721a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2722a0ba757dSStefano 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); 2723a0ba757dSStefano 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); 2724a0ba757dSStefano Zampini sum_requests++; 2725a0ba757dSStefano Zampini } 2726a0ba757dSStefano Zampini } 2727a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2728a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2729a0ba757dSStefano Zampini /* determine the connected component I need to adapt */ 2730a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&where_cc_adapt);CHKERRQ(ierr); 2731a0ba757dSStefano Zampini ierr = PetscMemzero(where_cc_adapt,where_values*sizeof(PetscInt));CHKERRQ(ierr); 2732a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2733a0ba757dSStefano Zampini for(j=cum_recv_counts[i];j<cum_recv_counts[i+1];j++){ 27343b03a366Sstefano_zampini /* The first condition is natural (i.e someone has a different number of cc than me), the second one is just to be safe */ 27353b03a366Sstefano_zampini if( mat_graph->where_ncmps[i]!=recv_buffer_where[j] || mat_graph->where_ncmps[i] > 1 ) { 2736a0ba757dSStefano Zampini where_cc_adapt[i]=PETSC_TRUE; 2737a0ba757dSStefano Zampini break; 2738a0ba757dSStefano Zampini } 2739a0ba757dSStefano Zampini } 2740a0ba757dSStefano Zampini } 2741a0ba757dSStefano Zampini /* now get from neighbours their ccs (in global numbering) and adapt them (in case it is needed) */ 2742a0ba757dSStefano Zampini /* first determine how much data to send (size of each queue plus the global indices) and communicate it to neighbours */ 2743a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&sizes_of_sends);CHKERRQ(ierr); 2744a0ba757dSStefano Zampini ierr = PetscMemzero(sizes_of_sends,where_values*sizeof(PetscInt));CHKERRQ(ierr); 2745a0ba757dSStefano Zampini sum_requests=0; 2746a0ba757dSStefano Zampini start_of_send=0; 2747a0ba757dSStefano Zampini start_of_recv=cum_recv_counts[where_values]; 2748a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 2749a0ba757dSStefano Zampini if(where_cc_adapt[i]) { 2750a0ba757dSStefano Zampini size_of_send=0; 2751a0ba757dSStefano Zampini for(j=i;j<mat_graph->ncmps;j++) { 2752a0ba757dSStefano Zampini if(mat_graph->where[mat_graph->queue[mat_graph->cptr[j]]] == i+1) { /* WARNING -> where values goes from 1 to where_values included */ 2753a0ba757dSStefano Zampini send_buffer[start_of_send+size_of_send]=mat_graph->cptr[j+1]-mat_graph->cptr[j]; 2754a0ba757dSStefano Zampini size_of_send+=1; 2755a0ba757dSStefano Zampini for(k=0;k<mat_graph->cptr[j+1]-mat_graph->cptr[j];k++) { 2756a0ba757dSStefano Zampini send_buffer[start_of_send+size_of_send+k]=queue_in_global_numbering[mat_graph->cptr[j]+k]; 2757a0ba757dSStefano Zampini } 2758a0ba757dSStefano Zampini size_of_send=size_of_send+mat_graph->cptr[j+1]-mat_graph->cptr[j]; 2759a0ba757dSStefano Zampini } 2760a0ba757dSStefano Zampini } 2761a0ba757dSStefano Zampini j = where_to_nodes_indices[i]; 2762a0ba757dSStefano Zampini k = (neighbours_set[j][0] == -1 ? 1 : 0); 2763a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2764a0ba757dSStefano 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); 2765a0ba757dSStefano 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); 2766a0ba757dSStefano Zampini sum_requests++; 2767a0ba757dSStefano Zampini } 2768a0ba757dSStefano Zampini sizes_of_sends[i]=size_of_send; 2769a0ba757dSStefano Zampini start_of_send+=size_of_send; 2770a0ba757dSStefano Zampini } 2771a0ba757dSStefano Zampini } 2772a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2773a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2774a0ba757dSStefano Zampini buffer_size=0; 2775a0ba757dSStefano Zampini for(k=0;k<sum_requests;k++) { buffer_size+=recv_buffer_where[start_of_recv+k]; } 2776a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscMPIInt),&recv_buffer);CHKERRQ(ierr); 2777a0ba757dSStefano Zampini /* now exchange the data */ 2778a0ba757dSStefano Zampini start_of_recv=0; 2779a0ba757dSStefano Zampini start_of_send=0; 2780a0ba757dSStefano Zampini sum_requests=0; 2781a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 2782a0ba757dSStefano Zampini if(where_cc_adapt[i]) { 2783a0ba757dSStefano Zampini size_of_send = sizes_of_sends[i]; 2784a0ba757dSStefano Zampini j = where_to_nodes_indices[i]; 2785a0ba757dSStefano Zampini k = (neighbours_set[j][0] == -1 ? 1 : 0); 2786a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2787a0ba757dSStefano 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); 2788a0ba757dSStefano Zampini size_of_recv=recv_buffer_where[cum_recv_counts[where_values]+sum_requests]; 2789a0ba757dSStefano 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); 2790a0ba757dSStefano Zampini start_of_recv+=size_of_recv; 2791a0ba757dSStefano Zampini sum_requests++; 2792a0ba757dSStefano Zampini } 2793a0ba757dSStefano Zampini start_of_send+=size_of_send; 2794a0ba757dSStefano Zampini } 2795a0ba757dSStefano Zampini } 2796a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2797a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2798a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscInt),&petsc_buffer);CHKERRQ(ierr); 2799a0ba757dSStefano Zampini for(k=0;k<start_of_recv;k++) { petsc_buffer[k]=(PetscInt)recv_buffer[k]; } 2800a0ba757dSStefano Zampini for(j=0;j<buffer_size;) { 2801a0ba757dSStefano Zampini ierr = ISGlobalToLocalMappingApply(matis->mapping,IS_GTOLM_MASK,petsc_buffer[j],&petsc_buffer[j+1],&petsc_buffer[j],&petsc_buffer[j+1]);CHKERRQ(ierr); 2802a0ba757dSStefano Zampini k=petsc_buffer[j]+1; 2803a0ba757dSStefano Zampini j+=k; 2804a0ba757dSStefano Zampini } 2805a0ba757dSStefano Zampini sum_requests=cum_recv_counts[where_values]; 2806a0ba757dSStefano Zampini start_of_recv=0; 2807a0ba757dSStefano Zampini ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt),&nodes_to_temp_buffer_indices);CHKERRQ(ierr); 2808a0ba757dSStefano Zampini global_where_counter=0; 2809a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2810a0ba757dSStefano Zampini if(where_cc_adapt[i]){ 2811a0ba757dSStefano Zampini temp_buffer_size=0; 2812a0ba757dSStefano Zampini /* find nodes on the shared interface we need to adapt */ 2813a0ba757dSStefano Zampini for(j=0;j<mat_graph->nvtxs;j++){ 2814a0ba757dSStefano Zampini if(mat_graph->where[j]==i+1) { 2815a0ba757dSStefano Zampini nodes_to_temp_buffer_indices[j]=temp_buffer_size; 2816a0ba757dSStefano Zampini temp_buffer_size++; 2817a0ba757dSStefano Zampini } else { 2818a0ba757dSStefano Zampini nodes_to_temp_buffer_indices[j]=-1; 2819a0ba757dSStefano Zampini } 2820a0ba757dSStefano Zampini } 2821a0ba757dSStefano Zampini /* allocate some temporary space */ 2822a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*sizeof(PetscInt*),&temp_buffer);CHKERRQ(ierr); 2823a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*(cum_recv_counts[i+1]-cum_recv_counts[i])*sizeof(PetscInt),&temp_buffer[0]);CHKERRQ(ierr); 2824a0ba757dSStefano Zampini ierr = PetscMemzero(temp_buffer[0],temp_buffer_size*(cum_recv_counts[i+1]-cum_recv_counts[i])*sizeof(PetscInt));CHKERRQ(ierr); 2825a0ba757dSStefano Zampini for(j=1;j<temp_buffer_size;j++){ 2826a0ba757dSStefano Zampini temp_buffer[j]=temp_buffer[j-1]+cum_recv_counts[i+1]-cum_recv_counts[i]; 2827a0ba757dSStefano Zampini } 2828a0ba757dSStefano Zampini /* analyze contributions from neighbouring subdomains for i-th conn comp 2829a0ba757dSStefano Zampini temp buffer structure: 2830a0ba757dSStefano Zampini supposing part of the interface has dimension 5 (global nodes 0,1,2,3,4) 2831a0ba757dSStefano Zampini 3 neighs procs with structured connected components: 2832a0ba757dSStefano Zampini neigh 0: [0 1 4], [2 3]; (2 connected components) 2833a0ba757dSStefano Zampini neigh 1: [0 1], [2 3 4]; (2 connected components) 2834a0ba757dSStefano Zampini neigh 2: [0 4], [1], [2 3]; (3 connected components) 2835a0ba757dSStefano Zampini tempbuffer (row-oriented) should be filled as: 2836a0ba757dSStefano Zampini [ 0, 0, 0; 2837a0ba757dSStefano Zampini 0, 0, 1; 2838a0ba757dSStefano Zampini 1, 1, 2; 2839a0ba757dSStefano Zampini 1, 1, 2; 2840a0ba757dSStefano Zampini 0, 1, 0; ]; 2841a0ba757dSStefano Zampini This way we can simply recover the resulting structure account for possible intersections of ccs among neighs. 2842a0ba757dSStefano Zampini The mat_graph->where array will be modified to reproduce the following 4 connected components [0], [1], [2 3], [4]; 2843a0ba757dSStefano Zampini */ 2844a0ba757dSStefano Zampini for(j=0;j<cum_recv_counts[i+1]-cum_recv_counts[i];j++) { 2845a0ba757dSStefano Zampini ins_val=0; 2846a0ba757dSStefano Zampini size_of_recv=recv_buffer_where[sum_requests]; /* total size of recv from neighs */ 2847a0ba757dSStefano Zampini for(buffer_size=0;buffer_size<size_of_recv;) { /* loop until all data from neighs has been taken into account */ 2848a0ba757dSStefano Zampini for(k=1;k<petsc_buffer[buffer_size+start_of_recv]+1;k++) { /* filling properly temp_buffer using data from a single recv */ 2849a0ba757dSStefano Zampini temp_buffer[ nodes_to_temp_buffer_indices[ petsc_buffer[ start_of_recv+buffer_size+k ] ] ][j]=ins_val; 2850a0ba757dSStefano Zampini } 2851a0ba757dSStefano Zampini buffer_size+=k; 2852a0ba757dSStefano Zampini ins_val++; 2853a0ba757dSStefano Zampini } 2854a0ba757dSStefano Zampini start_of_recv+=size_of_recv; 2855a0ba757dSStefano Zampini sum_requests++; 2856a0ba757dSStefano Zampini } 2857a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*sizeof(PetscInt),&add_to_where);CHKERRQ(ierr); 2858a0ba757dSStefano Zampini ierr = PetscMemzero(add_to_where,temp_buffer_size*sizeof(PetscInt));CHKERRQ(ierr); 2859a0ba757dSStefano Zampini for(j=0;j<temp_buffer_size;j++){ 2860a0ba757dSStefano Zampini if(!add_to_where[j]){ /* found a new cc */ 2861a0ba757dSStefano Zampini global_where_counter++; 2862a0ba757dSStefano Zampini add_to_where[j]=global_where_counter; 2863a0ba757dSStefano Zampini for(k=j+1;k<temp_buffer_size;k++){ /* check for other nodes in new cc */ 2864a0ba757dSStefano Zampini same_set=PETSC_TRUE; 2865a0ba757dSStefano Zampini for(s=0;s<cum_recv_counts[i+1]-cum_recv_counts[i];s++){ 2866a0ba757dSStefano Zampini if(temp_buffer[j][s]!=temp_buffer[k][s]) { 2867a0ba757dSStefano Zampini same_set=PETSC_FALSE; 2868a0ba757dSStefano Zampini break; 2869a0ba757dSStefano Zampini } 2870a0ba757dSStefano Zampini } 2871a0ba757dSStefano Zampini if(same_set) add_to_where[k]=global_where_counter; 2872a0ba757dSStefano Zampini } 2873a0ba757dSStefano Zampini } 2874a0ba757dSStefano Zampini } 2875a0ba757dSStefano Zampini /* insert new data in where array */ 2876a0ba757dSStefano Zampini temp_buffer_size=0; 2877a0ba757dSStefano Zampini for(j=0;j<mat_graph->nvtxs;j++){ 2878a0ba757dSStefano Zampini if(mat_graph->where[j]==i+1) { 2879a0ba757dSStefano Zampini mat_graph->where[j]=where_values+add_to_where[temp_buffer_size]; 2880a0ba757dSStefano Zampini temp_buffer_size++; 2881a0ba757dSStefano Zampini } 2882a0ba757dSStefano Zampini } 2883a0ba757dSStefano Zampini ierr = PetscFree(temp_buffer[0]);CHKERRQ(ierr); 2884a0ba757dSStefano Zampini ierr = PetscFree(temp_buffer);CHKERRQ(ierr); 2885a0ba757dSStefano Zampini ierr = PetscFree(add_to_where);CHKERRQ(ierr); 2886a0ba757dSStefano Zampini } 2887a0ba757dSStefano Zampini } 2888a0ba757dSStefano Zampini ierr = PetscFree(nodes_to_temp_buffer_indices);CHKERRQ(ierr); 2889a0ba757dSStefano Zampini ierr = PetscFree(sizes_of_sends);CHKERRQ(ierr); 2890a0ba757dSStefano Zampini ierr = PetscFree(send_requests);CHKERRQ(ierr); 2891a0ba757dSStefano Zampini ierr = PetscFree(recv_requests);CHKERRQ(ierr); 2892a0ba757dSStefano Zampini ierr = PetscFree(petsc_buffer);CHKERRQ(ierr); 2893a0ba757dSStefano Zampini ierr = PetscFree(recv_buffer);CHKERRQ(ierr); 2894a0ba757dSStefano Zampini ierr = PetscFree(recv_buffer_where);CHKERRQ(ierr); 2895a0ba757dSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 2896a0ba757dSStefano Zampini ierr = PetscFree(cum_recv_counts);CHKERRQ(ierr); 2897a0ba757dSStefano Zampini ierr = PetscFree(where_to_nodes_indices);CHKERRQ(ierr); 2898a0ba757dSStefano Zampini /* We are ready to evaluate consistent connected components on each part of the shared interface */ 2899a0ba757dSStefano Zampini if(global_where_counter) { 2900a0ba757dSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){ mat_graph->touched[i]=PETSC_FALSE; } 2901a0ba757dSStefano Zampini global_where_counter=0; 2902a0ba757dSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){ 2903a0ba757dSStefano Zampini if(mat_graph->where[i] && !mat_graph->touched[i]) { 2904a0ba757dSStefano Zampini global_where_counter++; 2905a0ba757dSStefano Zampini for(j=i+1;j<mat_graph->nvtxs;j++){ 2906a0ba757dSStefano Zampini if(!mat_graph->touched[j] && mat_graph->where[j]==mat_graph->where[i]) { 2907a0ba757dSStefano Zampini mat_graph->where[j]=global_where_counter; 2908a0ba757dSStefano Zampini mat_graph->touched[j]=PETSC_TRUE; 2909a0ba757dSStefano Zampini } 2910a0ba757dSStefano Zampini } 2911a0ba757dSStefano Zampini mat_graph->where[i]=global_where_counter; 2912a0ba757dSStefano Zampini mat_graph->touched[i]=PETSC_TRUE; 2913a0ba757dSStefano Zampini } 2914a0ba757dSStefano Zampini } 2915a0ba757dSStefano Zampini where_values=global_where_counter; 2916a0ba757dSStefano Zampini } 2917a0ba757dSStefano Zampini if(global_where_counter) { 2918a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->cptr,(mat_graph->nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 2919a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->queue,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2920a0ba757dSStefano Zampini ierr = PetscFree(mat_graph->where_ncmps);CHKERRQ(ierr); 2921a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscMPIInt),&mat_graph->where_ncmps);CHKERRQ(ierr); 2922a0ba757dSStefano Zampini ierr = PCBDDCFindConnectedComponents(mat_graph, where_values); 2923a0ba757dSStefano Zampini for(i=0;i<mat_graph->ncmps;i++) { 2924a0ba757dSStefano 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); 2925a0ba757dSStefano 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); 2926a0ba757dSStefano Zampini } 2927a0ba757dSStefano Zampini } 29283b03a366Sstefano_zampini } /* Finished adapting interface */ 29290c7d97c5SJed Brown PetscInt nfc=0; 29300c7d97c5SJed Brown PetscInt nec=0; 29310c7d97c5SJed Brown PetscInt nvc=0; 29323b03a366Sstefano_zampini PetscBool twodim_flag=PETSC_FALSE; 29330c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 29343b03a366Sstefano_zampini if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > vertex_size ){ 29353b03a366Sstefano_zampini if(mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]==1){ /* 1 neigh */ 29360c7d97c5SJed Brown nfc++; 29373b03a366Sstefano_zampini } else { /* note that nec will be zero in 2d */ 29383b03a366Sstefano_zampini nec++; 29393b03a366Sstefano_zampini } 29400c7d97c5SJed Brown } else { 29413b03a366Sstefano_zampini nvc+=mat_graph->cptr[i+1]-mat_graph->cptr[i]; 29423b03a366Sstefano_zampini } 29433b03a366Sstefano_zampini } 29443b03a366Sstefano_zampini 29453b03a366Sstefano_zampini if(!nec) { /* we are in a 2d case -> no faces, only edges */ 29463b03a366Sstefano_zampini nec = nfc; 29473b03a366Sstefano_zampini nfc = 0; 29483b03a366Sstefano_zampini twodim_flag = PETSC_TRUE; 29493b03a366Sstefano_zampini } 29503b03a366Sstefano_zampini /* allocate IS arrays for faces, edges. Vertices need a single index set. 29513b03a366Sstefano_zampini Reusing space allocated in mat_graph->where for creating IS objects */ 29523b03a366Sstefano_zampini if(!pcbddc->vertices_flag && !pcbddc->edges_flag) { 29533b03a366Sstefano_zampini ierr = PetscMalloc(nfc*sizeof(IS),&pcbddc->ISForFaces);CHKERRQ(ierr); 29543b03a366Sstefano_zampini use_faces=PETSC_TRUE; 29553b03a366Sstefano_zampini } 29563b03a366Sstefano_zampini if(!pcbddc->vertices_flag && !pcbddc->faces_flag) { 29573b03a366Sstefano_zampini ierr = PetscMalloc(nec*sizeof(IS),&pcbddc->ISForEdges);CHKERRQ(ierr); 29583b03a366Sstefano_zampini use_edges=PETSC_TRUE; 29593b03a366Sstefano_zampini } 29603b03a366Sstefano_zampini nfc=0; 29613b03a366Sstefano_zampini nec=0; 29623b03a366Sstefano_zampini for (i=0; i<mat_graph->ncmps; i++) { 29633b03a366Sstefano_zampini if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > vertex_size ){ 29643b03a366Sstefano_zampini for(j=0;j<mat_graph->cptr[i+1]-mat_graph->cptr[i];j++) { 29653b03a366Sstefano_zampini mat_graph->where[j]=mat_graph->queue[mat_graph->cptr[i]+j]; 29663b03a366Sstefano_zampini } 29673b03a366Sstefano_zampini if(mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]==1){ 29683b03a366Sstefano_zampini if(twodim_flag) { 29693b03a366Sstefano_zampini if(use_edges) { 29703b03a366Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,mat_graph->where,PETSC_COPY_VALUES,&pcbddc->ISForEdges[nec]);CHKERRQ(ierr); 29713b03a366Sstefano_zampini nec++; 29723b03a366Sstefano_zampini } 29733b03a366Sstefano_zampini } else { 29743b03a366Sstefano_zampini if(use_faces) { 29753b03a366Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,mat_graph->where,PETSC_COPY_VALUES,&pcbddc->ISForFaces[nfc]);CHKERRQ(ierr); 29763b03a366Sstefano_zampini nfc++; 29773b03a366Sstefano_zampini } 29783b03a366Sstefano_zampini } 29793b03a366Sstefano_zampini } else { 29803b03a366Sstefano_zampini if(use_edges) { 29813b03a366Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,mat_graph->where,PETSC_COPY_VALUES,&pcbddc->ISForEdges[nec]);CHKERRQ(ierr); 29820c7d97c5SJed Brown nec++; 29830c7d97c5SJed Brown } 29840c7d97c5SJed Brown } 29850c7d97c5SJed Brown } 29863b03a366Sstefano_zampini } 29873b03a366Sstefano_zampini pcbddc->n_ISForFaces=nfc; 29883b03a366Sstefano_zampini pcbddc->n_ISForEdges=nec; 29893b03a366Sstefano_zampini nvc=0; 29900c7d97c5SJed Brown if( !pcbddc->constraints_flag ) { 29913b03a366Sstefano_zampini for (i=0; i<mat_graph->ncmps; i++) { 29923b03a366Sstefano_zampini if( mat_graph->cptr[i+1]-mat_graph->cptr[i] <= vertex_size ){ 29933b03a366Sstefano_zampini for( j=mat_graph->cptr[i];j<mat_graph->cptr[i+1];j++) { 29943b03a366Sstefano_zampini mat_graph->where[nvc]=mat_graph->queue[j]; 29950c7d97c5SJed Brown nvc++; 29960c7d97c5SJed Brown } 29970c7d97c5SJed Brown } 29980c7d97c5SJed Brown } 29990c7d97c5SJed Brown } 3000a0ba757dSStefano Zampini /* sort vertex set (by local ordering) */ 30013b03a366Sstefano_zampini ierr = PetscSortInt(nvc,mat_graph->where);CHKERRQ(ierr); 30023b03a366Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nvc,mat_graph->where,PETSC_COPY_VALUES,&pcbddc->ISForVertices);CHKERRQ(ierr); 30030c7d97c5SJed Brown 3004e269702eSStefano Zampini if(pcbddc->dbg_flag) { 3005e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 3006e269702eSStefano Zampini 3007d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3008d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Details from PCBDDCManageLocalBoundaries for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 3009d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3010a0ba757dSStefano Zampini /* ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Graph (adjacency structure) of local Neumann mat\n");CHKERRQ(ierr); 3011a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3012e269702eSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++) { 3013a0ba757dSStefano 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); 3014e269702eSStefano Zampini for(j=mat_graph->xadj[i];j<mat_graph->xadj[i+1];j++){ 3015a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d ",mat_graph->adjncy[j]);CHKERRQ(ierr); 3016e269702eSStefano Zampini } 3017a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n--------------------------------------------------------------\n");CHKERRQ(ierr); 30183b03a366Sstefano_zampini } 3019d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Matrix graph has %d connected components", mat_graph->ncmps);CHKERRQ(ierr); 30200c7d97c5SJed Brown for(i=0;i<mat_graph->ncmps;i++) { 30213b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\nDetails for connected component number %02d: size %04d, count %01d. Nodes follow.\n", 30223b03a366Sstefano_zampini i,mat_graph->cptr[i+1]-mat_graph->cptr[i],mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]);CHKERRQ(ierr); 30230c7d97c5SJed Brown for (j=mat_graph->cptr[i]; j<mat_graph->cptr[i+1]; j++){ 30243828260eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d (%d), ",queue_in_global_numbering[j],mat_graph->queue[j]);CHKERRQ(ierr); 30250c7d97c5SJed Brown } 30260c7d97c5SJed Brown } 30273b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n--------------------------------------------------------------\n");CHKERRQ(ierr);*/ 30283b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local vertices\n",PetscGlobalRank,nvc);CHKERRQ(ierr); 30293b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local faces\n",PetscGlobalRank,nfc);CHKERRQ(ierr); 30303b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local edges\n",PetscGlobalRank,nec);CHKERRQ(ierr); 3031d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 30320c7d97c5SJed Brown } 30330c7d97c5SJed Brown 3034a0ba757dSStefano Zampini /* Restore CSR structure into sequantial matrix and free memory space no longer needed */ 3035a0ba757dSStefano Zampini ierr = MatRestoreRowIJ(mat_adj,0,symmetrize_rowij,compressed_rowij,&mat_graph->nvtxs,&mat_graph->xadj,&mat_graph->adjncy,&flg_row);CHKERRQ(ierr); 30360c7d97c5SJed Brown if(!flg_row) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called from PCBDDCManageLocalBoundaries.\n"); 3037a0ba757dSStefano Zampini ierr = MatDestroy(&mat_adj);CHKERRQ(ierr); 3038a0ba757dSStefano Zampini /* Free graph structure */ 30390c7d97c5SJed Brown if(mat_graph->nvtxs){ 3040a0ba757dSStefano Zampini ierr = PetscFree(neighbours_set[0]);CHKERRQ(ierr); 3041a0ba757dSStefano Zampini ierr = PetscFree(neighbours_set);CHKERRQ(ierr); 3042a0ba757dSStefano Zampini ierr = PetscFree4(mat_graph->where,mat_graph->count,mat_graph->cptr,mat_graph->queue);CHKERRQ(ierr); 3043a0ba757dSStefano Zampini ierr = PetscFree3(mat_graph->which_dof,mat_graph->touched,queue_in_global_numbering);CHKERRQ(ierr); 3044a0ba757dSStefano Zampini ierr = PetscFree(mat_graph->where_ncmps);CHKERRQ(ierr); 30450c7d97c5SJed Brown } 30460c7d97c5SJed Brown ierr = PetscFree(mat_graph);CHKERRQ(ierr); 30470c7d97c5SJed Brown 30480c7d97c5SJed Brown PetscFunctionReturn(0); 30490c7d97c5SJed Brown 30500c7d97c5SJed Brown } 30510c7d97c5SJed Brown 30520c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 30530c7d97c5SJed Brown 30540c7d97c5SJed Brown /* The following code has been adapted from function IsConnectedSubdomain contained 30550c7d97c5SJed Brown in source file contig.c of METIS library (version 5.0.1) */ 30560c7d97c5SJed Brown 30570c7d97c5SJed Brown #undef __FUNCT__ 30580c7d97c5SJed Brown #define __FUNCT__ "PCBDDCFindConnectedComponents" 30599c0446d6SStefano Zampini static PetscErrorCode PCBDDCFindConnectedComponents(PCBDDCGraph graph, PetscInt n_dist ) 30600c7d97c5SJed Brown { 30610c7d97c5SJed Brown PetscInt i, j, k, nvtxs, first, last, nleft, ncmps,pid,cum_queue,n,ncmps_pid; 30620c7d97c5SJed Brown PetscInt *xadj, *adjncy, *where, *queue; 30630c7d97c5SJed Brown PetscInt *cptr; 30640c7d97c5SJed Brown PetscBool *touched; 30650c7d97c5SJed Brown 30660c7d97c5SJed Brown PetscFunctionBegin; 30670c7d97c5SJed Brown 30680c7d97c5SJed Brown nvtxs = graph->nvtxs; 30690c7d97c5SJed Brown xadj = graph->xadj; 30700c7d97c5SJed Brown adjncy = graph->adjncy; 30710c7d97c5SJed Brown where = graph->where; 30720c7d97c5SJed Brown touched = graph->touched; 30730c7d97c5SJed Brown queue = graph->queue; 30740c7d97c5SJed Brown cptr = graph->cptr; 30750c7d97c5SJed Brown 30760c7d97c5SJed Brown for (i=0; i<nvtxs; i++) 30770c7d97c5SJed Brown touched[i] = PETSC_FALSE; 30780c7d97c5SJed Brown 30790c7d97c5SJed Brown cum_queue=0; 30800c7d97c5SJed Brown ncmps=0; 30810c7d97c5SJed Brown 30820c7d97c5SJed Brown for(n=0; n<n_dist; n++) { 3083a0ba757dSStefano Zampini pid = n+1; 30840c7d97c5SJed Brown nleft = 0; 30850c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 30860c7d97c5SJed Brown if (where[i] == pid) 30870c7d97c5SJed Brown nleft++; 30880c7d97c5SJed Brown } 30890c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 30900c7d97c5SJed Brown if (where[i] == pid) 30910c7d97c5SJed Brown break; 30920c7d97c5SJed Brown } 30930c7d97c5SJed Brown touched[i] = PETSC_TRUE; 30940c7d97c5SJed Brown queue[cum_queue] = i; 30950c7d97c5SJed Brown first = 0; last = 1; 30960c7d97c5SJed Brown cptr[ncmps] = cum_queue; /* This actually points to queue */ 30970c7d97c5SJed Brown ncmps_pid = 0; 30980c7d97c5SJed Brown while (first != nleft) { 30990c7d97c5SJed Brown if (first == last) { /* Find another starting vertex */ 31000c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 31010c7d97c5SJed Brown ncmps_pid++; 31020c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 31030c7d97c5SJed Brown if (where[i] == pid && !touched[i]) 31040c7d97c5SJed Brown break; 31050c7d97c5SJed Brown } 31060c7d97c5SJed Brown queue[cum_queue+last] = i; 31070c7d97c5SJed Brown last++; 31080c7d97c5SJed Brown touched[i] = PETSC_TRUE; 31090c7d97c5SJed Brown } 31100c7d97c5SJed Brown i = queue[cum_queue+first]; 31110c7d97c5SJed Brown first++; 31120c7d97c5SJed Brown for (j=xadj[i]; j<xadj[i+1]; j++) { 31130c7d97c5SJed Brown k = adjncy[j]; 31140c7d97c5SJed Brown if (where[k] == pid && !touched[k]) { 31150c7d97c5SJed Brown queue[cum_queue+last] = k; 31160c7d97c5SJed Brown last++; 31170c7d97c5SJed Brown touched[k] = PETSC_TRUE; 31180c7d97c5SJed Brown } 31190c7d97c5SJed Brown } 31200c7d97c5SJed Brown } 31210c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 31220c7d97c5SJed Brown ncmps_pid++; 31230c7d97c5SJed Brown cum_queue=cptr[ncmps]; 3124a0ba757dSStefano Zampini graph->where_ncmps[n] = ncmps_pid; 31250c7d97c5SJed Brown } 31260c7d97c5SJed Brown graph->ncmps = ncmps; 31270c7d97c5SJed Brown 31280c7d97c5SJed Brown PetscFunctionReturn(0); 31290c7d97c5SJed Brown } 31300c7d97c5SJed Brown 3131