153cdbc3dSStefano Zampini /* TODOLIST 2a0ba757dSStefano Zampini allow passing array of IS to identify dof splitting per node (see which_dof array) 3a0ba757dSStefano Zampini change how to deal with the coarse problem (PCBDDCSetCoarseEnvironment): 4a0ba757dSStefano Zampini - mind the problem with coarsening_factor 5a0ba757dSStefano Zampini - simplify coarse problem structure -> PCBDDC or PCREDUDANT, nothing else -> same comm for all levels? 6a0ba757dSStefano Zampini - remove coarse enums and allow use of PCBDDCGetCoarseKSP 7a0ba757dSStefano Zampini - remove metis dependency -> use MatPartitioning for multilevel -> Assemble serial adjacency in ManageLocalBoundaries? 8a0ba757dSStefano Zampini - Add level slot to bddc data structure and associated Set/Get functions 9a0ba757dSStefano Zampini code refactoring: 10a0ba757dSStefano Zampini - removing indices to constraints, quadrature constrainsts and similar from PCBDDCManageLocalBoundaries 11a0ba757dSStefano Zampini - analyze MatSetNearNullSpace as suggested by Jed 12a0ba757dSStefano Zampini - build constraint matrix after SVD on local connected components 13a0ba757dSStefano Zampini - pick up better names for static functions 14a0ba757dSStefano Zampini check log_summary for leaking (actually: 1 Vector per level plus only 1 IS) 15a0ba757dSStefano Zampini Inexact solvers: global preconditioner application is ready, ask to developers (Jed?) on how to best implement Dohrmann's approach (PCSHELL?) 16a0ba757dSStefano Zampini change options structure: 17a0ba757dSStefano Zampini - insert BDDC into MG framework? 18a0ba757dSStefano Zampini provide other ops? Ask to developers 19a0ba757dSStefano Zampini remove all unused printf 20a0ba757dSStefano Zampini remove // commments and adhere to PETSc code requirements 21a0ba757dSStefano Zampini man pages 2253cdbc3dSStefano Zampini */ 230c7d97c5SJed Brown 2453cdbc3dSStefano Zampini /* ---------------------------------------------------------------------------------------------------------------------------------------------- 250c7d97c5SJed Brown Implementation of BDDC preconditioner based on: 260c7d97c5SJed Brown C. Dohrmann "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 2753cdbc3dSStefano Zampini ---------------------------------------------------------------------------------------------------------------------------------------------- */ 2853cdbc3dSStefano Zampini 2953cdbc3dSStefano Zampini #include "bddc.h" /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 300c7d97c5SJed Brown 310c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 320c7d97c5SJed Brown #undef __FUNCT__ 330c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC" 340c7d97c5SJed Brown PetscErrorCode PCSetFromOptions_BDDC(PC pc) 350c7d97c5SJed Brown { 360c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 370c7d97c5SJed Brown PetscErrorCode ierr; 380c7d97c5SJed Brown 390c7d97c5SJed Brown PetscFunctionBegin; 400c7d97c5SJed Brown ierr = PetscOptionsHead("BDDC options");CHKERRQ(ierr); 410c7d97c5SJed Brown /* Verbose debugging of main data structures */ 42e269702eSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_check_all" ,"Verbose (debugging) output for PCBDDC" ,"none",pcbddc->dbg_flag ,&pcbddc->dbg_flag ,PETSC_NULL);CHKERRQ(ierr); 430c7d97c5SJed Brown /* Some customization for default primal space */ 440c7d97c5SJed 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); 450c7d97c5SJed 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); 460c7d97c5SJed 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); 470c7d97c5SJed 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); 480c7d97c5SJed Brown /* Coarse solver context */ 490c7d97c5SJed Brown static const char *avail_coarse_problems[] = {"sequential","replicated","parallel","multilevel",""}; //order of choiches depends on ENUM defined in bddc.h 500c7d97c5SJed 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); 510c7d97c5SJed Brown /* Two different application of BDDC to the whole set of dofs, internal and interface */ 520c7d97c5SJed 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); 530c7d97c5SJed 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); 540c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 550c7d97c5SJed Brown PetscFunctionReturn(0); 560c7d97c5SJed Brown } 570c7d97c5SJed Brown 580c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 590c7d97c5SJed Brown EXTERN_C_BEGIN 600c7d97c5SJed Brown #undef __FUNCT__ 610c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType_BDDC" 6253cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetCoarseProblemType_BDDC(PC pc, CoarseProblemType CPT) 630c7d97c5SJed Brown { 640c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 650c7d97c5SJed Brown 660c7d97c5SJed Brown PetscFunctionBegin; 670c7d97c5SJed Brown pcbddc->coarse_problem_type = CPT; 680c7d97c5SJed Brown PetscFunctionReturn(0); 690c7d97c5SJed Brown } 700c7d97c5SJed Brown EXTERN_C_END 710c7d97c5SJed Brown 720c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 730c7d97c5SJed Brown #undef __FUNCT__ 740c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType" 7553cdbc3dSStefano Zampini /*@ 7653cdbc3dSStefano Zampini PCBDDCSetCoarseProblemType - brief explanation 7753cdbc3dSStefano Zampini 7853cdbc3dSStefano Zampini Collective on PC 7953cdbc3dSStefano Zampini 8053cdbc3dSStefano Zampini Input Parameters: 8153cdbc3dSStefano Zampini + pc - the preconditioning context 8253cdbc3dSStefano Zampini - CoarseProblemType - pick a better name and explain what this is 8353cdbc3dSStefano Zampini 8453cdbc3dSStefano Zampini Level: intermediate 8553cdbc3dSStefano Zampini 8653cdbc3dSStefano Zampini Notes: 8753cdbc3dSStefano Zampini usage notes, perhaps an example 8853cdbc3dSStefano Zampini 8953cdbc3dSStefano Zampini .seealso: PCBDDC 9053cdbc3dSStefano Zampini @*/ 910c7d97c5SJed Brown PetscErrorCode PCBDDCSetCoarseProblemType(PC pc, CoarseProblemType CPT) 920c7d97c5SJed Brown { 930c7d97c5SJed Brown PetscErrorCode ierr; 940c7d97c5SJed Brown 950c7d97c5SJed Brown PetscFunctionBegin; 960c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 970c7d97c5SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetCoarseProblemType_C",(PC,CoarseProblemType),(pc,CPT));CHKERRQ(ierr); 980c7d97c5SJed Brown PetscFunctionReturn(0); 990c7d97c5SJed Brown } 1000c7d97c5SJed Brown 1010c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1020c7d97c5SJed Brown EXTERN_C_BEGIN 1030c7d97c5SJed Brown #undef __FUNCT__ 1040c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 10553cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 1060c7d97c5SJed Brown { 1070c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 10853cdbc3dSStefano Zampini PetscErrorCode ierr; 1090c7d97c5SJed Brown 1100c7d97c5SJed Brown PetscFunctionBegin; 11153cdbc3dSStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 11253cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 11353cdbc3dSStefano Zampini ierr = ISDuplicate(NeumannBoundaries,&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 11453cdbc3dSStefano Zampini ierr = ISCopy(NeumannBoundaries,pcbddc->NeumannBoundaries);CHKERRQ(ierr); 1150c7d97c5SJed Brown PetscFunctionReturn(0); 1160c7d97c5SJed Brown } 1170c7d97c5SJed Brown EXTERN_C_END 1180c7d97c5SJed Brown 1190c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1200c7d97c5SJed Brown #undef __FUNCT__ 1210c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 12257527edcSJed Brown /*@ 12353cdbc3dSStefano Zampini PCBDDCSetNeumannBoundaries - Set index set defining subdomain part of 12453cdbc3dSStefano Zampini Neumann boundaries for the global problem. 12557527edcSJed Brown 12653cdbc3dSStefano Zampini Logically Collective on PC 12757527edcSJed Brown 12857527edcSJed Brown Input Parameters: 12957527edcSJed Brown + pc - the preconditioning context 13053cdbc3dSStefano Zampini - NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 13157527edcSJed Brown 13257527edcSJed Brown Level: intermediate 13357527edcSJed Brown 13457527edcSJed Brown Notes: 13557527edcSJed Brown usage notes, perhaps an example 13657527edcSJed Brown 13757527edcSJed Brown .seealso: PCBDDC 13857527edcSJed Brown @*/ 13953cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 1400c7d97c5SJed Brown { 1410c7d97c5SJed Brown PetscErrorCode ierr; 1420c7d97c5SJed Brown 1430c7d97c5SJed Brown PetscFunctionBegin; 1440c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 14553cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 14653cdbc3dSStefano Zampini PetscFunctionReturn(0); 14753cdbc3dSStefano Zampini } 14853cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 14953cdbc3dSStefano Zampini EXTERN_C_BEGIN 15053cdbc3dSStefano Zampini #undef __FUNCT__ 15153cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 15253cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 15353cdbc3dSStefano Zampini { 15453cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15553cdbc3dSStefano Zampini 15653cdbc3dSStefano Zampini PetscFunctionBegin; 15753cdbc3dSStefano Zampini if(pcbddc->NeumannBoundaries) { 15853cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 15953cdbc3dSStefano Zampini } else { 16053cdbc3dSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Error in %s: Neumann boundaries not set!.\n",__FUNCT__); 16153cdbc3dSStefano Zampini } 16253cdbc3dSStefano Zampini PetscFunctionReturn(0); 16353cdbc3dSStefano Zampini } 16453cdbc3dSStefano Zampini EXTERN_C_END 16553cdbc3dSStefano Zampini 16653cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 16753cdbc3dSStefano Zampini #undef __FUNCT__ 16853cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 16953cdbc3dSStefano Zampini /*@ 17053cdbc3dSStefano Zampini PCBDDCGetNeumannBoundaries - Get index set defining subdomain part of 17153cdbc3dSStefano Zampini Neumann boundaries for the global problem. 17253cdbc3dSStefano Zampini 17353cdbc3dSStefano Zampini Logically Collective on PC 17453cdbc3dSStefano Zampini 17553cdbc3dSStefano Zampini Input Parameters: 17653cdbc3dSStefano Zampini + pc - the preconditioning context 17753cdbc3dSStefano Zampini 17853cdbc3dSStefano Zampini Output Parameters: 17953cdbc3dSStefano Zampini + NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 18053cdbc3dSStefano Zampini 18153cdbc3dSStefano Zampini Level: intermediate 18253cdbc3dSStefano Zampini 18353cdbc3dSStefano Zampini Notes: 18453cdbc3dSStefano Zampini usage notes, perhaps an example 18553cdbc3dSStefano Zampini 18653cdbc3dSStefano Zampini .seealso: PCBDDC 18753cdbc3dSStefano Zampini @*/ 18853cdbc3dSStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 18953cdbc3dSStefano Zampini { 19053cdbc3dSStefano Zampini PetscErrorCode ierr; 19153cdbc3dSStefano Zampini 19253cdbc3dSStefano Zampini PetscFunctionBegin; 19353cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 19453cdbc3dSStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 1950c7d97c5SJed Brown PetscFunctionReturn(0); 1960c7d97c5SJed Brown } 1970c7d97c5SJed Brown 19853cdbc3dSStefano Zampini #undef __FUNCT__ 19953cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 2000c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2010c7d97c5SJed Brown /* 2020c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 2030c7d97c5SJed Brown by setting data structures and options. 2040c7d97c5SJed Brown 2050c7d97c5SJed Brown Input Parameter: 20653cdbc3dSStefano Zampini + pc - the preconditioner context 2070c7d97c5SJed Brown 2080c7d97c5SJed Brown Application Interface Routine: PCSetUp() 2090c7d97c5SJed Brown 2100c7d97c5SJed Brown Notes: 2110c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 2120c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 2130c7d97c5SJed Brown */ 21453cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 2150c7d97c5SJed Brown { 2160c7d97c5SJed Brown PetscErrorCode ierr; 2170c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2180c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 2190c7d97c5SJed Brown 2200c7d97c5SJed Brown PetscFunctionBegin; 2210c7d97c5SJed Brown if (!pc->setupcalled) { 2220c7d97c5SJed Brown 2230c7d97c5SJed Brown /* For BDDC we need to define a local "Neumann" to that defined in PCISSetup 2240c7d97c5SJed Brown So, we set to pcnone the Neumann problem of pcid in order to avoid unneeded computation 2250c7d97c5SJed Brown Also, we decide to directly build the (same) Dirichlet problem */ 2260c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localN_pc_type","none");CHKERRQ(ierr); 2270c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localD_pc_type","none");CHKERRQ(ierr); 2280c7d97c5SJed Brown /* Set up all the "iterative substructuring" common block */ 2290c7d97c5SJed Brown ierr = PCISSetUp(pc);CHKERRQ(ierr); 2300c7d97c5SJed Brown /* Destroy some PC_IS data which is not needed by BDDC */ 2310c7d97c5SJed Brown //if (pcis->ksp_D) {ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr);} 2320c7d97c5SJed Brown //if (pcis->ksp_N) {ierr = KSPDestroy(&pcis->ksp_N);CHKERRQ(ierr);} 2330c7d97c5SJed Brown //if (pcis->vec2_B) {ierr = VecDestroy(&pcis->vec2_B);CHKERRQ(ierr);} 2340c7d97c5SJed Brown //if (pcis->vec3_B) {ierr = VecDestroy(&pcis->vec3_B);CHKERRQ(ierr);} 2350c7d97c5SJed Brown //pcis->ksp_D = 0; 2360c7d97c5SJed Brown //pcis->ksp_N = 0; 2370c7d97c5SJed Brown //pcis->vec2_B = 0; 2380c7d97c5SJed Brown //pcis->vec3_B = 0; 239e269702eSStefano Zampini if(pcbddc->dbg_flag) { 240e269702eSStefano Zampini ierr = PetscViewerASCIIGetStdout(((PetscObject)pc)->comm,&pcbddc->dbg_viewer);CHKERRQ(ierr); 241e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 242e269702eSStefano Zampini } 2430c7d97c5SJed Brown 2440c7d97c5SJed Brown //TODO MOVE CODE FRAGMENT 2450c7d97c5SJed Brown PetscInt im_active=0; 2460c7d97c5SJed Brown if(pcis->n) im_active = 1; 24753cdbc3dSStefano Zampini ierr = MPI_Allreduce(&im_active,&pcbddc->active_procs,1,MPIU_INT,MPI_SUM,((PetscObject)pc)->comm);CHKERRQ(ierr); 2480c7d97c5SJed Brown //printf("Calling PCBDDC MANAGE with active procs %d (im_active = %d)\n",pcbddc->active_procs,im_active); 2490c7d97c5SJed Brown /* Set up grid quantities for BDDC */ 2500c7d97c5SJed Brown //TODO only active procs must call this -> remove synchronized print inside (the only point of sync) 2510c7d97c5SJed Brown ierr = PCBDDCManageLocalBoundaries(pc);CHKERRQ(ierr); 2520c7d97c5SJed Brown 2530c7d97c5SJed Brown /* Create coarse and local stuffs used for evaluating action of preconditioner */ 2540c7d97c5SJed Brown ierr = PCBDDCCoarseSetUp(pc);CHKERRQ(ierr); 2550c7d97c5SJed Brown 2560c7d97c5SJed Brown if ( !pcis->n_neigh ) pcis->ISLocalToGlobalMappingGetInfoWasCalled=PETSC_FALSE; //processes fakely involved in multilevel should not call ISLocalToGlobalMappingRestoreInfo 2570c7d97c5SJed Brown /* We no more need this matrix */ 2580c7d97c5SJed Brown //if (pcis->A_BB) {ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr);} 2590c7d97c5SJed Brown //pcis->A_BB = 0; 2600c7d97c5SJed Brown 2610c7d97c5SJed Brown //printf("Using coarse problem type %d\n",pcbddc->coarse_problem_type); 2620c7d97c5SJed Brown //printf("Using coarse communications type %d\n",pcbddc->coarse_communications_type); 2630c7d97c5SJed Brown //printf("Using coarsening ratio %d\n",pcbddc->coarsening_ratio); 2640c7d97c5SJed Brown } 2650c7d97c5SJed Brown 2660c7d97c5SJed Brown PetscFunctionReturn(0); 2670c7d97c5SJed Brown } 2680c7d97c5SJed Brown 2690c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2700c7d97c5SJed Brown /* 2710c7d97c5SJed Brown PCApply_BDDC - Applies the BDDC preconditioner to a vector. 2720c7d97c5SJed Brown 2730c7d97c5SJed Brown Input Parameters: 2740c7d97c5SJed Brown . pc - the preconditioner context 2750c7d97c5SJed Brown . r - input vector (global) 2760c7d97c5SJed Brown 2770c7d97c5SJed Brown Output Parameter: 2780c7d97c5SJed Brown . z - output vector (global) 2790c7d97c5SJed Brown 2800c7d97c5SJed Brown Application Interface Routine: PCApply() 2810c7d97c5SJed Brown */ 2820c7d97c5SJed Brown #undef __FUNCT__ 2830c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 28453cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 2850c7d97c5SJed Brown { 2860c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 2870c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 2880c7d97c5SJed Brown PetscErrorCode ierr; 2890c7d97c5SJed Brown PetscScalar one = 1.0; 2900c7d97c5SJed Brown PetscScalar m_one = -1.0; 2910c7d97c5SJed Brown 2920c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 2930c7d97c5SJed Brown NN interface preconditioner changed to BDDC 2940c7d97c5SJed Brown Added support for M_3 preconditioenr in the reference article (code is active if pcbddc->prec_type = PETSC_TRUE) */ 2950c7d97c5SJed Brown 2960c7d97c5SJed Brown PetscFunctionBegin; 2970c7d97c5SJed Brown /* First Dirichlet solve */ 2980c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2990c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 30053cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 3010c7d97c5SJed Brown /* 3020c7d97c5SJed Brown Assembling right hand side for BDDC operator 3030c7d97c5SJed Brown - vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE) 3040c7d97c5SJed Brown - the interface part of the global vector z 3050c7d97c5SJed Brown */ 3060c7d97c5SJed Brown //ierr = VecScatterBegin(pcis->global_to_B,r,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3070c7d97c5SJed Brown //ierr = VecScatterEnd (pcis->global_to_B,r,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3080c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 3090c7d97c5SJed Brown ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 3100c7d97c5SJed Brown //ierr = MatMultAdd(pcis->A_BI,pcis->vec2_D,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 3110c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3120c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 3130c7d97c5SJed Brown ierr = VecCopy(r,z);CHKERRQ(ierr); 3140c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3150c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3160c7d97c5SJed Brown 3170c7d97c5SJed Brown /* 3180c7d97c5SJed Brown Apply interface preconditioner 3190c7d97c5SJed Brown Results are stored in: 3200c7d97c5SJed Brown - vec1_D (if needed, i.e. with prec_type = PETSC_TRUE) 3210c7d97c5SJed Brown - the interface part of the global vector z 3220c7d97c5SJed Brown */ 3230c7d97c5SJed Brown ierr = PCBDDCApplyInterfacePreconditioner(pc,z);CHKERRQ(ierr); 3240c7d97c5SJed Brown 3250c7d97c5SJed Brown /* Second Dirichlet solves and assembling of output */ 3260c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3270c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3280c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 3290c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 33053cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr); 3310c7d97c5SJed Brown ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr); 3320c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); } 3330c7d97c5SJed Brown ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr); 3340c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3350c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3360c7d97c5SJed Brown 3370c7d97c5SJed Brown PetscFunctionReturn(0); 3380c7d97c5SJed Brown 3390c7d97c5SJed Brown } 3400c7d97c5SJed Brown 3410c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 3420c7d97c5SJed Brown /* 3430c7d97c5SJed Brown PCBDDCApplyInterfacePreconditioner - Apply the BDDC preconditioner at the interface. 3440c7d97c5SJed Brown 3450c7d97c5SJed Brown */ 3460c7d97c5SJed Brown #undef __FUNCT__ 3470c7d97c5SJed Brown #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 34853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, Vec z) 3490c7d97c5SJed Brown { 3500c7d97c5SJed Brown PetscErrorCode ierr; 3510c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 3520c7d97c5SJed Brown PC_IS* pcis = (PC_IS*) (pc->data); 3530c7d97c5SJed Brown PetscScalar zero = 0.0; 3540c7d97c5SJed Brown 3550c7d97c5SJed Brown PetscFunctionBegin; 3560c7d97c5SJed Brown /* Get Local boundary and apply partition of unity */ 3570c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3580c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3590c7d97c5SJed Brown ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 3600c7d97c5SJed Brown 3610c7d97c5SJed Brown /* Application of PHI^T */ 3620c7d97c5SJed Brown ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 3630c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 3640c7d97c5SJed Brown 3650c7d97c5SJed Brown /* Scatter data of coarse_rhs */ 3660c7d97c5SJed Brown if(pcbddc->coarse_rhs) ierr = VecSet(pcbddc->coarse_rhs,zero);CHKERRQ(ierr); 3670c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3680c7d97c5SJed Brown 3690c7d97c5SJed Brown /* Local solution on R nodes */ 3700c7d97c5SJed Brown ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 3710c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3720c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3730c7d97c5SJed Brown if(pcbddc->prec_type) { 3740c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3750c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3760c7d97c5SJed Brown } 3770c7d97c5SJed Brown ierr = PCBDDCSolveSaddlePoint(pc);CHKERRQ(ierr); 3780c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 3790c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3800c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3810c7d97c5SJed Brown if(pcbddc->prec_type) { 3820c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3830c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3840c7d97c5SJed Brown } 3850c7d97c5SJed Brown 3860c7d97c5SJed Brown /* Coarse solution */ 3870c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 38853cdbc3dSStefano Zampini if(pcbddc->coarse_rhs) ierr = KSPSolve(pcbddc->coarse_ksp,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 3890c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3900c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd (pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3910c7d97c5SJed Brown 3920c7d97c5SJed Brown /* Sum contributions from two levels */ 3930c7d97c5SJed Brown /* Apply partition of unity and sum boundary values */ 3940c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 3950c7d97c5SJed Brown ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 3960c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3970c7d97c5SJed Brown ierr = VecSet(z,zero);CHKERRQ(ierr); 3980c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3990c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4000c7d97c5SJed Brown 4010c7d97c5SJed Brown PetscFunctionReturn(0); 4020c7d97c5SJed Brown } 4030c7d97c5SJed Brown 4040c7d97c5SJed Brown 4050c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 4060c7d97c5SJed Brown /* 4070c7d97c5SJed Brown PCBDDCSolveSaddlePoint 4080c7d97c5SJed Brown 4090c7d97c5SJed Brown */ 4100c7d97c5SJed Brown #undef __FUNCT__ 4110c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSolveSaddlePoint" 41253cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSolveSaddlePoint(PC pc) 4130c7d97c5SJed Brown { 4140c7d97c5SJed Brown PetscErrorCode ierr; 4150c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4160c7d97c5SJed Brown 4170c7d97c5SJed Brown PetscFunctionBegin; 4180c7d97c5SJed Brown 41953cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4200c7d97c5SJed Brown if(pcbddc->n_constraints) { 4210c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec2_R,pcbddc->vec1_C);CHKERRQ(ierr); 4220c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 4230c7d97c5SJed Brown } 4240c7d97c5SJed Brown 4250c7d97c5SJed Brown PetscFunctionReturn(0); 4260c7d97c5SJed Brown } 4270c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 4280c7d97c5SJed Brown /* 4290c7d97c5SJed Brown PCBDDCScatterCoarseDataBegin 4300c7d97c5SJed Brown 4310c7d97c5SJed Brown */ 4320c7d97c5SJed Brown #undef __FUNCT__ 4330c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 43453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,Vec vec_from, Vec vec_to, InsertMode imode, ScatterMode smode) 4350c7d97c5SJed Brown { 4360c7d97c5SJed Brown PetscErrorCode ierr; 4370c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4380c7d97c5SJed Brown 4390c7d97c5SJed Brown PetscFunctionBegin; 4400c7d97c5SJed Brown 4410c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 4420c7d97c5SJed Brown case SCATTERS_BDDC: 4430c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 4440c7d97c5SJed Brown break; 4450c7d97c5SJed Brown case GATHERS_BDDC: 4460c7d97c5SJed Brown break; 4470c7d97c5SJed Brown } 4480c7d97c5SJed Brown PetscFunctionReturn(0); 4490c7d97c5SJed Brown 4500c7d97c5SJed Brown } 4510c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 4520c7d97c5SJed Brown /* 4530c7d97c5SJed Brown PCBDDCScatterCoarseDataEnd 4540c7d97c5SJed Brown 4550c7d97c5SJed Brown */ 4560c7d97c5SJed Brown #undef __FUNCT__ 4570c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 45853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc,Vec vec_from, Vec vec_to, InsertMode imode, ScatterMode smode) 4590c7d97c5SJed Brown { 4600c7d97c5SJed Brown PetscErrorCode ierr; 4610c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4620c7d97c5SJed Brown PetscScalar* array_to; 4630c7d97c5SJed Brown PetscScalar* array_from; 4640c7d97c5SJed Brown MPI_Comm comm=((PetscObject)pc)->comm; 4650c7d97c5SJed Brown PetscInt i; 4660c7d97c5SJed Brown 4670c7d97c5SJed Brown PetscFunctionBegin; 4680c7d97c5SJed Brown 4690c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 4700c7d97c5SJed Brown case SCATTERS_BDDC: 4710c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 4720c7d97c5SJed Brown break; 4730c7d97c5SJed Brown case GATHERS_BDDC: 4740c7d97c5SJed Brown if(vec_from) VecGetArray(vec_from,&array_from); 4750c7d97c5SJed Brown if(vec_to) VecGetArray(vec_to,&array_to); 4760c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 4770c7d97c5SJed Brown case SEQUENTIAL_BDDC: 4780c7d97c5SJed Brown if(smode == SCATTER_FORWARD) { 47953cdbc3dSStefano 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); 4800c7d97c5SJed Brown if(vec_to) { 4810c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 4820c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 4830c7d97c5SJed Brown } 4840c7d97c5SJed Brown } else { 4850c7d97c5SJed Brown if(vec_from) 4860c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 4870c7d97c5SJed Brown pcbddc->replicated_local_primal_values[i]=array_from[pcbddc->replicated_local_primal_indices[i]]; 48853cdbc3dSStefano 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); 4890c7d97c5SJed Brown } 4900c7d97c5SJed Brown break; 4910c7d97c5SJed Brown case REPLICATED_BDDC: 4920c7d97c5SJed Brown if(smode == SCATTER_FORWARD) { 49353cdbc3dSStefano 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); 4940c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 4950c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 4960c7d97c5SJed Brown } else { /* no communications needed for SCATTER_REVERSE since needed data is already present */ 4970c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_size;i++) 4980c7d97c5SJed Brown array_to[i]=array_from[pcbddc->local_primal_indices[i]]; 4990c7d97c5SJed Brown } 5000c7d97c5SJed Brown break; 50153cdbc3dSStefano Zampini case MULTILEVEL_BDDC: 50253cdbc3dSStefano Zampini break; 50353cdbc3dSStefano Zampini case PARALLEL_BDDC: 50453cdbc3dSStefano Zampini break; 5050c7d97c5SJed Brown } 5060c7d97c5SJed Brown if(vec_from) VecRestoreArray(vec_from,&array_from); 5070c7d97c5SJed Brown if(vec_to) VecRestoreArray(vec_to,&array_to); 5080c7d97c5SJed Brown break; 5090c7d97c5SJed Brown } 5100c7d97c5SJed Brown PetscFunctionReturn(0); 5110c7d97c5SJed Brown 5120c7d97c5SJed Brown } 5130c7d97c5SJed Brown 5140c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 5150c7d97c5SJed Brown /* 5160c7d97c5SJed Brown PCDestroy_BDDC - Destroys the private context for the NN preconditioner 5170c7d97c5SJed Brown that was created with PCCreate_BDDC(). 5180c7d97c5SJed Brown 5190c7d97c5SJed Brown Input Parameter: 5200c7d97c5SJed Brown . pc - the preconditioner context 5210c7d97c5SJed Brown 5220c7d97c5SJed Brown Application Interface Routine: PCDestroy() 5230c7d97c5SJed Brown */ 5240c7d97c5SJed Brown #undef __FUNCT__ 5250c7d97c5SJed Brown #define __FUNCT__ "PCDestroy_BDDC" 52653cdbc3dSStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 5270c7d97c5SJed Brown { 5280c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5290c7d97c5SJed Brown PetscErrorCode ierr; 5300c7d97c5SJed Brown 5310c7d97c5SJed Brown PetscFunctionBegin; 5320c7d97c5SJed Brown /* free data created by PCIS */ 5330c7d97c5SJed Brown ierr = PCISDestroy(pc);CHKERRQ(ierr); 5340c7d97c5SJed Brown /* free BDDC data */ 53553cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 53653cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->coarse_rhs);CHKERRQ(ierr); 53753cdbc3dSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 53853cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_mat);CHKERRQ(ierr); 53953cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 54053cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 54153cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 54253cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 54353cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 54453cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 54553cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 54653cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 54753cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec4_D);CHKERRQ(ierr); 54853cdbc3dSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 54953cdbc3dSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 55053cdbc3dSStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 55153cdbc3dSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 55253cdbc3dSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 55353cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 55453cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->vertices);CHKERRQ(ierr); 55553cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->local_primal_indices);CHKERRQ(ierr); 55653cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 5570c7d97c5SJed Brown if (pcbddc->replicated_local_primal_values) { free(pcbddc->replicated_local_primal_values); } 55853cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->local_primal_displacements);CHKERRQ(ierr); 55953cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->local_primal_sizes);CHKERRQ(ierr); 5600c7d97c5SJed Brown if (pcbddc->n_constraints) { 5610c7d97c5SJed Brown ierr = PetscFree(pcbddc->indices_to_constraint[0]);CHKERRQ(ierr); 5620c7d97c5SJed Brown ierr = PetscFree(pcbddc->indices_to_constraint);CHKERRQ(ierr); 5630c7d97c5SJed Brown ierr = PetscFree(pcbddc->quadrature_constraint[0]);CHKERRQ(ierr); 5640c7d97c5SJed Brown ierr = PetscFree(pcbddc->quadrature_constraint);CHKERRQ(ierr); 5650c7d97c5SJed Brown ierr = PetscFree(pcbddc->sizes_of_constraint);CHKERRQ(ierr); 5660c7d97c5SJed Brown } 5670c7d97c5SJed Brown /* Free the private data structure that was hanging off the PC */ 5680c7d97c5SJed Brown ierr = PetscFree(pcbddc);CHKERRQ(ierr); 5690c7d97c5SJed Brown PetscFunctionReturn(0); 5700c7d97c5SJed Brown } 5710c7d97c5SJed Brown 5720c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 5730c7d97c5SJed Brown /*MC 5740c7d97c5SJed Brown PCBDDC - Balancing Domain Decomposition by Constraints. 5750c7d97c5SJed Brown 5760c7d97c5SJed Brown Options Database Keys: 577a0ba757dSStefano Zampini . -pcbddc ??? - 5780c7d97c5SJed Brown 5790c7d97c5SJed Brown Level: intermediate 5800c7d97c5SJed Brown 5810c7d97c5SJed Brown Notes: The matrix used with this preconditioner must be of type MATIS 5820c7d97c5SJed Brown 5830c7d97c5SJed Brown Unlike more 'conventional' interface preconditioners, this iterates over ALL the 5840c7d97c5SJed Brown degrees of freedom, NOT just those on the interface (this allows the use of approximate solvers 5850c7d97c5SJed Brown on the subdomains). 5860c7d97c5SJed Brown 587a0ba757dSStefano Zampini Options for the coarse grid preconditioner can be set with - 588a0ba757dSStefano Zampini Options for the Dirichlet subproblem can be set with - 589a0ba757dSStefano Zampini Options for the Neumann subproblem can be set with - 5900c7d97c5SJed Brown 5910c7d97c5SJed Brown Contributed by Stefano Zampini 5920c7d97c5SJed Brown 5930c7d97c5SJed Brown .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 5940c7d97c5SJed Brown M*/ 5950c7d97c5SJed Brown EXTERN_C_BEGIN 5960c7d97c5SJed Brown #undef __FUNCT__ 5970c7d97c5SJed Brown #define __FUNCT__ "PCCreate_BDDC" 5980c7d97c5SJed Brown PetscErrorCode PCCreate_BDDC(PC pc) 5990c7d97c5SJed Brown { 6000c7d97c5SJed Brown PetscErrorCode ierr; 6010c7d97c5SJed Brown PC_BDDC *pcbddc; 6020c7d97c5SJed Brown 6030c7d97c5SJed Brown PetscFunctionBegin; 6040c7d97c5SJed Brown /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 6050c7d97c5SJed Brown ierr = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr); 6060c7d97c5SJed Brown pc->data = (void*)pcbddc; 6070c7d97c5SJed Brown /* create PCIS data structure */ 6080c7d97c5SJed Brown ierr = PCISCreate(pc);CHKERRQ(ierr); 6090c7d97c5SJed Brown /* BDDC specific */ 6100c7d97c5SJed Brown pcbddc->coarse_vec = 0; 6110c7d97c5SJed Brown pcbddc->coarse_rhs = 0; 61253cdbc3dSStefano Zampini pcbddc->coarse_ksp = 0; 6130c7d97c5SJed Brown pcbddc->coarse_phi_B = 0; 6140c7d97c5SJed Brown pcbddc->coarse_phi_D = 0; 6150c7d97c5SJed Brown pcbddc->vec1_P = 0; 6160c7d97c5SJed Brown pcbddc->vec1_R = 0; 6170c7d97c5SJed Brown pcbddc->vec2_R = 0; 6180c7d97c5SJed Brown pcbddc->local_auxmat1 = 0; 6190c7d97c5SJed Brown pcbddc->local_auxmat2 = 0; 6200c7d97c5SJed Brown pcbddc->R_to_B = 0; 6210c7d97c5SJed Brown pcbddc->R_to_D = 0; 62253cdbc3dSStefano Zampini pcbddc->ksp_D = 0; 62353cdbc3dSStefano Zampini pcbddc->ksp_R = 0; 6240c7d97c5SJed Brown pcbddc->n_constraints = 0; 6250c7d97c5SJed Brown pcbddc->n_vertices = 0; 6260c7d97c5SJed Brown pcbddc->vertices = 0; 6270c7d97c5SJed Brown pcbddc->indices_to_constraint = 0; 6280c7d97c5SJed Brown pcbddc->quadrature_constraint = 0; 6290c7d97c5SJed Brown pcbddc->sizes_of_constraint = 0; 6300c7d97c5SJed Brown pcbddc->local_primal_indices = 0; 6310c7d97c5SJed Brown pcbddc->prec_type = PETSC_FALSE; 63253cdbc3dSStefano Zampini pcbddc->NeumannBoundaries = 0; 6330c7d97c5SJed Brown pcbddc->local_primal_sizes = 0; 6340c7d97c5SJed Brown pcbddc->local_primal_displacements = 0; 6350c7d97c5SJed Brown pcbddc->replicated_local_primal_indices = 0; 6360c7d97c5SJed Brown pcbddc->replicated_local_primal_values = 0; 6370c7d97c5SJed Brown pcbddc->coarse_loc_to_glob = 0; 638e269702eSStefano Zampini pcbddc->dbg_flag = PETSC_FALSE; 6390c7d97c5SJed Brown pcbddc->vertices_flag = PETSC_FALSE; 6400c7d97c5SJed Brown pcbddc->constraints_flag = PETSC_FALSE; 6410c7d97c5SJed Brown pcbddc->faces_flag = PETSC_FALSE; 6420c7d97c5SJed Brown pcbddc->edges_flag = PETSC_FALSE; 6430c7d97c5SJed Brown pcbddc->coarsening_ratio = 8; 6440c7d97c5SJed Brown /* function pointers */ 6450c7d97c5SJed Brown pc->ops->apply = PCApply_BDDC; 6460c7d97c5SJed Brown pc->ops->applytranspose = 0; 6470c7d97c5SJed Brown pc->ops->setup = PCSetUp_BDDC; 6480c7d97c5SJed Brown pc->ops->destroy = PCDestroy_BDDC; 6490c7d97c5SJed Brown pc->ops->setfromoptions = PCSetFromOptions_BDDC; 6500c7d97c5SJed Brown pc->ops->view = 0; 6510c7d97c5SJed Brown pc->ops->applyrichardson = 0; 6520c7d97c5SJed Brown pc->ops->applysymmetricleft = 0; 6530c7d97c5SJed Brown pc->ops->applysymmetricright = 0; 6540c7d97c5SJed Brown /* composing function */ 6550c7d97c5SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C","PCBDDCSetNeumannBoundaries_BDDC", 6560c7d97c5SJed Brown PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 65753cdbc3dSStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C","PCBDDCGetNeumannBoundaries_BDDC", 65853cdbc3dSStefano Zampini PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 6590c7d97c5SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetCoarseProblemType_C","PCBDDCSetCoarseProblemType_BDDC", 6600c7d97c5SJed Brown PCBDDCSetCoarseProblemType_BDDC);CHKERRQ(ierr); 6610c7d97c5SJed Brown PetscFunctionReturn(0); 6620c7d97c5SJed Brown } 6630c7d97c5SJed Brown EXTERN_C_END 6640c7d97c5SJed Brown 6650c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 6660c7d97c5SJed Brown /* 6670c7d97c5SJed Brown PCBDDCCoarseSetUp - 6680c7d97c5SJed Brown */ 6690c7d97c5SJed Brown #undef __FUNCT__ 6700c7d97c5SJed Brown #define __FUNCT__ "PCBDDCCoarseSetUp" 67153cdbc3dSStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC pc) 6720c7d97c5SJed Brown { 6730c7d97c5SJed Brown PetscErrorCode ierr; 6740c7d97c5SJed Brown 6750c7d97c5SJed Brown PC_IS* pcis = (PC_IS*)(pc->data); 6760c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 6770c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 6780c7d97c5SJed Brown IS is_R_local; 6790c7d97c5SJed Brown IS is_V_local; 6800c7d97c5SJed Brown IS is_C_local; 6810c7d97c5SJed Brown IS is_aux1; 6820c7d97c5SJed Brown IS is_aux2; 6830c7d97c5SJed Brown const VecType impVecType; 6840c7d97c5SJed Brown const MatType impMatType; 6850c7d97c5SJed Brown PetscInt n_R=0; 6860c7d97c5SJed Brown PetscInt n_D=0; 6870c7d97c5SJed Brown PetscInt n_B=0; 6880c7d97c5SJed Brown PetscMPIInt totprocs; 6890c7d97c5SJed Brown PetscScalar zero=0.0; 6900c7d97c5SJed Brown PetscScalar one=1.0; 6910c7d97c5SJed Brown PetscScalar m_one=-1.0; 6920c7d97c5SJed Brown PetscScalar* array; 6930c7d97c5SJed Brown PetscScalar *coarse_submat_vals; 6940c7d97c5SJed Brown PetscInt *idx_R_local; 6950c7d97c5SJed Brown PetscInt *idx_V_B; 6960c7d97c5SJed Brown PetscScalar *coarsefunctions_errors; 6970c7d97c5SJed Brown PetscScalar *constraints_errors; 6980c7d97c5SJed Brown /* auxiliary indices */ 6990c7d97c5SJed Brown PetscInt s,i,j,k; 700e269702eSStefano Zampini /* for verbose output of bddc */ 701e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 702e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 703a0ba757dSStefano Zampini /* for counting coarse dofs */ 704a0ba757dSStefano Zampini PetscScalar coarsesum; 7050c7d97c5SJed Brown 7060c7d97c5SJed Brown PetscFunctionBegin; 7070c7d97c5SJed Brown /* Set Non-overlapping dimensions */ 7080c7d97c5SJed Brown n_B = pcis->n_B; n_D = pcis->n - n_B; 7090c7d97c5SJed Brown /* Set local primal size */ 7100c7d97c5SJed Brown pcbddc->local_primal_size = pcbddc->n_vertices + pcbddc->n_constraints; 711a0ba757dSStefano 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) */ 712a0ba757dSStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 713a0ba757dSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 714a0ba757dSStefano Zampini for(i=0;i<pcbddc->n_vertices;i++) { array[ pcbddc->vertices[i] ] = one; } 715a0ba757dSStefano Zampini for(i=0;i<pcbddc->n_constraints;i++) { 716a0ba757dSStefano Zampini for (j=0; j<pcbddc->sizes_of_constraint[i]; j++) { 717a0ba757dSStefano Zampini k = pcbddc->indices_to_constraint[i][j]; 718a0ba757dSStefano Zampini if( array[k] == zero ) { 719a0ba757dSStefano Zampini array[k] = one; 720a0ba757dSStefano Zampini break; 721a0ba757dSStefano Zampini } 722a0ba757dSStefano Zampini } 723a0ba757dSStefano Zampini } 724a0ba757dSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 725a0ba757dSStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 726a0ba757dSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 727a0ba757dSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 728a0ba757dSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 729a0ba757dSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 730a0ba757dSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 731a0ba757dSStefano Zampini for(i=0;i<pcis->n;i++) { if(array[i] > zero) array[i] = one/array[i]; } 732a0ba757dSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 733a0ba757dSStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 734a0ba757dSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 735a0ba757dSStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 736a0ba757dSStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 737a0ba757dSStefano Zampini pcbddc->coarse_size = (PetscInt) coarsesum; 738a0ba757dSStefano Zampini 7390c7d97c5SJed Brown /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 7400c7d97c5SJed Brown ierr = VecSet(pcis->vec1_N,one);CHKERRQ(ierr); 7410c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7420c7d97c5SJed Brown for (i=0;i<pcbddc->n_vertices;i++) { array[ pcbddc->vertices[i] ] = zero; } 7430c7d97c5SJed Brown ierr = PetscMalloc(( pcis->n - pcbddc->n_vertices )*sizeof(PetscInt),&idx_R_local);CHKERRQ(ierr); 7440c7d97c5SJed Brown for (i=0, n_R=0; i<pcis->n; i++) { if (array[i] == one) { idx_R_local[n_R] = i; n_R++; } } 7450c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 746e269702eSStefano Zampini if(dbg_flag) { 7470c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 7480c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 7490c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 7500c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 7510c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"r_size = %d, v_size = %d, constraints = %d, local_primal_size = %d\n",n_R,pcbddc->n_vertices,pcbddc->n_constraints,pcbddc->local_primal_size);CHKERRQ(ierr); 7520c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 753a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 754a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem = %d (%f)\n",pcbddc->coarse_size,coarsesum);CHKERRQ(ierr); 755a0ba757dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 7560c7d97c5SJed Brown } 7570c7d97c5SJed Brown /* Allocate needed vectors */ 7580c7d97c5SJed Brown /* Set Mat type for local matrices needed by BDDC precondtioner */ 7590c7d97c5SJed Brown impMatType = MATSEQDENSE; 7600c7d97c5SJed Brown impVecType = VECSEQ; 7610c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_D,&pcbddc->vec4_D);CHKERRQ(ierr); 7620c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_N,&pcis->vec2_N);CHKERRQ(ierr); 7630c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_R);CHKERRQ(ierr); 7640c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_R,n_R,n_R);CHKERRQ(ierr); 7650c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 766d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 7670c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_P);CHKERRQ(ierr); 7680c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_P,pcbddc->local_primal_size,pcbddc->local_primal_size);CHKERRQ(ierr); 7690c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 7700c7d97c5SJed Brown 7710c7d97c5SJed Brown /* Creating some index sets needed */ 7720c7d97c5SJed Brown /* For submatrices */ 7730c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,n_R,idx_R_local,PETSC_COPY_VALUES,&is_R_local);CHKERRQ(ierr); 7740c7d97c5SJed Brown if(pcbddc->n_vertices) { ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->vertices,PETSC_COPY_VALUES,&is_V_local);CHKERRQ(ierr); } 7750c7d97c5SJed Brown if(pcbddc->n_constraints) { ierr = ISCreateStride (PETSC_COMM_SELF,pcbddc->n_constraints,pcbddc->n_vertices,1,&is_C_local);CHKERRQ(ierr); } 7760c7d97c5SJed Brown /* For VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 7770c7d97c5SJed Brown { 7780c7d97c5SJed Brown PetscInt *aux_array1; 7790c7d97c5SJed Brown PetscInt *aux_array2; 7800c7d97c5SJed Brown PetscScalar value; 7810c7d97c5SJed Brown 7820c7d97c5SJed Brown ierr = PetscMalloc( (pcis->n_B-pcbddc->n_vertices)*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 7830c7d97c5SJed Brown ierr = PetscMalloc( (pcis->n_B-pcbddc->n_vertices)*sizeof(PetscInt),&aux_array2);CHKERRQ(ierr); 7840c7d97c5SJed Brown 785d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 7860c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7870c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7880c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7890c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7900c7d97c5SJed Brown ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7910c7d97c5SJed Brown ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7920c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7930c7d97c5SJed Brown for (i=0, s=0; i<n_R; i++) { if (array[idx_R_local[i]] > one) { aux_array1[s] = i; s++; } } 7940c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7950c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 7960c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 7970c7d97c5SJed Brown for (i=0, s=0; i<n_B; i++) { if (array[i] > one) { aux_array2[s] = i; s++; } } 7983828260eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 7990c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array2,PETSC_COPY_VALUES,&is_aux2);CHKERRQ(ierr); 8000c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 8010c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 8020c7d97c5SJed Brown ierr = PetscFree(aux_array2);CHKERRQ(ierr); 8030c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 8040c7d97c5SJed Brown ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 8050c7d97c5SJed Brown 806e269702eSStefano Zampini if(pcbddc->prec_type || dbg_flag ) { 8070c7d97c5SJed Brown ierr = PetscMalloc(n_D*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 8080c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8090c7d97c5SJed Brown for (i=0, s=0; i<n_R; i++) { if (array[idx_R_local[i]] == one) { aux_array1[s] = i; s++; } } 8100c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8110c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 8120c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 8130c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 8140c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 8150c7d97c5SJed Brown } 8160c7d97c5SJed Brown 8170c7d97c5SJed Brown /* Check scatters */ 818e269702eSStefano Zampini if(dbg_flag) { 8190c7d97c5SJed Brown 8200c7d97c5SJed Brown Vec vec_aux; 8210c7d97c5SJed Brown 8220c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 8230c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Checking pcbddc->R_to_B scatter\n");CHKERRQ(ierr); 8240c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 825d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 826d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_B,PETSC_NULL);CHKERRQ(ierr); 827d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&vec_aux);CHKERRQ(ierr); 828d49ef151SStefano Zampini ierr = VecCopy(pcbddc->vec1_R,vec_aux);CHKERRQ(ierr); 829d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 830d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 831d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 832d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 833d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 834d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 8350c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_B FORWARD error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 836d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 8370c7d97c5SJed Brown 838d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 839d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_B,PETSC_NULL);CHKERRQ(ierr); 840d49ef151SStefano Zampini ierr = VecDuplicate(pcis->vec1_B,&vec_aux);CHKERRQ(ierr); 841d49ef151SStefano Zampini ierr = VecCopy(pcis->vec1_B,vec_aux);CHKERRQ(ierr); 842d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 843d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 844d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 845d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 846d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcis->vec1_B);CHKERRQ(ierr); 847d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 8480c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_B REVERSE error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 849d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 8500c7d97c5SJed Brown 8510c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 8520c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Checking pcbddc->R_to_D scatter\n");CHKERRQ(ierr); 8530c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 8540c7d97c5SJed Brown 855d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 856d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL);CHKERRQ(ierr); 857d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&vec_aux);CHKERRQ(ierr); 858d49ef151SStefano Zampini ierr = VecCopy(pcbddc->vec1_R,vec_aux);CHKERRQ(ierr); 859d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 860d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 861d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 862d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 863d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 864d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 8650c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_D FORWARD error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 866d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 8670c7d97c5SJed Brown 868d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 869d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL);CHKERRQ(ierr); 870d49ef151SStefano Zampini ierr = VecDuplicate(pcis->vec1_D,&vec_aux);CHKERRQ(ierr); 871d49ef151SStefano Zampini ierr = VecCopy(pcis->vec1_D,vec_aux);CHKERRQ(ierr); 872d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 873d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 874d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 875d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 876d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcis->vec1_D);CHKERRQ(ierr); 877d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 8780c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_D REVERSE error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 879d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 8800c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 8810c7d97c5SJed Brown 8820c7d97c5SJed Brown } 8830c7d97c5SJed Brown } 8840c7d97c5SJed Brown 8850c7d97c5SJed Brown /* vertices in boundary numbering */ 8860c7d97c5SJed Brown if(pcbddc->n_vertices) { 887d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,m_one);CHKERRQ(ierr); 8880c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8890c7d97c5SJed Brown for (i=0; i<pcbddc->n_vertices; i++) { array[ pcbddc->vertices[i] ] = i; } 8900c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 891d49ef151SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 892d49ef151SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8930c7d97c5SJed Brown ierr = PetscMalloc(pcbddc->n_vertices*sizeof(PetscInt),&idx_V_B);CHKERRQ(ierr); 8940c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 8950c7d97c5SJed Brown //printf("vertices in boundary numbering\n"); 8960c7d97c5SJed Brown for (i=0; i<pcbddc->n_vertices; i++) { 8970c7d97c5SJed Brown s=0; 8980c7d97c5SJed Brown while (array[s] != i ) {s++;} 8990c7d97c5SJed Brown idx_V_B[i]=s; 9000c7d97c5SJed Brown //printf("idx_V_B[%d]=%d\n",i,s); 9010c7d97c5SJed Brown } 9020c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 9030c7d97c5SJed Brown } 9040c7d97c5SJed Brown 9050c7d97c5SJed Brown 9060c7d97c5SJed Brown /* Creating PC contexts for local Dirichlet and Neumann problems */ 9070c7d97c5SJed Brown { 9080c7d97c5SJed Brown Mat A_RR; 90953cdbc3dSStefano Zampini PC pc_temp; 9100c7d97c5SJed Brown /* Matrix for Dirichlet problem is A_II -> we already have it from pcis.c code */ 91153cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 91253cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 91353cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II,SAME_PRECONDITIONER);CHKERRQ(ierr); 91453cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 915a0ba757dSStefano Zampini //ierr = KSPSetOptionsPrefix();CHKERRQ(ierr); 9160c7d97c5SJed Brown /* default */ 91753cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 91853cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 9190c7d97c5SJed Brown /* Allow user's customization */ 92053cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 92153cdbc3dSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 92253cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 9230c7d97c5SJed Brown /* Matrix for Neumann problem is A_RR -> we need to create it */ 9240c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_R_local,is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 92553cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 92653cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 92753cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR,SAME_PRECONDITIONER);CHKERRQ(ierr); 92853cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 929a0ba757dSStefano Zampini //ierr = KSPSetOptionsPrefix();CHKERRQ(ierr); 9300c7d97c5SJed Brown /* default */ 93153cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 93253cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 9330c7d97c5SJed Brown /* Allow user's customization */ 93453cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 93553cdbc3dSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 93653cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 937a0ba757dSStefano Zampini /* check Dirichlet and Neumann solvers */ 938e269702eSStefano Zampini if(pcbddc->dbg_flag) { 9390c7d97c5SJed Brown Vec temp_vec; 9400c7d97c5SJed Brown PetscScalar value; 9410c7d97c5SJed Brown 942a0ba757dSStefano Zampini ierr = VecDuplicate(pcis->vec1_D,&temp_vec);CHKERRQ(ierr); 943a0ba757dSStefano Zampini ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL);CHKERRQ(ierr); 944a0ba757dSStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 945a0ba757dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,temp_vec);CHKERRQ(ierr); 946a0ba757dSStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcis->vec1_D);CHKERRQ(ierr); 947a0ba757dSStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 948a0ba757dSStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 949a0ba757dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 950a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 951a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Checking solution of Dirichlet and Neumann problems\n");CHKERRQ(ierr); 952a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Dirichlet solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 953d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&temp_vec);CHKERRQ(ierr); 954d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 955d49ef151SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 956d49ef151SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,temp_vec);CHKERRQ(ierr); 957d49ef151SStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 958d49ef151SStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 959e269702eSStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 9600c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Neumann solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 961d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 9620c7d97c5SJed Brown } 9630c7d97c5SJed Brown /* free Neumann problem's matrix */ 9640c7d97c5SJed Brown ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 9650c7d97c5SJed Brown } 9660c7d97c5SJed Brown 9670c7d97c5SJed Brown /* Assemble all remaining stuff needed to apply BDDC */ 9680c7d97c5SJed Brown { 9690c7d97c5SJed Brown Mat A_RV,A_VR,A_VV; 9700c7d97c5SJed Brown Mat M1,M2; 9710c7d97c5SJed Brown Mat C_CR; 9720c7d97c5SJed Brown Mat CMAT,AUXMAT; 9730c7d97c5SJed Brown Vec vec1_C; 9740c7d97c5SJed Brown Vec vec2_C; 9750c7d97c5SJed Brown Vec vec1_V; 9760c7d97c5SJed Brown Vec vec2_V; 9770c7d97c5SJed Brown PetscInt *nnz; 9780c7d97c5SJed Brown PetscInt *auxindices; 97953cdbc3dSStefano Zampini PetscInt index; 9800c7d97c5SJed Brown PetscScalar* array2; 9810c7d97c5SJed Brown MatFactorInfo matinfo; 9820c7d97c5SJed Brown 9830c7d97c5SJed Brown /* Allocating some extra storage just to be safe */ 9840c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 9850c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&auxindices);CHKERRQ(ierr); 9860c7d97c5SJed Brown for(i=0;i<pcis->n;i++) {auxindices[i]=i;} 9870c7d97c5SJed Brown 9880c7d97c5SJed Brown /* some work vectors on vertices and/or constraints */ 9890c7d97c5SJed Brown if(pcbddc->n_vertices) { 9900c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_V);CHKERRQ(ierr); 9910c7d97c5SJed Brown ierr = VecSetSizes(vec1_V,pcbddc->n_vertices,pcbddc->n_vertices);CHKERRQ(ierr); 9920c7d97c5SJed Brown ierr = VecSetType(vec1_V,impVecType);CHKERRQ(ierr); 9930c7d97c5SJed Brown ierr = VecDuplicate(vec1_V,&vec2_V);CHKERRQ(ierr); 9940c7d97c5SJed Brown } 9950c7d97c5SJed Brown if(pcbddc->n_constraints) { 9960c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_C);CHKERRQ(ierr); 9970c7d97c5SJed Brown ierr = VecSetSizes(vec1_C,pcbddc->n_constraints,pcbddc->n_constraints);CHKERRQ(ierr); 9980c7d97c5SJed Brown ierr = VecSetType(vec1_C,impVecType);CHKERRQ(ierr); 9990c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&vec2_C);CHKERRQ(ierr); 10000c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&pcbddc->vec1_C);CHKERRQ(ierr); 10010c7d97c5SJed Brown } 10020c7d97c5SJed Brown /* Create C matrix [I 0; 0 const] */ 1003d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&CMAT);CHKERRQ(ierr); 10040c7d97c5SJed Brown ierr = MatSetType(CMAT,MATSEQAIJ);CHKERRQ(ierr); 10050c7d97c5SJed Brown ierr = MatSetSizes(CMAT,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 10060c7d97c5SJed Brown /* nonzeros */ 10070c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++) { nnz[i]= 1; } 10080c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++) { nnz[i+pcbddc->n_vertices]=pcbddc->sizes_of_constraint[i];} 10090c7d97c5SJed Brown ierr = MatSeqAIJSetPreallocation(CMAT,0,nnz);CHKERRQ(ierr); 10100c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++) { 10110c7d97c5SJed Brown ierr = MatSetValue(CMAT,i,pcbddc->vertices[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 10120c7d97c5SJed Brown } 10130c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++) { 101453cdbc3dSStefano Zampini index=i+pcbddc->n_vertices; 101553cdbc3dSStefano Zampini ierr = MatSetValues(CMAT,1,&index,pcbddc->sizes_of_constraint[i],pcbddc->indices_to_constraint[i],pcbddc->quadrature_constraint[i],INSERT_VALUES);CHKERRQ(ierr); 10160c7d97c5SJed Brown } 1017e269702eSStefano Zampini //if(dbg_flag) printf("CMAT assembling\n"); 10180c7d97c5SJed Brown ierr = MatAssemblyBegin(CMAT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10190c7d97c5SJed Brown ierr = MatAssemblyEnd(CMAT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10200c7d97c5SJed Brown //ierr = MatView(CMAT,PETSC_VIEWER_STDOUT_SELF); 10210c7d97c5SJed Brown 10220c7d97c5SJed Brown /* Precompute stuffs needed for preprocessing and application of BDDC*/ 10230c7d97c5SJed Brown 10240c7d97c5SJed Brown if(pcbddc->n_constraints) { 10250c7d97c5SJed Brown /* some work vectors */ 10260c7d97c5SJed Brown ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->local_auxmat2);CHKERRQ(ierr); 10270c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->local_auxmat2,n_R,pcbddc->n_constraints,n_R,pcbddc->n_constraints);CHKERRQ(ierr); 10280c7d97c5SJed Brown ierr = MatSetType(pcbddc->local_auxmat2,impMatType);CHKERRQ(ierr); 10290c7d97c5SJed Brown 10300c7d97c5SJed Brown /* Assemble local_auxmat2 = - A_{RR}^{-1} C^T_{CR} needed by BDDC application */ 10310c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++) { 1032d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 10330c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 10340c7d97c5SJed Brown for(j=0;j<pcbddc->sizes_of_constraint[i];j++) { array[ pcbddc->indices_to_constraint[i][j] ] = - pcbddc->quadrature_constraint[i][j]; } 10350c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 10360c7d97c5SJed Brown for(j=0;j<n_R;j++) { array2[j] = array[ idx_R_local[j] ]; } 10370c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 10380c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 103953cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 10400c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 104153cdbc3dSStefano Zampini index=i; 104253cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->local_auxmat2,n_R,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 10430c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 10440c7d97c5SJed Brown } 1045e269702eSStefano Zampini //if(dbg_flag) printf("pcbddc->local_auxmat2 assembling\n"); 10460c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10470c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10480c7d97c5SJed Brown 10490c7d97c5SJed Brown /* Create Constraint matrix on R nodes: C_{CR} */ 10500c7d97c5SJed Brown ierr = MatGetSubMatrix(CMAT,is_C_local,is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 10510c7d97c5SJed Brown ierr = ISDestroy(&is_C_local);CHKERRQ(ierr); 10520c7d97c5SJed Brown 10530c7d97c5SJed Brown /* Assemble AUXMAT = ( LUFactor )( -C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 10540c7d97c5SJed Brown ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AUXMAT);CHKERRQ(ierr); 1055d49ef151SStefano Zampini ierr = MatFactorInfoInitialize(&matinfo);CHKERRQ(ierr); 10560c7d97c5SJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->n_constraints,0,1,&is_aux1);CHKERRQ(ierr); 10570c7d97c5SJed Brown ierr = MatLUFactor(AUXMAT,is_aux1,is_aux1,&matinfo);CHKERRQ(ierr); 10580c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 10590c7d97c5SJed Brown 10600c7d97c5SJed Brown /* Assemble explicitly M1 = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} needed in preproc (should be dense) */ 1061d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M1);CHKERRQ(ierr); 10620c7d97c5SJed Brown ierr = MatSetSizes(M1,pcbddc->n_constraints,pcbddc->n_constraints,pcbddc->n_constraints,pcbddc->n_constraints);CHKERRQ(ierr); 10630c7d97c5SJed Brown ierr = MatSetType(M1,impMatType);CHKERRQ(ierr); 10640c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++) { 10650c7d97c5SJed Brown ierr = VecSet(vec1_C,zero);CHKERRQ(ierr); 10660c7d97c5SJed Brown ierr = VecSetValue(vec1_C,i,one,INSERT_VALUES);CHKERRQ(ierr); 10670c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_C);CHKERRQ(ierr); 10680c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_C);CHKERRQ(ierr); 10690c7d97c5SJed Brown ierr = MatSolve(AUXMAT,vec1_C,vec2_C);CHKERRQ(ierr); 10700c7d97c5SJed Brown ierr = VecScale(vec2_C,m_one);CHKERRQ(ierr); 10710c7d97c5SJed Brown ierr = VecGetArray(vec2_C,&array);CHKERRQ(ierr); 107253cdbc3dSStefano Zampini index=i; 107353cdbc3dSStefano Zampini ierr = MatSetValues(M1,pcbddc->n_constraints,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 10740c7d97c5SJed Brown ierr = VecRestoreArray(vec2_C,&array);CHKERRQ(ierr); 10750c7d97c5SJed Brown } 1076e269702eSStefano Zampini //if(dbg_flag) printf("M1 assembling\n"); 10770c7d97c5SJed Brown ierr = MatAssemblyBegin(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10780c7d97c5SJed Brown ierr = MatAssemblyEnd (M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10790c7d97c5SJed Brown ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 10800c7d97c5SJed Brown /* Assemble local_auxmat1 = M1*C_{CR} needed by BDDC application in KSP and in preproc */ 1081e269702eSStefano Zampini //if(dbg_flag) printf("pcbddc->local_auxmat1 computing and assembling\n"); 10820c7d97c5SJed Brown ierr = MatMatMult(M1,C_CR,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 10830c7d97c5SJed Brown 10840c7d97c5SJed Brown } 10850c7d97c5SJed Brown 10860c7d97c5SJed Brown /* Get submatrices from subdomain matrix */ 10870c7d97c5SJed Brown if(pcbddc->n_vertices){ 10880c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_R_local,is_V_local,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 10890c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_V_local,is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 10900c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_V_local,is_V_local,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 10910c7d97c5SJed Brown /* Assemble M2 = A_RR^{-1}A_RV */ 1092d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M2);CHKERRQ(ierr); 10930c7d97c5SJed Brown ierr = MatSetSizes(M2,n_R,pcbddc->n_vertices,n_R,pcbddc->n_vertices);CHKERRQ(ierr); 10940c7d97c5SJed Brown ierr = MatSetType(M2,impMatType);CHKERRQ(ierr); 10950c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++) { 10960c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 10970c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 10980c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 10990c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 11000c7d97c5SJed Brown ierr = MatMult(A_RV,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 110153cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 110253cdbc3dSStefano Zampini index=i; 11030c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 110453cdbc3dSStefano Zampini ierr = MatSetValues(M2,n_R,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 11050c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 11060c7d97c5SJed Brown } 1107e269702eSStefano Zampini //if(dbg_flag) printf("M2 assembling\n"); 11080c7d97c5SJed Brown ierr = MatAssemblyBegin(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11090c7d97c5SJed Brown ierr = MatAssemblyEnd (M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11100c7d97c5SJed Brown } 11110c7d97c5SJed Brown 11120c7d97c5SJed Brown /* Matrix of coarse basis functions (local) */ 1113d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 11140c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 11150c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_B,impMatType);CHKERRQ(ierr); 1116e269702eSStefano Zampini if(pcbddc->prec_type || dbg_flag ) { 1117d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 11180c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 11190c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_D,impMatType);CHKERRQ(ierr); 11200c7d97c5SJed Brown } 11210c7d97c5SJed Brown 11220c7d97c5SJed Brown /* Subdomain contribution (Non-overlapping) to coarse matrix */ 1123e269702eSStefano Zampini if(dbg_flag) { 11240c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&coarsefunctions_errors);CHKERRQ(ierr); 11250c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&constraints_errors);CHKERRQ(ierr); 11260c7d97c5SJed Brown } 11270c7d97c5SJed Brown ierr = PetscMalloc ((pcbddc->local_primal_size)*(pcbddc->local_primal_size)*sizeof(PetscScalar),&coarse_submat_vals);CHKERRQ(ierr); 11280c7d97c5SJed Brown 11290c7d97c5SJed Brown /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 11300c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++){ 11310c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 11320c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 11330c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 11340c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 11350c7d97c5SJed Brown /* solution of saddle point problem */ 11360c7d97c5SJed Brown ierr = MatMult(M2,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 11370c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_R,m_one);CHKERRQ(ierr); 11380c7d97c5SJed Brown if(pcbddc->n_constraints) { 11390c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec1_R,vec1_C);CHKERRQ(ierr); 11400c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 11410c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 11420c7d97c5SJed Brown } 11430c7d97c5SJed Brown ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); 11440c7d97c5SJed Brown ierr = MatMultAdd(A_VV,vec1_V,vec2_V,vec2_V);CHKERRQ(ierr); 11450c7d97c5SJed Brown 11460c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 11470c7d97c5SJed Brown /* coarse basis functions */ 114853cdbc3dSStefano Zampini index=i; 11490c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 11500c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11510c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11520c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 115353cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 11540c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 11550c7d97c5SJed Brown ierr = MatSetValue(pcbddc->coarse_phi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 1156e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 11570c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11580c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11590c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 116053cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 11610c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 11620c7d97c5SJed Brown } 11630c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 11640c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 11650c7d97c5SJed Brown for(j=0;j<pcbddc->n_vertices;j++) {coarse_submat_vals[i*pcbddc->local_primal_size+j]=array[j];} //WARNING -> column major ordering 11660c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 11670c7d97c5SJed Brown if( pcbddc->n_constraints) { 11680c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 11690c7d97c5SJed Brown for(j=0;j<pcbddc->n_constraints;j++) {coarse_submat_vals[i*pcbddc->local_primal_size+j+pcbddc->n_vertices]=array[j];} //WARNING -> column major ordering 11700c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 11710c7d97c5SJed Brown } 11720c7d97c5SJed Brown 1173e269702eSStefano Zampini if( dbg_flag ) { 11740c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 1175d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 11760c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 11770c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 11780c7d97c5SJed Brown for(j=0;j<n_R;j++) { array[idx_R_local[j]] = array2[j]; } 11790c7d97c5SJed Brown array[ pcbddc->vertices[i] ] = one; 11800c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 11810c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 11820c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers (i.e. primal nodes) */ 1183d49ef151SStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 11840c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 11850c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 11860c7d97c5SJed Brown for(j=0;j<pcbddc->n_vertices;j++) { array2[j]=array[j]; } 11870c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 11880c7d97c5SJed Brown if(pcbddc->n_constraints) { 11890c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 11900c7d97c5SJed Brown for(j=0;j<pcbddc->n_constraints;j++) { array2[j+pcbddc->n_vertices]=array[j]; } 11910c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 11920c7d97c5SJed Brown } 11930c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 11940c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_P,m_one);CHKERRQ(ierr); 11950c7d97c5SJed Brown /* check saddle point solution */ 11960c7d97c5SJed Brown ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 119753cdbc3dSStefano Zampini ierr = MatMultTransposeAdd(CMAT,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 119853cdbc3dSStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[index]);CHKERRQ(ierr); 11990c7d97c5SJed Brown ierr = MatMult(CMAT,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 12000c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 120153cdbc3dSStefano Zampini array[index]=array[index]+m_one; /* shift by the identity matrix */ 12020c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 120353cdbc3dSStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[index]);CHKERRQ(ierr); 12040c7d97c5SJed Brown } 12050c7d97c5SJed Brown } 12060c7d97c5SJed Brown 12070c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++){ 1208d49ef151SStefano Zampini ierr = VecSet(vec2_C,zero);CHKERRQ(ierr); 12090c7d97c5SJed Brown ierr = VecSetValue(vec2_C,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 12100c7d97c5SJed Brown ierr = VecAssemblyBegin(vec2_C);CHKERRQ(ierr); 12110c7d97c5SJed Brown ierr = VecAssemblyEnd(vec2_C);CHKERRQ(ierr); 12120c7d97c5SJed Brown /* solution of saddle point problem */ 12130c7d97c5SJed Brown ierr = MatMult(M1,vec2_C,vec1_C);CHKERRQ(ierr); 12140c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 12150c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 12160c7d97c5SJed Brown if(pcbddc->n_vertices) { ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); } 12170c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 12180c7d97c5SJed Brown /* coarse basis functions */ 121953cdbc3dSStefano Zampini index=i+pcbddc->n_vertices; 12200c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 12210c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12220c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12230c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 122453cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 12250c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1226e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 12270c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12280c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12290c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 123053cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 12310c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 12320c7d97c5SJed Brown } 12330c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 12340c7d97c5SJed Brown if(pcbddc->n_vertices) { 12350c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 123653cdbc3dSStefano Zampini for(j=0;j<pcbddc->n_vertices;j++) {coarse_submat_vals[index*pcbddc->local_primal_size+j]=array[j];} //WARNING -> column major ordering 12370c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 12380c7d97c5SJed Brown } 12390c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 124053cdbc3dSStefano Zampini for(j=0;j<pcbddc->n_constraints;j++) {coarse_submat_vals[index*pcbddc->local_primal_size+j+pcbddc->n_vertices]=array[j];} //WARNING -> column major ordering 12410c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 12420c7d97c5SJed Brown 1243e269702eSStefano Zampini if( dbg_flag ) { 12440c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 124553cdbc3dSStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 12460c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 12470c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 12480c7d97c5SJed Brown for(j=0;j<n_R;j++){ array[ idx_R_local[j] ] = array2[j]; } 12490c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 12500c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 12510c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers */ 125253cdbc3dSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 12530c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 12540c7d97c5SJed Brown if( pcbddc->n_vertices) { 12550c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 12560c7d97c5SJed Brown for(j=0;j<pcbddc->n_vertices;j++) {array2[j]=-array[j];} 12570c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 12580c7d97c5SJed Brown } 12590c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 12600c7d97c5SJed Brown for(j=0;j<pcbddc->n_constraints;j++) {array2[j+pcbddc->n_vertices]=-array[j];} 12610c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 12620c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 12630c7d97c5SJed Brown /* check saddle point solution */ 12640c7d97c5SJed Brown ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 1265d49ef151SStefano Zampini ierr = MatMultTransposeAdd(CMAT,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 126653cdbc3dSStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[index]);CHKERRQ(ierr); 12670c7d97c5SJed Brown ierr = MatMult(CMAT,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 12680c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 126953cdbc3dSStefano Zampini array[index]=array[index]+m_one; /* shift by the identity matrix */ 12700c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 127153cdbc3dSStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[index]);CHKERRQ(ierr); 12720c7d97c5SJed Brown } 12730c7d97c5SJed Brown } 12740c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12750c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1276e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 12770c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12780c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12790c7d97c5SJed Brown } 12800c7d97c5SJed Brown /* Checking coarse_sub_mat and coarse basis functios */ 12810c7d97c5SJed Brown /* It shuld be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 1282*9d2fce94SStefano Zampini if(dbg_flag) { 12830c7d97c5SJed Brown 12840c7d97c5SJed Brown Mat coarse_sub_mat; 12850c7d97c5SJed Brown Mat TM1,TM2,TM3,TM4; 12860c7d97c5SJed Brown Mat coarse_phi_D,coarse_phi_B,A_II,A_BB,A_IB,A_BI; 1287a0ba757dSStefano Zampini const MatType checkmattype=MATSEQAIJ; 12880c7d97c5SJed Brown PetscScalar value; 12890c7d97c5SJed Brown 1290c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 1291c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 1292c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 1293c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 1294c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 1295c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 1296c042a7c3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 1297c042a7c3SStefano Zampini ierr = MatConvert(coarse_sub_mat,checkmattype,MAT_REUSE_MATRIX,&coarse_sub_mat);CHKERRQ(ierr); 12980c7d97c5SJed Brown 12990c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 13000c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Check coarse sub mat and local basis functions\n");CHKERRQ(ierr); 13010c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 130253cdbc3dSStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 130353cdbc3dSStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 130453cdbc3dSStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1305c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 130653cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 130753cdbc3dSStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1308c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 130953cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 131053cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 131153cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 131253cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 131353cdbc3dSStefano Zampini ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 131453cdbc3dSStefano Zampini ierr = MatNorm(TM1,NORM_INFINITY,&value);CHKERRQ(ierr); 13150c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"----------------------------------\n");CHKERRQ(ierr); 13160c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d \n",PetscGlobalRank);CHKERRQ(ierr); 13170c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"matrix error = % 1.14e\n",value);CHKERRQ(ierr); 13180c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"coarse functions errors\n");CHKERRQ(ierr); 131953cdbc3dSStefano 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); } 13200c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"constraints errors\n");CHKERRQ(ierr); 132153cdbc3dSStefano 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); } 13220c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 132353cdbc3dSStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 132453cdbc3dSStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 132553cdbc3dSStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 132653cdbc3dSStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 132753cdbc3dSStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 132853cdbc3dSStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 132953cdbc3dSStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 133053cdbc3dSStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 133153cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 133253cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 133353cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 13340c7d97c5SJed Brown ierr = PetscFree(coarsefunctions_errors);CHKERRQ(ierr); 13350c7d97c5SJed Brown ierr = PetscFree(constraints_errors);CHKERRQ(ierr); 13360c7d97c5SJed Brown } 13370c7d97c5SJed Brown 13380c7d97c5SJed Brown /* create coarse matrix and data structures for message passing associated actual choice of coarse problem type */ 13390c7d97c5SJed Brown ierr = PCBDDCSetupCoarseEnvironment(pc,coarse_submat_vals);CHKERRQ(ierr); 13400c7d97c5SJed Brown /* free memory */ 13410c7d97c5SJed Brown ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 13420c7d97c5SJed Brown ierr = PetscFree(auxindices);CHKERRQ(ierr); 13430c7d97c5SJed Brown ierr = PetscFree(nnz);CHKERRQ(ierr); 13440c7d97c5SJed Brown if(pcbddc->n_vertices) { 13450c7d97c5SJed Brown ierr = VecDestroy(&vec1_V);CHKERRQ(ierr); 13460c7d97c5SJed Brown ierr = VecDestroy(&vec2_V);CHKERRQ(ierr); 13470c7d97c5SJed Brown ierr = MatDestroy(&M2);CHKERRQ(ierr); 13480c7d97c5SJed Brown ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 13490c7d97c5SJed Brown ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 13500c7d97c5SJed Brown ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 13510c7d97c5SJed Brown } 13520c7d97c5SJed Brown if(pcbddc->n_constraints) { 13530c7d97c5SJed Brown ierr = VecDestroy(&vec1_C);CHKERRQ(ierr); 13540c7d97c5SJed Brown ierr = VecDestroy(&vec2_C);CHKERRQ(ierr); 13550c7d97c5SJed Brown ierr = MatDestroy(&M1);CHKERRQ(ierr); 13560c7d97c5SJed Brown ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 13570c7d97c5SJed Brown } 13580c7d97c5SJed Brown ierr = MatDestroy(&CMAT);CHKERRQ(ierr); 13590c7d97c5SJed Brown } 13600c7d97c5SJed Brown /* free memory */ 13610c7d97c5SJed Brown if(pcbddc->n_vertices) { 13620c7d97c5SJed Brown ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 13630c7d97c5SJed Brown ierr = ISDestroy(&is_V_local);CHKERRQ(ierr); 13640c7d97c5SJed Brown } 13650c7d97c5SJed Brown ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 13660c7d97c5SJed Brown ierr = ISDestroy(&is_R_local);CHKERRQ(ierr); 13670c7d97c5SJed Brown 13680c7d97c5SJed Brown PetscFunctionReturn(0); 13690c7d97c5SJed Brown } 13700c7d97c5SJed Brown 13710c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 13720c7d97c5SJed Brown 13730c7d97c5SJed Brown #undef __FUNCT__ 13740c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetupCoarseEnvironment" 137553cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetupCoarseEnvironment(PC pc,PetscScalar* coarse_submat_vals) 13760c7d97c5SJed Brown { 13770c7d97c5SJed Brown 13780c7d97c5SJed Brown 13790c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 13800c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 13810c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 13820c7d97c5SJed Brown MPI_Comm prec_comm = ((PetscObject)pc)->comm; 13830c7d97c5SJed Brown MPI_Comm coarse_comm; 13840c7d97c5SJed Brown 13850c7d97c5SJed Brown /* common to all choiches */ 13860c7d97c5SJed Brown PetscScalar *temp_coarse_mat_vals; 13870c7d97c5SJed Brown PetscScalar *ins_coarse_mat_vals; 13880c7d97c5SJed Brown PetscInt *ins_local_primal_indices; 13890c7d97c5SJed Brown PetscMPIInt *localsizes2,*localdispl2; 13900c7d97c5SJed Brown PetscMPIInt size_prec_comm; 13910c7d97c5SJed Brown PetscMPIInt rank_prec_comm; 13920c7d97c5SJed Brown PetscMPIInt active_rank=MPI_PROC_NULL; 13930c7d97c5SJed Brown PetscMPIInt master_proc=0; 13940c7d97c5SJed Brown PetscInt ins_local_primal_size; 13950c7d97c5SJed Brown /* specific to MULTILEVEL_BDDC */ 13960c7d97c5SJed Brown PetscMPIInt *ranks_recv; 13970c7d97c5SJed Brown PetscMPIInt count_recv=0; 13980c7d97c5SJed Brown PetscMPIInt rank_coarse_proc_send_to; 13990c7d97c5SJed Brown PetscMPIInt coarse_color = MPI_UNDEFINED; 14000c7d97c5SJed Brown ISLocalToGlobalMapping coarse_ISLG; 14010c7d97c5SJed Brown /* some other variables */ 14020c7d97c5SJed Brown PetscErrorCode ierr; 14030c7d97c5SJed Brown const MatType coarse_mat_type; 14040c7d97c5SJed Brown const PCType coarse_pc_type; 140553cdbc3dSStefano Zampini const KSPType coarse_ksp_type; 140653cdbc3dSStefano Zampini PC pc_temp; 14070c7d97c5SJed Brown PetscInt i,j,k,bs; 1408e269702eSStefano Zampini /* verbose output viewer */ 1409e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 1410e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 14110c7d97c5SJed Brown 14120c7d97c5SJed Brown PetscFunctionBegin; 14130c7d97c5SJed Brown 14140c7d97c5SJed Brown ins_local_primal_indices = 0; 14150c7d97c5SJed Brown ins_coarse_mat_vals = 0; 14160c7d97c5SJed Brown localsizes2 = 0; 14170c7d97c5SJed Brown localdispl2 = 0; 14180c7d97c5SJed Brown temp_coarse_mat_vals = 0; 14190c7d97c5SJed Brown coarse_ISLG = 0; 14200c7d97c5SJed Brown 142153cdbc3dSStefano Zampini ierr = MPI_Comm_size(prec_comm,&size_prec_comm);CHKERRQ(ierr); 142253cdbc3dSStefano Zampini ierr = MPI_Comm_rank(prec_comm,&rank_prec_comm);CHKERRQ(ierr); 14230c7d97c5SJed Brown ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 14240c7d97c5SJed Brown 1425beed3852SStefano Zampini /* Assign global numbering to coarse dofs */ 1426beed3852SStefano Zampini { 1427a0ba757dSStefano Zampini PetscScalar one=1.,zero=0.; 1428beed3852SStefano Zampini PetscScalar *array; 1429beed3852SStefano Zampini PetscMPIInt *auxlocal_primal; 1430beed3852SStefano Zampini PetscMPIInt *auxglobal_primal; 1431beed3852SStefano Zampini PetscMPIInt *all_auxglobal_primal; 1432beed3852SStefano Zampini PetscMPIInt *all_auxglobal_primal_dummy; 1433beed3852SStefano Zampini PetscMPIInt mpi_local_primal_size = (PetscMPIInt)pcbddc->local_primal_size; 1434beed3852SStefano Zampini 1435beed3852SStefano Zampini /* Construct needed data structures for message passing */ 1436beed3852SStefano Zampini ierr = PetscMalloc(mpi_local_primal_size*sizeof(PetscMPIInt),&pcbddc->local_primal_indices);CHKERRQ(ierr); 1437beed3852SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&pcbddc->local_primal_sizes);CHKERRQ(ierr); 1438beed3852SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 1439beed3852SStefano Zampini /* Gather local_primal_size information for all processes */ 14405619798eSStefano Zampini ierr = MPI_Allgather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,prec_comm);CHKERRQ(ierr); 1441beed3852SStefano Zampini pcbddc->replicated_primal_size = 0; 1442beed3852SStefano Zampini for (i=0; i<size_prec_comm; i++) { 1443beed3852SStefano Zampini pcbddc->local_primal_displacements[i] = pcbddc->replicated_primal_size ; 1444beed3852SStefano Zampini pcbddc->replicated_primal_size += pcbddc->local_primal_sizes[i]; 1445beed3852SStefano Zampini } 14465619798eSStefano Zampini if(rank_prec_comm == 0) { 1447beed3852SStefano Zampini /* allocate some auxiliary space */ 1448beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->replicated_primal_size*sizeof(*all_auxglobal_primal),&all_auxglobal_primal);CHKERRQ(ierr); 1449beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->replicated_primal_size*sizeof(*all_auxglobal_primal_dummy),&all_auxglobal_primal_dummy);CHKERRQ(ierr); 1450beed3852SStefano Zampini } 1451beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscMPIInt),&auxlocal_primal);CHKERRQ(ierr); 1452beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscMPIInt),&auxglobal_primal);CHKERRQ(ierr); 1453beed3852SStefano Zampini 1454beed3852SStefano 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) 1455beed3852SStefano Zampini This code fragment assumes that the number of local constraints per connected component 1456beed3852SStefano Zampini is not greater than the number of nodes defined for the connected component 1457beed3852SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 1458beed3852SStefano Zampini /* auxlocal_primal : primal indices in local nodes numbering (internal and interface) */ 1459beed3852SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 1460beed3852SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1461beed3852SStefano Zampini for(i=0;i<pcbddc->n_vertices;i++) { 1462beed3852SStefano Zampini array[ pcbddc->vertices[i] ] = one; 1463beed3852SStefano Zampini auxlocal_primal[i] = pcbddc->vertices[i]; 1464beed3852SStefano Zampini } 1465beed3852SStefano Zampini for(i=0;i<pcbddc->n_constraints;i++) { 1466beed3852SStefano Zampini for (j=0; j<pcbddc->sizes_of_constraint[i]; j++) { 1467beed3852SStefano Zampini k = pcbddc->indices_to_constraint[i][j]; 1468beed3852SStefano Zampini if( array[k] == zero ) { 1469beed3852SStefano Zampini array[k] = one; 1470beed3852SStefano Zampini auxlocal_primal[i+pcbddc->n_vertices] = k; 1471beed3852SStefano Zampini break; 1472beed3852SStefano Zampini } 1473beed3852SStefano Zampini } 1474beed3852SStefano Zampini } 1475beed3852SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1476a0ba757dSStefano Zampini 1477a0ba757dSStefano Zampini /*ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 1478beed3852SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1479beed3852SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1480beed3852SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1481beed3852SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1482beed3852SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1483d49ef151SStefano Zampini for(i=0;i<pcis->n;i++) { if(array[i] > 0.0) array[i] = one/array[i]; } 1484beed3852SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1485beed3852SStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 1486beed3852SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1487beed3852SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1488beed3852SStefano Zampini 1489beed3852SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 1490beed3852SStefano Zampini pcbddc->coarse_size = (PetscInt) coarsesum; 1491e269702eSStefano Zampini if(dbg_flag) { 1492e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 14933828260eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem = %d (%f)\n",pcbddc->coarse_size,coarsesum);CHKERRQ(ierr); 1494e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1495a0ba757dSStefano Zampini }*/ 1496a0ba757dSStefano Zampini 1497beed3852SStefano Zampini /* Now assign them a global numbering */ 1498beed3852SStefano Zampini /* auxglobal_primal contains indices in global nodes numbering (internal and interface) */ 1499beed3852SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,pcbddc->local_primal_size,auxlocal_primal,auxglobal_primal);CHKERRQ(ierr); 1500beed3852SStefano Zampini /* all_auxglobal_primal contains all primal nodes indices in global nodes numbering (internal and interface) */ 1501beed3852SStefano 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); 1502beed3852SStefano Zampini 1503beed3852SStefano Zampini /* After this block all_auxglobal_primal should contains one copy of each primal node's indices in global nodes numbering */ 1504beed3852SStefano Zampini /* It implements a function similar to PetscSortRemoveDupsInt */ 1505beed3852SStefano Zampini if(rank_prec_comm==0) { 1506beed3852SStefano Zampini /* dummy argument since PetscSortMPIInt doesn't exist! */ 1507beed3852SStefano Zampini ierr = PetscSortMPIIntWithArray(pcbddc->replicated_primal_size,all_auxglobal_primal,all_auxglobal_primal_dummy);CHKERRQ(ierr); 1508beed3852SStefano Zampini k=1; 1509beed3852SStefano Zampini j=all_auxglobal_primal[0]; /* first dof in global numbering */ 1510beed3852SStefano Zampini for(i=1;i< pcbddc->replicated_primal_size ;i++) { 1511beed3852SStefano Zampini if(j != all_auxglobal_primal[i] ) { 1512beed3852SStefano Zampini all_auxglobal_primal[k]=all_auxglobal_primal[i]; 1513beed3852SStefano Zampini k++; 1514beed3852SStefano Zampini j=all_auxglobal_primal[i]; 1515beed3852SStefano Zampini } 1516beed3852SStefano Zampini } 1517beed3852SStefano Zampini } else { 1518beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscMPIInt),&all_auxglobal_primal);CHKERRQ(ierr); 1519beed3852SStefano Zampini } 15205619798eSStefano Zampini /* We only need to broadcast the indices from 0 to pcbddc->coarse_size. Remaning elements of array all_aux_global_primal are garbage. */ 1521beed3852SStefano Zampini ierr = MPI_Bcast(all_auxglobal_primal,pcbddc->coarse_size,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 1522beed3852SStefano Zampini 1523beed3852SStefano Zampini /* Now get global coarse numbering of local primal nodes */ 1524beed3852SStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) { 1525beed3852SStefano Zampini k=0; 1526beed3852SStefano Zampini while( all_auxglobal_primal[k] != auxglobal_primal[i] ) { k++;} 1527beed3852SStefano Zampini pcbddc->local_primal_indices[i]=k; 1528beed3852SStefano Zampini } 1529e269702eSStefano Zampini if(dbg_flag) { 1530e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1531e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 1532e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1533e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 1534e269702eSStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) { 1535e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_primal_indices[%d]=%d \n",i,pcbddc->local_primal_indices[i]); 1536e269702eSStefano Zampini } 1537e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1538e269702eSStefano Zampini } 1539beed3852SStefano Zampini /* free allocated memory */ 1540beed3852SStefano Zampini ierr = PetscFree(auxlocal_primal);CHKERRQ(ierr); 1541beed3852SStefano Zampini ierr = PetscFree(auxglobal_primal);CHKERRQ(ierr); 1542beed3852SStefano Zampini ierr = PetscFree(all_auxglobal_primal);CHKERRQ(ierr); 1543e269702eSStefano Zampini if(rank_prec_comm == 0) { 1544beed3852SStefano Zampini ierr = PetscFree(all_auxglobal_primal_dummy);CHKERRQ(ierr); 1545beed3852SStefano Zampini } 1546e269702eSStefano Zampini } 1547beed3852SStefano Zampini 15480c7d97c5SJed Brown /* adapt coarse problem type */ 15490c7d97c5SJed Brown if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC && pcbddc->active_procs < MIN_PROCS_FOR_BDDC ) 15500c7d97c5SJed Brown pcbddc->coarse_problem_type = PARALLEL_BDDC; 15510c7d97c5SJed Brown 15520c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 15530c7d97c5SJed Brown 15540c7d97c5SJed Brown case(MULTILEVEL_BDDC): //we define a coarse mesh where subdomains are elements 15550c7d97c5SJed Brown { 15560c7d97c5SJed Brown /* we need additional variables */ 15570c7d97c5SJed Brown MetisInt n_subdomains,n_parts,objval,ncon,faces_nvtxs; 15580c7d97c5SJed Brown MetisInt *metis_coarse_subdivision; 15590c7d97c5SJed Brown MetisInt options[METIS_NOPTIONS]; 15600c7d97c5SJed Brown PetscMPIInt size_coarse_comm,rank_coarse_comm; 15610c7d97c5SJed Brown PetscMPIInt procs_jumps_coarse_comm; 15620c7d97c5SJed Brown PetscMPIInt *coarse_subdivision; 15630c7d97c5SJed Brown PetscMPIInt *total_count_recv; 15640c7d97c5SJed Brown PetscMPIInt *total_ranks_recv; 15650c7d97c5SJed Brown PetscMPIInt *displacements_recv; 15660c7d97c5SJed Brown PetscMPIInt *my_faces_connectivity; 15670c7d97c5SJed Brown PetscMPIInt *petsc_faces_adjncy; 15680c7d97c5SJed Brown MetisInt *faces_adjncy; 15690c7d97c5SJed Brown MetisInt *faces_xadj; 15700c7d97c5SJed Brown PetscMPIInt *number_of_faces; 15710c7d97c5SJed Brown PetscMPIInt *faces_displacements; 15720c7d97c5SJed Brown PetscInt *array_int; 15730c7d97c5SJed Brown PetscMPIInt my_faces=0; 15740c7d97c5SJed Brown PetscMPIInt total_faces=0; 15753828260eSStefano Zampini PetscInt ranks_stretching_ratio; 15760c7d97c5SJed Brown 15770c7d97c5SJed Brown /* define some quantities */ 15780c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 15790c7d97c5SJed Brown coarse_mat_type = MATIS; 15800c7d97c5SJed Brown coarse_pc_type = PCBDDC; 158153cdbc3dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 15820c7d97c5SJed Brown 15830c7d97c5SJed Brown /* details of coarse decomposition */ 15840c7d97c5SJed Brown n_subdomains = pcbddc->active_procs; 15850c7d97c5SJed Brown n_parts = n_subdomains/pcbddc->coarsening_ratio; 15863828260eSStefano Zampini ranks_stretching_ratio = size_prec_comm/pcbddc->active_procs; 15873828260eSStefano Zampini procs_jumps_coarse_comm = pcbddc->coarsening_ratio*ranks_stretching_ratio; 15883828260eSStefano Zampini 15893828260eSStefano Zampini printf("Coarse algorithm details: \n"); 1590a0ba757dSStefano 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)); 15910c7d97c5SJed Brown 15920c7d97c5SJed Brown /* build CSR graph of subdomains' connectivity through faces */ 15930c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&array_int);CHKERRQ(ierr); 15943828260eSStefano Zampini ierr = PetscMemzero(array_int,pcis->n*sizeof(PetscInt));CHKERRQ(ierr); 15950c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){/* i=1 so I don't count myself -> faces nodes counts to 1 */ 15960c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 15970c7d97c5SJed Brown array_int[ pcis->shared[i][j] ]+=1; 15980c7d97c5SJed Brown } 15990c7d97c5SJed Brown } 16000c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){ 16010c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 16020c7d97c5SJed Brown if(array_int[ pcis->shared[i][j] ] == 1 ){ 16030c7d97c5SJed Brown my_faces++; 16040c7d97c5SJed Brown break; 16050c7d97c5SJed Brown } 16060c7d97c5SJed Brown } 16070c7d97c5SJed Brown } 16080c7d97c5SJed Brown //printf("I found %d faces.\n",my_faces); 16090c7d97c5SJed Brown 161053cdbc3dSStefano Zampini ierr = MPI_Reduce(&my_faces,&total_faces,1,MPIU_INT,MPI_SUM,master_proc,prec_comm);CHKERRQ(ierr); 16110c7d97c5SJed Brown ierr = PetscMalloc (my_faces*sizeof(PetscInt),&my_faces_connectivity);CHKERRQ(ierr); 16120c7d97c5SJed Brown my_faces=0; 16130c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){ 16140c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 16150c7d97c5SJed Brown if(array_int[ pcis->shared[i][j] ] == 1 ){ 16160c7d97c5SJed Brown my_faces_connectivity[my_faces]=pcis->neigh[i]; 16170c7d97c5SJed Brown my_faces++; 16180c7d97c5SJed Brown break; 16190c7d97c5SJed Brown } 16200c7d97c5SJed Brown } 16210c7d97c5SJed Brown } 16220c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 16230c7d97c5SJed Brown //printf("I found %d total faces.\n",total_faces); 16240c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(PetscMPIInt),&petsc_faces_adjncy);CHKERRQ(ierr); 16250c7d97c5SJed Brown ierr = PetscMalloc (size_prec_comm*sizeof(PetscMPIInt),&number_of_faces);CHKERRQ(ierr); 16260c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(MetisInt),&faces_adjncy);CHKERRQ(ierr); 16270c7d97c5SJed Brown ierr = PetscMalloc ((n_subdomains+1)*sizeof(MetisInt),&faces_xadj);CHKERRQ(ierr); 16280c7d97c5SJed Brown ierr = PetscMalloc ((size_prec_comm+1)*sizeof(PetscMPIInt),&faces_displacements);CHKERRQ(ierr); 16290c7d97c5SJed Brown } 163053cdbc3dSStefano Zampini ierr = MPI_Gather(&my_faces,1,MPIU_INT,&number_of_faces[0],1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 16310c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 16320c7d97c5SJed Brown faces_xadj[0]=0; 16330c7d97c5SJed Brown faces_displacements[0]=0; 16340c7d97c5SJed Brown j=0; 16350c7d97c5SJed Brown for(i=1;i<size_prec_comm+1;i++) { 16360c7d97c5SJed Brown faces_displacements[i]=faces_displacements[i-1]+number_of_faces[i-1]; 16370c7d97c5SJed Brown if(number_of_faces[i-1]) { 16380c7d97c5SJed Brown j++; 16390c7d97c5SJed Brown faces_xadj[j]=faces_xadj[j-1]+number_of_faces[i-1]; 16400c7d97c5SJed Brown } 16410c7d97c5SJed Brown } 16420c7d97c5SJed Brown printf("The J I count is %d and should be %d\n",j,n_subdomains); 16430c7d97c5SJed Brown printf("Total faces seem %d and should be %d\n",faces_xadj[j],total_faces); 16440c7d97c5SJed Brown } 164553cdbc3dSStefano 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); 16460c7d97c5SJed Brown ierr = PetscFree(my_faces_connectivity);CHKERRQ(ierr); 16470c7d97c5SJed Brown ierr = PetscFree(array_int);CHKERRQ(ierr); 16480c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 16493828260eSStefano Zampini for(i=0;i<total_faces;i++) faces_adjncy[i]=(MetisInt)(petsc_faces_adjncy[i]/ranks_stretching_ratio); /* cast to MetisInt */ 16503828260eSStefano Zampini printf("This is the face connectivity (actual ranks)\n"); 16510c7d97c5SJed Brown for(i=0;i<n_subdomains;i++){ 16520c7d97c5SJed Brown printf("proc %d is connected with \n",i); 16530c7d97c5SJed Brown for(j=faces_xadj[i];j<faces_xadj[i+1];j++) 16540c7d97c5SJed Brown printf("%d ",faces_adjncy[j]); 16550c7d97c5SJed Brown printf("\n"); 16560c7d97c5SJed Brown } 16570c7d97c5SJed Brown ierr = PetscFree(faces_displacements);CHKERRQ(ierr); 16580c7d97c5SJed Brown ierr = PetscFree(number_of_faces);CHKERRQ(ierr); 16590c7d97c5SJed Brown ierr = PetscFree(petsc_faces_adjncy);CHKERRQ(ierr); 16600c7d97c5SJed Brown } 16610c7d97c5SJed Brown 16620c7d97c5SJed Brown if( rank_prec_comm == master_proc ) { 16630c7d97c5SJed Brown 16643828260eSStefano Zampini PetscInt heuristic_for_metis=3; 16653828260eSStefano Zampini 16660c7d97c5SJed Brown ncon=1; 16670c7d97c5SJed Brown faces_nvtxs=n_subdomains; 16680c7d97c5SJed Brown /* partition graoh induced by face connectivity */ 16690c7d97c5SJed Brown ierr = PetscMalloc (n_subdomains*sizeof(MetisInt),&metis_coarse_subdivision);CHKERRQ(ierr); 16700c7d97c5SJed Brown ierr = METIS_SetDefaultOptions(options); 16710c7d97c5SJed Brown /* we need a contiguous partition of the coarse mesh */ 16720c7d97c5SJed Brown options[METIS_OPTION_CONTIG]=1; 16730c7d97c5SJed Brown options[METIS_OPTION_DBGLVL]=1; 16740c7d97c5SJed Brown options[METIS_OPTION_NITER]=30; 16750c7d97c5SJed Brown //options[METIS_OPTION_NCUTS]=1; 16763828260eSStefano Zampini printf("METIS PART GRAPH\n"); 16773828260eSStefano Zampini if(n_subdomains>n_parts*heuristic_for_metis) { 16783828260eSStefano Zampini printf("Using Kway\n"); 16793828260eSStefano Zampini options[METIS_OPTION_IPTYPE]=METIS_IPTYPE_EDGE; 16803828260eSStefano Zampini options[METIS_OPTION_OBJTYPE]=METIS_OBJTYPE_CUT; 16810c7d97c5SJed Brown ierr = METIS_PartGraphKway(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 16823828260eSStefano Zampini } else { 16833828260eSStefano Zampini printf("Using Recursive\n"); 16843828260eSStefano Zampini ierr = METIS_PartGraphRecursive(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 16853828260eSStefano Zampini } 16860c7d97c5SJed 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); 16873828260eSStefano Zampini printf("Partition done!\n"); 16880c7d97c5SJed Brown ierr = PetscFree(faces_xadj);CHKERRQ(ierr); 16890c7d97c5SJed Brown ierr = PetscFree(faces_adjncy);CHKERRQ(ierr); 16900c7d97c5SJed Brown coarse_subdivision = (PetscMPIInt*)calloc(size_prec_comm,sizeof(PetscMPIInt)); /* calloc for contiguous memory since we need to scatter these values later */ 16910c7d97c5SJed Brown /* copy/cast values avoiding possible type conflicts between PETSc, MPI and METIS */ 16923828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) coarse_subdivision[i]=MPI_PROC_NULL; 16933828260eSStefano Zampini for(i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=(PetscInt)(metis_coarse_subdivision[i]); 16940c7d97c5SJed Brown ierr = PetscFree(metis_coarse_subdivision);CHKERRQ(ierr); 16950c7d97c5SJed Brown } 16960c7d97c5SJed Brown 16970c7d97c5SJed Brown /* Create new communicator for coarse problem splitting the old one */ 16980c7d97c5SJed Brown if( !(rank_prec_comm%procs_jumps_coarse_comm) && rank_prec_comm < procs_jumps_coarse_comm*n_parts ){ 16990c7d97c5SJed Brown coarse_color=0; //for communicator splitting 17000c7d97c5SJed Brown active_rank=rank_prec_comm; //for insertion of matrix values 17010c7d97c5SJed Brown } 17020c7d97c5SJed Brown // procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 17030c7d97c5SJed Brown // key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator 170453cdbc3dSStefano Zampini ierr = MPI_Comm_split(prec_comm,coarse_color,rank_prec_comm,&coarse_comm);CHKERRQ(ierr); 17050c7d97c5SJed Brown 17060c7d97c5SJed Brown if( coarse_color == 0 ) { 170753cdbc3dSStefano Zampini ierr = MPI_Comm_size(coarse_comm,&size_coarse_comm);CHKERRQ(ierr); 170853cdbc3dSStefano Zampini ierr = MPI_Comm_rank(coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 17093828260eSStefano Zampini printf("Details of coarse comm\n"); 17103828260eSStefano Zampini printf("size = %d, myrank = %d\n",size_coarse_comm,rank_coarse_comm); 17113828260eSStefano Zampini printf("jumps = %d, coarse_color = %d, n_parts = %d\n",procs_jumps_coarse_comm,coarse_color,n_parts); 17120c7d97c5SJed Brown } else { 17130c7d97c5SJed Brown rank_coarse_comm = MPI_PROC_NULL; 17140c7d97c5SJed Brown } 17150c7d97c5SJed Brown 17160c7d97c5SJed Brown /* master proc take care of arranging and distributing coarse informations */ 17170c7d97c5SJed Brown if(rank_coarse_comm == master_proc) { 17180c7d97c5SJed Brown ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&displacements_recv);CHKERRQ(ierr); 17190c7d97c5SJed Brown //ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&total_count_recv);CHKERRQ(ierr); 17200c7d97c5SJed Brown //ierr = PetscMalloc (n_subdomains*sizeof(PetscMPIInt),&total_ranks_recv);CHKERRQ(ierr); 17210c7d97c5SJed Brown total_count_recv = (PetscMPIInt*)calloc(size_prec_comm,sizeof(PetscMPIInt)); 17220c7d97c5SJed Brown total_ranks_recv = (PetscMPIInt*)calloc(n_subdomains,sizeof(PetscMPIInt)); 17230c7d97c5SJed Brown /* some initializations */ 17240c7d97c5SJed Brown displacements_recv[0]=0; 17250c7d97c5SJed Brown //PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt)); not needed -> calloc initializes to zero 17260c7d97c5SJed Brown /* count from how many processes the j-th process of the coarse decomposition will receive data */ 17270c7d97c5SJed Brown for(j=0;j<size_coarse_comm;j++) 17283828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) 17290c7d97c5SJed Brown if(coarse_subdivision[i]==j) 17300c7d97c5SJed Brown total_count_recv[j]++; 17310c7d97c5SJed Brown /* displacements needed for scatterv of total_ranks_recv */ 17320c7d97c5SJed Brown for(i=1;i<size_coarse_comm;i++) displacements_recv[i]=displacements_recv[i-1]+total_count_recv[i-1]; 17330c7d97c5SJed Brown /* Now fill properly total_ranks_recv -> each coarse process will receive the ranks (in prec_comm communicator) of its friend (sending) processes */ 17340c7d97c5SJed Brown ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 17350c7d97c5SJed Brown for(j=0;j<size_coarse_comm;j++) { 17363828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) { 17370c7d97c5SJed Brown if(coarse_subdivision[i]==j) { 17380c7d97c5SJed Brown total_ranks_recv[displacements_recv[j]+total_count_recv[j]]=i; 17393828260eSStefano Zampini total_count_recv[j]+=1; 17400c7d97c5SJed Brown } 17410c7d97c5SJed Brown } 17420c7d97c5SJed Brown } 17433828260eSStefano Zampini for(j=0;j<size_coarse_comm;j++) { 17443828260eSStefano Zampini printf("process %d in new rank will receive from %d processes (original ranks follows)\n",j,total_count_recv[j]); 17453828260eSStefano Zampini for(i=0;i<total_count_recv[j];i++) { 17463828260eSStefano Zampini printf("%d ",total_ranks_recv[displacements_recv[j]+i]); 17473828260eSStefano Zampini } 17483828260eSStefano Zampini printf("\n"); 17493828260eSStefano Zampini } 17500c7d97c5SJed Brown 17510c7d97c5SJed Brown /* identify new decomposition in terms of ranks in the old communicator */ 17523828260eSStefano Zampini for(i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=coarse_subdivision[ranks_stretching_ratio*i]*procs_jumps_coarse_comm; 17530c7d97c5SJed Brown printf("coarse_subdivision in old end new ranks\n"); 17540c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) 17553828260eSStefano Zampini if(coarse_subdivision[i]!=MPI_PROC_NULL) { 17563828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]/procs_jumps_coarse_comm); 17573828260eSStefano Zampini } else { 17583828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]); 17593828260eSStefano Zampini } 17600c7d97c5SJed Brown printf("\n"); 17610c7d97c5SJed Brown } 17620c7d97c5SJed Brown 17630c7d97c5SJed Brown /* Scatter new decomposition for send details */ 176453cdbc3dSStefano Zampini ierr = MPI_Scatter(&coarse_subdivision[0],1,MPIU_INT,&rank_coarse_proc_send_to,1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 17650c7d97c5SJed Brown /* Scatter receiving details to members of coarse decomposition */ 17660c7d97c5SJed Brown if( coarse_color == 0) { 176753cdbc3dSStefano Zampini ierr = MPI_Scatter(&total_count_recv[0],1,MPIU_INT,&count_recv,1,MPIU_INT,master_proc,coarse_comm);CHKERRQ(ierr); 17680c7d97c5SJed Brown ierr = PetscMalloc (count_recv*sizeof(PetscMPIInt),&ranks_recv);CHKERRQ(ierr); 176953cdbc3dSStefano 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); 17700c7d97c5SJed Brown } 17710c7d97c5SJed Brown 17720c7d97c5SJed Brown //printf("I will send my matrix data to proc %d\n",rank_coarse_proc_send_to); 17730c7d97c5SJed Brown //if(coarse_color == 0) { 17740c7d97c5SJed Brown // printf("I will receive some matrix data from %d processes (ranks follows)\n",count_recv); 17750c7d97c5SJed Brown // for(i=0;i<count_recv;i++) 17760c7d97c5SJed Brown // printf("%d ",ranks_recv[i]); 17770c7d97c5SJed Brown // printf("\n"); 17780c7d97c5SJed Brown //} 17790c7d97c5SJed Brown 17800c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 17810c7d97c5SJed Brown //ierr = PetscFree(coarse_subdivision);CHKERRQ(ierr); 17820c7d97c5SJed Brown //ierr = PetscFree(total_count_recv);CHKERRQ(ierr); 17830c7d97c5SJed Brown //ierr = PetscFree(total_ranks_recv);CHKERRQ(ierr); 17840c7d97c5SJed Brown free(coarse_subdivision); 17850c7d97c5SJed Brown free(total_count_recv); 17860c7d97c5SJed Brown free(total_ranks_recv); 17870c7d97c5SJed Brown ierr = PetscFree(displacements_recv);CHKERRQ(ierr); 17880c7d97c5SJed Brown } 17890c7d97c5SJed Brown break; 17900c7d97c5SJed Brown } 17910c7d97c5SJed Brown 17920c7d97c5SJed Brown case(REPLICATED_BDDC): 17930c7d97c5SJed Brown 17940c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 17950c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 17960c7d97c5SJed Brown coarse_pc_type = PCLU; 179753cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 17980c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 17990c7d97c5SJed Brown active_rank = rank_prec_comm; 18000c7d97c5SJed Brown break; 18010c7d97c5SJed Brown 18020c7d97c5SJed Brown case(PARALLEL_BDDC): 18030c7d97c5SJed Brown 18040c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 18050c7d97c5SJed Brown coarse_mat_type = MATMPIAIJ; 18060c7d97c5SJed Brown coarse_pc_type = PCREDUNDANT; 180753cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 18080c7d97c5SJed Brown coarse_comm = prec_comm; 18090c7d97c5SJed Brown active_rank = rank_prec_comm; 18100c7d97c5SJed Brown break; 18110c7d97c5SJed Brown 18120c7d97c5SJed Brown case(SEQUENTIAL_BDDC): 18130c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 18140c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 18150c7d97c5SJed Brown coarse_pc_type = PCLU; 181653cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 18170c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 18180c7d97c5SJed Brown active_rank = master_proc; 18190c7d97c5SJed Brown break; 18200c7d97c5SJed Brown } 18210c7d97c5SJed Brown 18220c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 18230c7d97c5SJed Brown 18240c7d97c5SJed Brown case(SCATTERS_BDDC): 18250c7d97c5SJed Brown { 18260c7d97c5SJed Brown if(pcbddc->coarse_problem_type==MULTILEVEL_BDDC) { 18270c7d97c5SJed Brown 18280c7d97c5SJed Brown PetscMPIInt send_size; 18290c7d97c5SJed Brown PetscInt *aux_ins_indices; 18300c7d97c5SJed Brown PetscInt ii,jj; 18310c7d97c5SJed Brown MPI_Request *requests; 18320c7d97c5SJed Brown 18330c7d97c5SJed Brown /* allocate auxiliary space */ 18345619798eSStefano Zampini ierr = PetscMalloc (pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 18355619798eSStefano 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); 18360c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->coarse_size*sizeof(PetscInt),&aux_ins_indices);CHKERRQ(ierr); 18370c7d97c5SJed Brown ierr = PetscMemzero(aux_ins_indices,pcbddc->coarse_size*sizeof(PetscInt));CHKERRQ(ierr); 18380c7d97c5SJed Brown /* allocate stuffs for message massing */ 18390c7d97c5SJed Brown ierr = PetscMalloc ( (count_recv+1)*sizeof(MPI_Request),&requests);CHKERRQ(ierr); 18400c7d97c5SJed Brown for(i=0;i<count_recv+1;i++) requests[i]=MPI_REQUEST_NULL; 18410c7d97c5SJed Brown ierr = PetscMalloc ( count_recv*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 18420c7d97c5SJed Brown ierr = PetscMalloc ( count_recv*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 18430c7d97c5SJed Brown /* fill up quantities */ 18440c7d97c5SJed Brown j=0; 18450c7d97c5SJed Brown for(i=0;i<count_recv;i++){ 18460c7d97c5SJed Brown ii = ranks_recv[i]; 18470c7d97c5SJed Brown localsizes2[i]=pcbddc->local_primal_sizes[ii]*pcbddc->local_primal_sizes[ii]; 18480c7d97c5SJed Brown localdispl2[i]=j; 18490c7d97c5SJed Brown j+=localsizes2[i]; 18500c7d97c5SJed Brown jj = pcbddc->local_primal_displacements[ii]; 18510c7d97c5SJed 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 18520c7d97c5SJed Brown } 18530c7d97c5SJed Brown //printf("aux_ins_indices 1\n"); 18540c7d97c5SJed Brown //for(i=0;i<pcbddc->coarse_size;i++) 18550c7d97c5SJed Brown // printf("%d ",aux_ins_indices[i]); 18560c7d97c5SJed Brown //printf("\n"); 18570c7d97c5SJed Brown /* temp_coarse_mat_vals used to store temporarly received matrix values */ 18580c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 18590c7d97c5SJed Brown /* evaluate how many values I will insert in coarse mat */ 18600c7d97c5SJed Brown ins_local_primal_size=0; 18610c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++) 18620c7d97c5SJed Brown if(aux_ins_indices[i]) 18630c7d97c5SJed Brown ins_local_primal_size++; 18640c7d97c5SJed Brown /* evaluate indices I will insert in coarse mat */ 18650c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 18660c7d97c5SJed Brown j=0; 18670c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++) 18680c7d97c5SJed Brown if(aux_ins_indices[i]) 18690c7d97c5SJed Brown ins_local_primal_indices[j++]=i; 18700c7d97c5SJed Brown /* use aux_ins_indices to realize a global to local mapping */ 18710c7d97c5SJed Brown j=0; 18720c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++){ 18730c7d97c5SJed Brown if(aux_ins_indices[i]==0){ 18740c7d97c5SJed Brown aux_ins_indices[i]=-1; 18750c7d97c5SJed Brown } else { 18760c7d97c5SJed Brown aux_ins_indices[i]=j; 18770c7d97c5SJed Brown j++; 18780c7d97c5SJed Brown } 18790c7d97c5SJed Brown } 18800c7d97c5SJed Brown 18810c7d97c5SJed Brown //printf("New details localsizes2 localdispl2\n"); 18820c7d97c5SJed Brown //for(i=0;i<count_recv;i++) 18830c7d97c5SJed Brown // printf("(%d %d) ",localsizes2[i],localdispl2[i]); 18840c7d97c5SJed Brown //printf("\n"); 18850c7d97c5SJed Brown //printf("aux_ins_indices 2\n"); 18860c7d97c5SJed Brown //for(i=0;i<pcbddc->coarse_size;i++) 18870c7d97c5SJed Brown // printf("%d ",aux_ins_indices[i]); 18880c7d97c5SJed Brown //printf("\n"); 18890c7d97c5SJed Brown //printf("ins_local_primal_indices\n"); 18900c7d97c5SJed Brown //for(i=0;i<ins_local_primal_size;i++) 18910c7d97c5SJed Brown // printf("%d ",ins_local_primal_indices[i]); 18920c7d97c5SJed Brown //printf("\n"); 18930c7d97c5SJed Brown //printf("coarse_submat_vals\n"); 18940c7d97c5SJed Brown //for(i=0;i<pcbddc->local_primal_size;i++) 18950c7d97c5SJed Brown // for(j=0;j<pcbddc->local_primal_size;j++) 18960c7d97c5SJed 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]); 18970c7d97c5SJed Brown //printf("\n"); 18980c7d97c5SJed Brown 18990c7d97c5SJed Brown /* processes partecipating in coarse problem receive matrix data from their friends */ 190053cdbc3dSStefano 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); 19010c7d97c5SJed Brown if(rank_coarse_proc_send_to != MPI_PROC_NULL ) { 19020c7d97c5SJed Brown send_size=pcbddc->local_primal_size*pcbddc->local_primal_size; 190353cdbc3dSStefano 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); 19040c7d97c5SJed Brown } 190553cdbc3dSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 19060c7d97c5SJed Brown 19070c7d97c5SJed Brown //if(coarse_color == 0) { 19080c7d97c5SJed Brown // printf("temp_coarse_mat_vals\n"); 19090c7d97c5SJed Brown // for(k=0;k<count_recv;k++){ 19100c7d97c5SJed Brown // printf("---- %d ----\n",ranks_recv[k]); 19110c7d97c5SJed Brown // for(i=0;i<pcbddc->local_primal_sizes[ranks_recv[k]];i++) 19120c7d97c5SJed Brown // for(j=0;j<pcbddc->local_primal_sizes[ranks_recv[k]];j++) 19130c7d97c5SJed 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]); 19140c7d97c5SJed Brown // printf("\n"); 19150c7d97c5SJed Brown // } 19160c7d97c5SJed Brown //} 19170c7d97c5SJed Brown /* calculate data to insert in coarse mat */ 19180c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 19190c7d97c5SJed Brown PetscMemzero(ins_coarse_mat_vals,ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar)); 19200c7d97c5SJed Brown 19210c7d97c5SJed Brown PetscMPIInt rr,kk,lps,lpd; 19220c7d97c5SJed Brown PetscInt row_ind,col_ind; 19230c7d97c5SJed Brown for(k=0;k<count_recv;k++){ 19240c7d97c5SJed Brown rr = ranks_recv[k]; 19250c7d97c5SJed Brown kk = localdispl2[k]; 19260c7d97c5SJed Brown lps = pcbddc->local_primal_sizes[rr]; 19270c7d97c5SJed Brown lpd = pcbddc->local_primal_displacements[rr]; 19280c7d97c5SJed Brown //printf("Inserting the following indices (received from %d)\n",rr); 19290c7d97c5SJed Brown for(j=0;j<lps;j++){ 19300c7d97c5SJed Brown col_ind=aux_ins_indices[pcbddc->replicated_local_primal_indices[lpd+j]]; 19310c7d97c5SJed Brown for(i=0;i<lps;i++){ 19320c7d97c5SJed Brown row_ind=aux_ins_indices[pcbddc->replicated_local_primal_indices[lpd+i]]; 19330c7d97c5SJed Brown //printf("%d %d\n",row_ind,col_ind); 19340c7d97c5SJed Brown ins_coarse_mat_vals[col_ind*ins_local_primal_size+row_ind]+=temp_coarse_mat_vals[kk+j*lps+i]; 19350c7d97c5SJed Brown } 19360c7d97c5SJed Brown } 19370c7d97c5SJed Brown } 19380c7d97c5SJed Brown ierr = PetscFree(requests);CHKERRQ(ierr); 19390c7d97c5SJed Brown ierr = PetscFree(aux_ins_indices);CHKERRQ(ierr); 19400c7d97c5SJed Brown ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr); 19410c7d97c5SJed Brown if(coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 19420c7d97c5SJed Brown 19430c7d97c5SJed Brown /* create local to global mapping needed by coarse MATIS */ 19440c7d97c5SJed Brown { 19450c7d97c5SJed Brown IS coarse_IS; 194653cdbc3dSStefano Zampini if(coarse_comm != MPI_COMM_NULL ) ierr = MPI_Comm_free(&coarse_comm);CHKERRQ(ierr); 19470c7d97c5SJed Brown coarse_comm = prec_comm; 19480c7d97c5SJed Brown active_rank=rank_prec_comm; 19490c7d97c5SJed Brown ierr = ISCreateGeneral(coarse_comm,ins_local_primal_size,ins_local_primal_indices,PETSC_COPY_VALUES,&coarse_IS);CHKERRQ(ierr); 19500c7d97c5SJed Brown ierr = ISLocalToGlobalMappingCreateIS(coarse_IS,&coarse_ISLG);CHKERRQ(ierr); 19510c7d97c5SJed Brown ierr = ISDestroy(&coarse_IS);CHKERRQ(ierr); 19520c7d97c5SJed Brown } 19530c7d97c5SJed Brown } 19540c7d97c5SJed Brown if(pcbddc->coarse_problem_type==PARALLEL_BDDC) { 19550c7d97c5SJed Brown /* arrays for values insertion */ 19560c7d97c5SJed Brown ins_local_primal_size = pcbddc->local_primal_size; 19570c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscMPIInt),&ins_local_primal_indices);CHKERRQ(ierr); 19580c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 19590c7d97c5SJed Brown for(j=0;j<ins_local_primal_size;j++){ 19600c7d97c5SJed Brown ins_local_primal_indices[j]=pcbddc->local_primal_indices[j]; 19610c7d97c5SJed 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]; 19620c7d97c5SJed Brown } 19630c7d97c5SJed Brown } 19640c7d97c5SJed Brown break; 19650c7d97c5SJed Brown 19660c7d97c5SJed Brown } 19670c7d97c5SJed Brown 19680c7d97c5SJed Brown case(GATHERS_BDDC): 19690c7d97c5SJed Brown { 19700c7d97c5SJed Brown 19710c7d97c5SJed Brown PetscMPIInt mysize,mysize2; 19720c7d97c5SJed Brown 19730c7d97c5SJed Brown if(rank_prec_comm==active_rank) { 19740c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 19750c7d97c5SJed Brown pcbddc->replicated_local_primal_values = (PetscScalar*)calloc(pcbddc->replicated_primal_size,sizeof(PetscScalar)); 19760c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 19770c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 19780c7d97c5SJed Brown /* arrays for values insertion */ 19790c7d97c5SJed Brown ins_local_primal_size = pcbddc->coarse_size; 19800c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscMPIInt),&ins_local_primal_indices);CHKERRQ(ierr); 19810c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 19820c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) localsizes2[i]=pcbddc->local_primal_sizes[i]*pcbddc->local_primal_sizes[i]; 19830c7d97c5SJed Brown localdispl2[0]=0; 19840c7d97c5SJed Brown for(i=1;i<size_prec_comm;i++) localdispl2[i]=localsizes2[i-1]+localdispl2[i-1]; 19850c7d97c5SJed Brown j=0; 19860c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) j+=localsizes2[i]; 19870c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 19880c7d97c5SJed Brown } 19890c7d97c5SJed Brown 19900c7d97c5SJed Brown mysize=pcbddc->local_primal_size; 19910c7d97c5SJed Brown mysize2=pcbddc->local_primal_size*pcbddc->local_primal_size; 19920c7d97c5SJed Brown if(pcbddc->coarse_problem_type == SEQUENTIAL_BDDC){ 199353cdbc3dSStefano 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); 199453cdbc3dSStefano 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); 19950c7d97c5SJed Brown } else { 199653cdbc3dSStefano 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); 199753cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,prec_comm);CHKERRQ(ierr); 19980c7d97c5SJed Brown } 19990c7d97c5SJed Brown 20000c7d97c5SJed Brown /* free data structures no longer needed and allocate some space which will be needed in BDDC application */ 20010c7d97c5SJed Brown if(rank_prec_comm==active_rank) { 20020c7d97c5SJed Brown PetscInt offset,offset2,row_ind,col_ind; 20030c7d97c5SJed Brown for(j=0;j<ins_local_primal_size;j++){ 20040c7d97c5SJed Brown ins_local_primal_indices[j]=j; 20050c7d97c5SJed Brown for(i=0;i<ins_local_primal_size;i++) ins_coarse_mat_vals[j*ins_local_primal_size+i]=0.0; 20060c7d97c5SJed Brown } 20070c7d97c5SJed Brown for(k=0;k<size_prec_comm;k++){ 20080c7d97c5SJed Brown offset=pcbddc->local_primal_displacements[k]; 20090c7d97c5SJed Brown offset2=localdispl2[k]; 20100c7d97c5SJed Brown for(j=0;j<pcbddc->local_primal_sizes[k];j++){ 20110c7d97c5SJed Brown col_ind=pcbddc->replicated_local_primal_indices[offset+j]; 20120c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_sizes[k];i++){ 20130c7d97c5SJed Brown row_ind=pcbddc->replicated_local_primal_indices[offset+i]; 20140c7d97c5SJed Brown ins_coarse_mat_vals[col_ind*pcbddc->coarse_size+row_ind]+=temp_coarse_mat_vals[offset2+j*pcbddc->local_primal_sizes[k]+i]; 20150c7d97c5SJed Brown } 20160c7d97c5SJed Brown } 20170c7d97c5SJed Brown } 20180c7d97c5SJed Brown } 20190c7d97c5SJed Brown break; 20200c7d97c5SJed Brown }//switch on coarse problem and communications associated with finished 20210c7d97c5SJed Brown } 20220c7d97c5SJed Brown 20230c7d97c5SJed Brown /* Now create and fill up coarse matrix */ 20240c7d97c5SJed Brown if( rank_prec_comm == active_rank ) { 20250c7d97c5SJed Brown if(pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 20260c7d97c5SJed Brown ierr = MatCreate(coarse_comm,&pcbddc->coarse_mat);CHKERRQ(ierr); 20270c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_mat,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size);CHKERRQ(ierr); 20280c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_mat,coarse_mat_type);CHKERRQ(ierr); 20290c7d97c5SJed Brown ierr = MatSetOption(pcbddc->coarse_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 20300c7d97c5SJed Brown ierr = MatSetOption(pcbddc->coarse_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); //local values stored in column major 20310c7d97c5SJed Brown } else { 20320c7d97c5SJed Brown Mat matis_coarse_local_mat; 20330c7d97c5SJed Brown ierr = MatCreateIS(coarse_comm,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_ISLG,&pcbddc->coarse_mat);CHKERRQ(ierr); 20340c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 20350c7d97c5SJed Brown ierr = MatSetOption(matis_coarse_local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); //local values stored in column major 2036a0ba757dSStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 20370c7d97c5SJed Brown } 2038a0ba757dSStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 20390c7d97c5SJed 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); 20400c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20410c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20420c7d97c5SJed Brown if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 20430c7d97c5SJed Brown Mat matis_coarse_local_mat; 20440c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 20450c7d97c5SJed Brown ierr = MatSetBlockSize(matis_coarse_local_mat,bs);CHKERRQ(ierr); 20460c7d97c5SJed Brown } 20470c7d97c5SJed Brown 20480c7d97c5SJed Brown ierr = MatGetVecs(pcbddc->coarse_mat,&pcbddc->coarse_vec,&pcbddc->coarse_rhs);CHKERRQ(ierr); 20490c7d97c5SJed Brown /* Preconditioner for coarse problem */ 205053cdbc3dSStefano Zampini ierr = KSPCreate(coarse_comm,&pcbddc->coarse_ksp);CHKERRQ(ierr); 205153cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 205253cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 20535619798eSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 205453cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 205553cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 205653cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 20570c7d97c5SJed Brown /* Allow user's customization */ 205853cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 20590c7d97c5SJed Brown /* Set Up PC for coarse problem BDDC */ 206053cdbc3dSStefano Zampini if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2061e269702eSStefano Zampini if(dbg_flag) { 2062e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------Setting up a new level---------------\n");CHKERRQ(ierr); 2063e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2064e269702eSStefano Zampini } 206553cdbc3dSStefano Zampini ierr = PCBDDCSetCoarseProblemType(pc_temp,MULTILEVEL_BDDC);CHKERRQ(ierr); 206653cdbc3dSStefano Zampini } 206753cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 20685619798eSStefano Zampini if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 20695619798eSStefano Zampini if(dbg_flag) { 20705619798eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------New level set------------------------\n");CHKERRQ(ierr); 20715619798eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 20725619798eSStefano Zampini } 20735619798eSStefano Zampini } 20740c7d97c5SJed Brown } 20750c7d97c5SJed Brown if(pcbddc->coarse_communications_type == SCATTERS_BDDC) { 20760c7d97c5SJed Brown IS local_IS,global_IS; 20770c7d97c5SJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&local_IS);CHKERRQ(ierr); 20780c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_indices,PETSC_COPY_VALUES,&global_IS);CHKERRQ(ierr); 20790c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_P,local_IS,pcbddc->coarse_vec,global_IS,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 20800c7d97c5SJed Brown ierr = ISDestroy(&local_IS);CHKERRQ(ierr); 20810c7d97c5SJed Brown ierr = ISDestroy(&global_IS);CHKERRQ(ierr); 20820c7d97c5SJed Brown } 20830c7d97c5SJed Brown 20840c7d97c5SJed Brown 20850c7d97c5SJed Brown /* Check condition number of coarse problem */ 2086e269702eSStefano Zampini if( pcbddc->coarse_problem_type == MULTILEVEL_BDDC && dbg_flag && rank_prec_comm == active_rank ) { 20870c7d97c5SJed Brown PetscScalar m_one=-1.0; 20885619798eSStefano Zampini PetscReal infty_error,lambda_min,lambda_max,kappa_2; 20890c7d97c5SJed Brown 20905619798eSStefano Zampini /* change coarse ksp object to an iterative method suitable for extreme eigenvalues' estimation */ 2091d49ef151SStefano Zampini ierr = KSPSetComputeSingularValues(pcbddc->coarse_ksp,PETSC_TRUE);CHKERRQ(ierr); 20925619798eSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,KSPGMRES);CHKERRQ(ierr); 20935619798eSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,1.e-8,1.e-8,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 20945619798eSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 2095d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->coarse_rhs,PETSC_NULL);CHKERRQ(ierr); 2096d49ef151SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 2097d49ef151SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,pcbddc->coarse_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 2098d49ef151SStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,pcbddc->coarse_rhs,pcbddc->coarse_rhs);CHKERRQ(ierr); 2099d49ef151SStefano Zampini ierr = KSPComputeExtremeSingularValues(pcbddc->coarse_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); 21005619798eSStefano Zampini kappa_2=lambda_max/lambda_min; 21015619798eSStefano Zampini ierr = KSPGetIterationNumber(pcbddc->coarse_ksp,&k);CHKERRQ(ierr); 2102d49ef151SStefano Zampini ierr = VecAXPY(pcbddc->coarse_rhs,m_one,pcbddc->coarse_vec);CHKERRQ(ierr); 2103d49ef151SStefano Zampini ierr = VecNorm(pcbddc->coarse_rhs,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 21045619798eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem condition number estimated with %d iterations of gmres is: % 1.14e\n",k,kappa_2);CHKERRQ(ierr); 2105e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues: % 1.14e %1.14e\n",lambda_min,lambda_max);CHKERRQ(ierr); 2106e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem infty_error: %1.14e\n",infty_error);CHKERRQ(ierr); 21075619798eSStefano Zampini /* restore coarse ksp to default values */ 2108d49ef151SStefano Zampini ierr = KSPSetComputeSingularValues(pcbddc->coarse_ksp,PETSC_FALSE);CHKERRQ(ierr); 21095619798eSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 21105619798eSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 21115619798eSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 21125619798eSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 211353cdbc3dSStefano Zampini } 21140c7d97c5SJed Brown 21150c7d97c5SJed Brown /* free data structures no longer needed */ 21160c7d97c5SJed Brown if(coarse_ISLG) { ierr = ISLocalToGlobalMappingDestroy(&coarse_ISLG);CHKERRQ(ierr); } 21170c7d97c5SJed Brown if(ins_local_primal_indices) { ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); } 21180c7d97c5SJed Brown if(ins_coarse_mat_vals) { ierr = PetscFree(ins_coarse_mat_vals);CHKERRQ(ierr);} 21190c7d97c5SJed Brown if(localsizes2) { ierr = PetscFree(localsizes2);CHKERRQ(ierr);} 21200c7d97c5SJed Brown if(localdispl2) { ierr = PetscFree(localdispl2);CHKERRQ(ierr);} 21210c7d97c5SJed Brown if(temp_coarse_mat_vals) { ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr);} 21220c7d97c5SJed Brown 21230c7d97c5SJed Brown PetscFunctionReturn(0); 21240c7d97c5SJed Brown } 21250c7d97c5SJed Brown 21260c7d97c5SJed Brown #undef __FUNCT__ 21270c7d97c5SJed Brown #define __FUNCT__ "PCBDDCManageLocalBoundaries" 212853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCManageLocalBoundaries(PC pc) 21290c7d97c5SJed Brown { 21300c7d97c5SJed Brown 21310c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 21320c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 21330c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 213453cdbc3dSStefano Zampini PetscInt **neighbours_set; 213553cdbc3dSStefano Zampini PetscInt bs,ierr,i,j,s,k,iindex; 21360c7d97c5SJed Brown PetscInt total_counts; 21370c7d97c5SJed Brown PetscBool flg_row; 21380c7d97c5SJed Brown PCBDDCGraph mat_graph; 213953cdbc3dSStefano Zampini PetscInt neumann_bsize; 214053cdbc3dSStefano Zampini const PetscInt* neumann_nodes; 21410c7d97c5SJed Brown Mat mat_adj; 2142a0ba757dSStefano Zampini PetscBool symmetrize_rowij=PETSC_TRUE,compressed_rowij=PETSC_FALSE; 2143a0ba757dSStefano Zampini PetscMPIInt adapt_interface=0,adapt_interface_reduced=0; 2144a0ba757dSStefano Zampini PetscInt* queue_in_global_numbering; 2145a0ba757dSStefano Zampini MPI_Comm interface_comm=((PetscObject)pc)->comm; 21460c7d97c5SJed Brown 21470c7d97c5SJed Brown PetscFunctionBegin; 21480c7d97c5SJed Brown 2149a0ba757dSStefano Zampini /* allocate and initialize needed graph structure */ 21500c7d97c5SJed Brown ierr = PetscMalloc(sizeof(*mat_graph),&mat_graph);CHKERRQ(ierr); 21510c7d97c5SJed Brown ierr = MatConvert(matis->A,MATMPIADJ,MAT_INITIAL_MATRIX,&mat_adj);CHKERRQ(ierr); 2152a0ba757dSStefano Zampini /* ierr = MatDuplicate(matis->A,MAT_COPY_VALUES,&mat_adj);CHKERRQ(ierr); */ 2153a0ba757dSStefano Zampini ierr = MatGetRowIJ(mat_adj,0,symmetrize_rowij,compressed_rowij,&mat_graph->nvtxs,&mat_graph->xadj,&mat_graph->adjncy,&flg_row);CHKERRQ(ierr); 21540c7d97c5SJed Brown if(!flg_row) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatGetRowIJ called from PCBDDCManageLocalBoundaries.\n"); 2155a0ba757dSStefano Zampini i = mat_graph->nvtxs; 2156a0ba757dSStefano 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); 2157a0ba757dSStefano Zampini ierr = PetscMalloc3(i,PetscInt,&mat_graph->which_dof,i,PetscBool,&mat_graph->touched,i,PetscInt,&queue_in_global_numbering);CHKERRQ(ierr); 2158a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->where,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2159a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->count,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2160a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->which_dof,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2161a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->queue,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 21623828260eSStefano Zampini ierr = PetscMemzero(mat_graph->cptr,(mat_graph->nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 21633828260eSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){mat_graph->touched[i]=PETSC_FALSE;} 2164a0ba757dSStefano Zampini 2165a0ba757dSStefano Zampini /* TODO: IS for dof splitting */ 2166a0ba757dSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 21670c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs/bs;i++) { 21680c7d97c5SJed Brown for(s=0;s<bs;s++) { 21690c7d97c5SJed Brown mat_graph->which_dof[i*bs+s]=s; 21700c7d97c5SJed Brown } 21710c7d97c5SJed Brown } 21720c7d97c5SJed Brown 21730c7d97c5SJed Brown total_counts=0; 21740c7d97c5SJed Brown for(i=0;i<pcis->n_neigh;i++){ 21750c7d97c5SJed Brown s=pcis->n_shared[i]; 21760c7d97c5SJed Brown total_counts+=s; 217753cdbc3dSStefano Zampini for(j=0;j<s;j++){ 21780c7d97c5SJed Brown mat_graph->count[pcis->shared[i][j]] += 1; 21790c7d97c5SJed Brown } 21800c7d97c5SJed Brown } 21810c7d97c5SJed Brown /* Take into account Neumann data incrementing number of sharing subdomains for all but faces nodes lying on the interface */ 218253cdbc3dSStefano Zampini if(pcbddc->NeumannBoundaries) { 218353cdbc3dSStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundaries,&neumann_bsize);CHKERRQ(ierr); 218453cdbc3dSStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundaries,&neumann_nodes);CHKERRQ(ierr); 218553cdbc3dSStefano Zampini for(i=0;i<neumann_bsize;i++){ 218653cdbc3dSStefano Zampini iindex = neumann_nodes[i]; 218753cdbc3dSStefano Zampini if(mat_graph->count[iindex] > 2){ 218853cdbc3dSStefano Zampini mat_graph->count[iindex]+=1; 21890c7d97c5SJed Brown total_counts++; 21900c7d97c5SJed Brown } 21910c7d97c5SJed Brown } 21920c7d97c5SJed Brown } 21930c7d97c5SJed Brown 2194a0ba757dSStefano Zampini /* allocate space for storing neighbours' set */ 219553cdbc3dSStefano Zampini ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt*),&neighbours_set);CHKERRQ(ierr); 219653cdbc3dSStefano Zampini if(mat_graph->nvtxs) ierr = PetscMalloc(total_counts*sizeof(PetscInt),&neighbours_set[0]);CHKERRQ(ierr); 219753cdbc3dSStefano Zampini for(i=1;i<mat_graph->nvtxs;i++) neighbours_set[i]=neighbours_set[i-1]+mat_graph->count[i-1]; 2198a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->count,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 21990c7d97c5SJed Brown for(i=0;i<pcis->n_neigh;i++){ 22000c7d97c5SJed Brown s=pcis->n_shared[i]; 22010c7d97c5SJed Brown for(j=0;j<s;j++) { 22020c7d97c5SJed Brown k=pcis->shared[i][j]; 220353cdbc3dSStefano Zampini neighbours_set[k][mat_graph->count[k]] = pcis->neigh[i]; 22040c7d97c5SJed Brown mat_graph->count[k]+=1; 22050c7d97c5SJed Brown } 22060c7d97c5SJed Brown } 22070c7d97c5SJed Brown /* set -1 fake neighbour */ 220853cdbc3dSStefano Zampini if(pcbddc->NeumannBoundaries) { 220953cdbc3dSStefano Zampini for(i=0;i<neumann_bsize;i++){ 221053cdbc3dSStefano Zampini iindex = neumann_nodes[i]; 221153cdbc3dSStefano Zampini if( mat_graph->count[iindex] > 2){ 2212a0ba757dSStefano Zampini neighbours_set[iindex][mat_graph->count[iindex]] = -1; /* An additional fake neighbour (with rank -1) */ 221353cdbc3dSStefano Zampini mat_graph->count[iindex]+=1; 22140c7d97c5SJed Brown } 22150c7d97c5SJed Brown } 221653cdbc3dSStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundaries,&neumann_nodes);CHKERRQ(ierr); 22170c7d97c5SJed Brown } 2218a0ba757dSStefano Zampini /* sort set of sharing subdomains for comparison */ 221953cdbc3dSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++) { ierr = PetscSortInt(mat_graph->count[i],neighbours_set[i]);CHKERRQ(ierr); } 2220a0ba757dSStefano Zampini /* start analyzing local interface */ 22210c7d97c5SJed Brown PetscInt nodes_touched=0; 22220c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs;i++){ 2223a0ba757dSStefano Zampini if(!mat_graph->count[i]){ /* internal nodes */ 22240c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 22250c7d97c5SJed Brown mat_graph->where[i]=0; 22260c7d97c5SJed Brown nodes_touched++; 22270c7d97c5SJed Brown } 22280c7d97c5SJed Brown } 2229a0ba757dSStefano Zampini PetscInt where_values=1; 22300c7d97c5SJed Brown PetscBool same_set; 22310c7d97c5SJed Brown mat_graph->ncmps = 0; 22320c7d97c5SJed Brown while(nodes_touched<mat_graph->nvtxs) { 2233a0ba757dSStefano Zampini /* find first untouched node in local ordering */ 22340c7d97c5SJed Brown i=0; 22350c7d97c5SJed Brown while(mat_graph->touched[i]) i++; 22360c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 2237a0ba757dSStefano Zampini mat_graph->where[i]=where_values; 22380c7d97c5SJed Brown nodes_touched++; 2239a0ba757dSStefano Zampini /* now find all other nodes having the same set of sharing subdomains */ 22400c7d97c5SJed Brown for(j=i+1;j<mat_graph->nvtxs;j++){ 2241a0ba757dSStefano Zampini /* check for same number of sharing subdomains and dof number */ 22420c7d97c5SJed Brown if(mat_graph->count[i]==mat_graph->count[j] && mat_graph->which_dof[i] == mat_graph->which_dof[j] ){ 2243a0ba757dSStefano Zampini /* check for same set of sharing subdomains */ 22440c7d97c5SJed Brown same_set=PETSC_TRUE; 22450c7d97c5SJed Brown for(k=0;k<mat_graph->count[j];k++){ 224653cdbc3dSStefano Zampini if(neighbours_set[i][k]!=neighbours_set[j][k]) { 22470c7d97c5SJed Brown same_set=PETSC_FALSE; 22480c7d97c5SJed Brown } 22490c7d97c5SJed Brown } 2250a0ba757dSStefano Zampini /* I found a friend of mine */ 22510c7d97c5SJed Brown if(same_set) { 2252a0ba757dSStefano Zampini mat_graph->where[j]=where_values; 22530c7d97c5SJed Brown mat_graph->touched[j]=PETSC_TRUE; 22540c7d97c5SJed Brown nodes_touched++; 22550c7d97c5SJed Brown } 22560c7d97c5SJed Brown } 22570c7d97c5SJed Brown } 2258a0ba757dSStefano Zampini where_values++; 22590c7d97c5SJed Brown } 2260a0ba757dSStefano Zampini where_values--; if(where_values<0) where_values=0; 2261a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscMPIInt),&mat_graph->where_ncmps);CHKERRQ(ierr); 2262a0ba757dSStefano Zampini /* Find connected components defined on the shared interface */ 2263a0ba757dSStefano Zampini if(where_values) { 2264a0ba757dSStefano Zampini ierr = PCBDDCFindConnectedComponents(mat_graph, where_values); 2265a0ba757dSStefano Zampini /* For consistency among neughbouring procs, I need to sort (by global ordering) each connected component contained in the global queue (and carring together the local queue) */ 2266a0ba757dSStefano Zampini for(i=0;i<mat_graph->ncmps;i++) { 2267a0ba757dSStefano 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); 2268a0ba757dSStefano 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); 2269a0ba757dSStefano Zampini } 2270a0ba757dSStefano Zampini /* for(i=0;i<mat_graph->ncmps;i++) { 2271a0ba757dSStefano Zampini printf("[queue num %d] ptr %d, length %d: global node (local node)\n",i,mat_graph->cptr[i],mat_graph->cptr[i+1]-mat_graph->cptr[i]); 2272a0ba757dSStefano Zampini for(j=0;j<mat_graph->cptr[i+1]-mat_graph->cptr[i];j++){ 2273a0ba757dSStefano Zampini printf("%d (%d) ",queue_in_global_numbering[mat_graph->cptr[i]+j],mat_graph->queue[mat_graph->cptr[i]+j]); 2274a0ba757dSStefano Zampini } 2275a0ba757dSStefano Zampini printf("\n"); 2276a0ba757dSStefano Zampini } */ 2277a0ba757dSStefano Zampini } 2278a0ba757dSStefano Zampini /* check consistency of connected components among neighbouring subdomains -> it adapt them in case it is needed */ 2279a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 2280a0ba757dSStefano Zampini if(mat_graph->where_ncmps[i]>1) { /* We are not sure that two connected components will be the same among subdomains sharing a subset of local interface */ 2281a0ba757dSStefano Zampini adapt_interface=1; 2282a0ba757dSStefano Zampini break; 2283a0ba757dSStefano Zampini } 2284a0ba757dSStefano Zampini } 2285a0ba757dSStefano Zampini ierr = MPI_Allreduce(&adapt_interface,&adapt_interface_reduced,1,MPIU_INT,MPI_LOR,interface_comm);CHKERRQ(ierr); 2286a0ba757dSStefano Zampini if(where_values && adapt_interface_reduced) { 22870c7d97c5SJed Brown 2288a0ba757dSStefano Zampini PetscInt sum_requests=0,my_rank; 2289a0ba757dSStefano Zampini PetscInt buffer_size,start_of_recv,size_of_recv,start_of_send; 2290a0ba757dSStefano Zampini PetscInt temp_buffer_size,ins_val,global_where_counter; 2291a0ba757dSStefano Zampini PetscInt *cum_recv_counts; 2292a0ba757dSStefano Zampini PetscInt *where_to_nodes_indices; 2293a0ba757dSStefano Zampini PetscInt *petsc_buffer; 2294a0ba757dSStefano Zampini PetscMPIInt *recv_buffer; 2295a0ba757dSStefano Zampini PetscMPIInt *recv_buffer_where; 2296a0ba757dSStefano Zampini PetscMPIInt *send_buffer; 2297a0ba757dSStefano Zampini PetscMPIInt size_of_send; 2298a0ba757dSStefano Zampini PetscInt *sizes_of_sends; 2299a0ba757dSStefano Zampini MPI_Request *send_requests; 2300a0ba757dSStefano Zampini MPI_Request *recv_requests; 2301a0ba757dSStefano Zampini PetscInt *where_cc_adapt; 2302a0ba757dSStefano Zampini PetscInt **temp_buffer; 2303a0ba757dSStefano Zampini PetscInt *nodes_to_temp_buffer_indices; 2304a0ba757dSStefano Zampini PetscInt *add_to_where; 2305a0ba757dSStefano Zampini 2306a0ba757dSStefano Zampini ierr = MPI_Comm_rank(interface_comm,&my_rank);CHKERRQ(ierr); 2307a0ba757dSStefano Zampini ierr = PetscMalloc((where_values+1)*sizeof(PetscInt),&cum_recv_counts);CHKERRQ(ierr); 2308a0ba757dSStefano Zampini ierr = PetscMemzero(cum_recv_counts,(where_values+1)*sizeof(PetscInt));CHKERRQ(ierr); 2309a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&where_to_nodes_indices);CHKERRQ(ierr); 2310a0ba757dSStefano Zampini /* first count how many neighbours per connected component I will receive from */ 2311a0ba757dSStefano Zampini cum_recv_counts[0]=0; 2312a0ba757dSStefano Zampini for(i=1;i<where_values+1;i++){ 2313a0ba757dSStefano Zampini j=0; 2314a0ba757dSStefano Zampini while(mat_graph->where[j] != i) j++; 2315a0ba757dSStefano Zampini where_to_nodes_indices[i-1]=j; 2316a0ba757dSStefano Zampini if(neighbours_set[j][0]!=-1) { cum_recv_counts[i]=cum_recv_counts[i-1]+mat_graph->count[j]-1; } /* We don't want sends/recvs_to/from_self -> here I don't count myself */ 2317a0ba757dSStefano Zampini else { cum_recv_counts[i]=cum_recv_counts[i-1]+mat_graph->count[j]-2; } 2318a0ba757dSStefano Zampini } 2319a0ba757dSStefano Zampini buffer_size=2*cum_recv_counts[where_values]+mat_graph->nvtxs; 2320a0ba757dSStefano Zampini ierr = PetscMalloc(2*cum_recv_counts[where_values]*sizeof(PetscMPIInt),&recv_buffer_where);CHKERRQ(ierr); 2321a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 2322a0ba757dSStefano Zampini ierr = PetscMalloc(cum_recv_counts[where_values]*sizeof(MPI_Request),&send_requests);CHKERRQ(ierr); 2323a0ba757dSStefano Zampini ierr = PetscMalloc(cum_recv_counts[where_values]*sizeof(MPI_Request),&recv_requests);CHKERRQ(ierr); 2324a0ba757dSStefano Zampini for(i=0;i<cum_recv_counts[where_values];i++) { 2325a0ba757dSStefano Zampini send_requests[i]=MPI_REQUEST_NULL; 2326a0ba757dSStefano Zampini recv_requests[i]=MPI_REQUEST_NULL; 2327a0ba757dSStefano Zampini } 2328a0ba757dSStefano Zampini /* printf("MPI sizes: buffer size for send %d, number of requests %d\n",buffer_size,cum_recv_counts[where_values]); */ 2329a0ba757dSStefano Zampini 2330a0ba757dSStefano Zampini /* exchange with my neighbours the number of my connected components on the shared interface */ 2331a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2332a0ba757dSStefano Zampini j=where_to_nodes_indices[i]; 2333a0ba757dSStefano Zampini k = (neighbours_set[j][0] == -1 ? 1 : 0); 2334a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2335a0ba757dSStefano Zampini if(neighbours_set[j][k] != my_rank) { 2336a0ba757dSStefano 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); 2337a0ba757dSStefano 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); 2338a0ba757dSStefano Zampini /*printf("SENDREQ[%d]: to %d (tag %d) the value %d\n",sum_requests,neighbours_set[j][k],(my_rank+1)*mat_graph->count[j],mat_graph->where_ncmps[i]); 2339a0ba757dSStefano Zampini printf("RECVREQ[%d]: from %d (tag %d) at buffer address %d\n",sum_requests,neighbours_set[j][k],(neighbours_set[j][k]+1)*mat_graph->count[j],sum_requests);*/ 2340a0ba757dSStefano Zampini sum_requests++; 2341a0ba757dSStefano Zampini } 2342a0ba757dSStefano Zampini } 2343a0ba757dSStefano Zampini } 2344a0ba757dSStefano Zampini /* printf("Final number of request: s=r=%d (should be equal to %d)\n",sum_requests,cum_recv_counts[where_values]); */ 2345a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2346a0ba757dSStefano Zampini /*for(i=0;i<where_values;i++){ 2347a0ba757dSStefano Zampini printf("my where_ncmps[%d]=%d\n",i,mat_graph->where_ncmps[i]); 2348a0ba757dSStefano Zampini for(j=cum_recv_counts[i];j<cum_recv_counts[i+1];j++){ 2349a0ba757dSStefano Zampini printf(" recv where_ncmps[%d]=%d\n",j,recv_buffer_where[j]); 2350a0ba757dSStefano Zampini } 2351a0ba757dSStefano Zampini }*/ 2352a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2353a0ba757dSStefano Zampini 2354a0ba757dSStefano Zampini /* determine the connected component I need to adapt */ 2355a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&where_cc_adapt);CHKERRQ(ierr); 2356a0ba757dSStefano Zampini ierr = PetscMemzero(where_cc_adapt,where_values*sizeof(PetscInt));CHKERRQ(ierr); 2357a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2358a0ba757dSStefano Zampini for(j=cum_recv_counts[i];j<cum_recv_counts[i+1];j++){ 2359a0ba757dSStefano Zampini if( mat_graph->where_ncmps[i]!=recv_buffer_where[j] || mat_graph->where_ncmps[i] > 1 ) { /* The first condition is natural (i.e someone has a different number of cc than me), the second one is just to be safe */ 2360a0ba757dSStefano Zampini where_cc_adapt[i]=PETSC_TRUE; 2361a0ba757dSStefano Zampini break; 2362a0ba757dSStefano Zampini } 2363a0ba757dSStefano Zampini } 2364a0ba757dSStefano Zampini } 2365a0ba757dSStefano Zampini /* now get from neighbours their ccs (in global numbering) and adapt them (in case it is needed) */ 2366a0ba757dSStefano Zampini /* first determine how much data to send (size of each queue plus the global indices) and communicate it to neighbours */ 2367a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&sizes_of_sends);CHKERRQ(ierr); 2368a0ba757dSStefano Zampini ierr = PetscMemzero(sizes_of_sends,where_values*sizeof(PetscInt));CHKERRQ(ierr); 2369a0ba757dSStefano Zampini sum_requests=0; 2370a0ba757dSStefano Zampini start_of_send=0; 2371a0ba757dSStefano Zampini start_of_recv=cum_recv_counts[where_values]; 2372a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 2373a0ba757dSStefano Zampini if(where_cc_adapt[i]) { 2374a0ba757dSStefano Zampini size_of_send=0; 2375a0ba757dSStefano Zampini for(j=i;j<mat_graph->ncmps;j++) { 2376a0ba757dSStefano Zampini if(mat_graph->where[mat_graph->queue[mat_graph->cptr[j]]] == i+1) { /* WARNING -> where values goes from 1 to where_values included */ 2377a0ba757dSStefano Zampini send_buffer[start_of_send+size_of_send]=mat_graph->cptr[j+1]-mat_graph->cptr[j]; 2378a0ba757dSStefano Zampini size_of_send+=1; 2379a0ba757dSStefano Zampini for(k=0;k<mat_graph->cptr[j+1]-mat_graph->cptr[j];k++) { 2380a0ba757dSStefano Zampini send_buffer[start_of_send+size_of_send+k]=queue_in_global_numbering[mat_graph->cptr[j]+k]; 2381a0ba757dSStefano Zampini } 2382a0ba757dSStefano Zampini size_of_send=size_of_send+mat_graph->cptr[j+1]-mat_graph->cptr[j]; 2383a0ba757dSStefano Zampini } 2384a0ba757dSStefano Zampini } 2385a0ba757dSStefano Zampini j = where_to_nodes_indices[i]; 2386a0ba757dSStefano Zampini k = (neighbours_set[j][0] == -1 ? 1 : 0); 2387a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2388a0ba757dSStefano Zampini if(neighbours_set[j][k] != my_rank) { 2389a0ba757dSStefano Zampini /* printf("SENDREQ[%d]: to %d (tag %d) the value %d\n",sum_requests,neighbours_set[j][k],(my_rank+1)*mat_graph->count[j],size_of_send); 2390a0ba757dSStefano Zampini printf("RECVREQ[%d]: from %d (tag %d) at buffer address %d\n",sum_requests,neighbours_set[j][k],(neighbours_set[j][k]+1)*mat_graph->count[j],sum_requests+start_of_recv);*/ 2391a0ba757dSStefano 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); 2392a0ba757dSStefano 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); 2393a0ba757dSStefano Zampini sum_requests++; 2394a0ba757dSStefano Zampini } 2395a0ba757dSStefano Zampini } 2396a0ba757dSStefano Zampini sizes_of_sends[i]=size_of_send; 2397a0ba757dSStefano Zampini start_of_send+=size_of_send; 2398a0ba757dSStefano Zampini } 2399a0ba757dSStefano Zampini } 2400a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2401a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2402a0ba757dSStefano Zampini /*j=0; 2403a0ba757dSStefano Zampini for(k=0;k<where_values;k++) { j+=sizes_of_sends[k]; } 2404a0ba757dSStefano Zampini printf("This is the send buffer (size %d): \n",j); 2405a0ba757dSStefano Zampini for(k=0;k<j;k++) { printf("%d ",send_buffer[k]); } 2406a0ba757dSStefano Zampini printf("\n");*/ 2407a0ba757dSStefano Zampini buffer_size=0; 2408a0ba757dSStefano Zampini for(k=0;k<sum_requests;k++) { buffer_size+=recv_buffer_where[start_of_recv+k]; } 2409a0ba757dSStefano Zampini /* printf("Allocating recv buffer of size %d\n",buffer_size); */ 2410a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscMPIInt),&recv_buffer);CHKERRQ(ierr); 2411a0ba757dSStefano Zampini /* now exchange the data */ 2412a0ba757dSStefano Zampini start_of_recv=0; 2413a0ba757dSStefano Zampini start_of_send=0; 2414a0ba757dSStefano Zampini sum_requests=0; 2415a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 2416a0ba757dSStefano Zampini if(where_cc_adapt[i]) { 2417a0ba757dSStefano Zampini size_of_send = sizes_of_sends[i]; 2418a0ba757dSStefano Zampini j = where_to_nodes_indices[i]; 2419a0ba757dSStefano Zampini k = (neighbours_set[j][0] == -1 ? 1 : 0); 2420a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2421a0ba757dSStefano Zampini if(neighbours_set[j][k] != my_rank) { 2422a0ba757dSStefano Zampini /* printf("SENDREQ[%d]: to %d (tag %d) with size %d at buffer address %d\n",sum_requests,neighbours_set[j][k],(my_rank+1)*mat_graph->count[j],size_of_send,start_of_send); 2423a0ba757dSStefano Zampini printf("RECVREQ[%d]: from %d (tag %d) at buffer address %d\n",sum_requests,neighbours_set[j][k],(neighbours_set[j][k]+1)*mat_graph->count[j],start_of_recv); */ 2424a0ba757dSStefano 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); 2425a0ba757dSStefano Zampini size_of_recv=recv_buffer_where[cum_recv_counts[where_values]+sum_requests]; 2426a0ba757dSStefano 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); 2427a0ba757dSStefano Zampini start_of_recv+=size_of_recv; 2428a0ba757dSStefano Zampini sum_requests++; 2429a0ba757dSStefano Zampini } 2430a0ba757dSStefano Zampini } 2431a0ba757dSStefano Zampini start_of_send+=size_of_send; 2432a0ba757dSStefano Zampini } 2433a0ba757dSStefano Zampini } 2434a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2435a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2436a0ba757dSStefano Zampini /*printf("This is what I received (size %d): \n",start_of_recv); 2437a0ba757dSStefano Zampini for(k=0;k<start_of_recv;k++) { printf("%d ",recv_buffer[k]); } 2438a0ba757dSStefano Zampini printf("\n");*/ 2439a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscInt),&petsc_buffer);CHKERRQ(ierr); 2440a0ba757dSStefano Zampini for(k=0;k<start_of_recv;k++) { petsc_buffer[k]=(PetscInt)recv_buffer[k]; } 2441a0ba757dSStefano Zampini for(j=0;j<buffer_size;) { 2442a0ba757dSStefano Zampini ierr = ISGlobalToLocalMappingApply(matis->mapping,IS_GTOLM_MASK,petsc_buffer[j],&petsc_buffer[j+1],&petsc_buffer[j],&petsc_buffer[j+1]);CHKERRQ(ierr); 2443a0ba757dSStefano Zampini k=petsc_buffer[j]+1; 2444a0ba757dSStefano Zampini j+=k; 2445a0ba757dSStefano Zampini } 2446a0ba757dSStefano Zampini /*printf("This is what I received in local numbering (unrolled): \n"); 2447a0ba757dSStefano Zampini i=0; 2448a0ba757dSStefano Zampini for(j=0;j<buffer_size;) { 2449a0ba757dSStefano Zampini printf("queue num %d (j=%d)\n",i,j); 2450a0ba757dSStefano Zampini for(k=1;k<petsc_buffer[j]+1;k++) { printf("%d ",petsc_buffer[k+j]); } 2451a0ba757dSStefano Zampini printf("\n"); 2452a0ba757dSStefano Zampini i++;j+=k; 2453a0ba757dSStefano Zampini }*/ 2454a0ba757dSStefano Zampini sum_requests=cum_recv_counts[where_values]; 2455a0ba757dSStefano Zampini start_of_recv=0; 2456a0ba757dSStefano Zampini ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt),&nodes_to_temp_buffer_indices);CHKERRQ(ierr); 2457a0ba757dSStefano Zampini global_where_counter=0; 2458a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2459a0ba757dSStefano Zampini if(where_cc_adapt[i]){ 2460a0ba757dSStefano Zampini temp_buffer_size=0; 2461a0ba757dSStefano Zampini /* find nodes on the shared interface we need to adapt */ 2462a0ba757dSStefano Zampini for(j=0;j<mat_graph->nvtxs;j++){ 2463a0ba757dSStefano Zampini if(mat_graph->where[j]==i+1) { 2464a0ba757dSStefano Zampini nodes_to_temp_buffer_indices[j]=temp_buffer_size; 2465a0ba757dSStefano Zampini temp_buffer_size++; 2466a0ba757dSStefano Zampini } else { 2467a0ba757dSStefano Zampini nodes_to_temp_buffer_indices[j]=-1; 2468a0ba757dSStefano Zampini } 2469a0ba757dSStefano Zampini } 2470a0ba757dSStefano Zampini /* allocate some temporary space */ 2471a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*sizeof(PetscInt*),&temp_buffer);CHKERRQ(ierr); 2472a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*(cum_recv_counts[i+1]-cum_recv_counts[i])*sizeof(PetscInt),&temp_buffer[0]);CHKERRQ(ierr); 2473a0ba757dSStefano Zampini ierr = PetscMemzero(temp_buffer[0],temp_buffer_size*(cum_recv_counts[i+1]-cum_recv_counts[i])*sizeof(PetscInt));CHKERRQ(ierr); 2474a0ba757dSStefano Zampini for(j=1;j<temp_buffer_size;j++){ 2475a0ba757dSStefano Zampini temp_buffer[j]=temp_buffer[j-1]+cum_recv_counts[i+1]-cum_recv_counts[i]; 2476a0ba757dSStefano Zampini } 2477a0ba757dSStefano Zampini /* analyze contributions from neighbouring subdomains for i-th conn comp 2478a0ba757dSStefano Zampini temp buffer structure: 2479a0ba757dSStefano Zampini supposing part of the interface has dimension 5 (global nodes 0,1,2,3,4) 2480a0ba757dSStefano Zampini 3 neighs procs with structured connected components: 2481a0ba757dSStefano Zampini neigh 0: [0 1 4], [2 3]; (2 connected components) 2482a0ba757dSStefano Zampini neigh 1: [0 1], [2 3 4]; (2 connected components) 2483a0ba757dSStefano Zampini neigh 2: [0 4], [1], [2 3]; (3 connected components) 2484a0ba757dSStefano Zampini tempbuffer (row-oriented) should be filled as: 2485a0ba757dSStefano Zampini [ 0, 0, 0; 2486a0ba757dSStefano Zampini 0, 0, 1; 2487a0ba757dSStefano Zampini 1, 1, 2; 2488a0ba757dSStefano Zampini 1, 1, 2; 2489a0ba757dSStefano Zampini 0, 1, 0; ]; 2490a0ba757dSStefano Zampini This way we can simply recover the resulting structure account for possible intersections of ccs among neighs. 2491a0ba757dSStefano Zampini The mat_graph->where array will be modified to reproduce the following 4 connected components [0], [1], [2 3], [4]; 2492a0ba757dSStefano Zampini */ 2493a0ba757dSStefano Zampini for(j=0;j<cum_recv_counts[i+1]-cum_recv_counts[i];j++) { 2494a0ba757dSStefano Zampini ins_val=0; 2495a0ba757dSStefano Zampini size_of_recv=recv_buffer_where[sum_requests]; /* total size of recv from neighs */ 2496a0ba757dSStefano Zampini for(buffer_size=0;buffer_size<size_of_recv;) { /* loop until all data from neighs has been taken into account */ 2497a0ba757dSStefano Zampini for(k=1;k<petsc_buffer[buffer_size+start_of_recv]+1;k++) { /* filling properly temp_buffer using data from a single recv */ 2498a0ba757dSStefano Zampini temp_buffer[ nodes_to_temp_buffer_indices[ petsc_buffer[ start_of_recv+buffer_size+k ] ] ][j]=ins_val; 2499a0ba757dSStefano Zampini } 2500a0ba757dSStefano Zampini buffer_size+=k; 2501a0ba757dSStefano Zampini ins_val++; 2502a0ba757dSStefano Zampini } 2503a0ba757dSStefano Zampini start_of_recv+=size_of_recv; 2504a0ba757dSStefano Zampini sum_requests++; 2505a0ba757dSStefano Zampini } 2506a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*sizeof(PetscInt),&add_to_where);CHKERRQ(ierr); 2507a0ba757dSStefano Zampini ierr = PetscMemzero(add_to_where,temp_buffer_size*sizeof(PetscInt));CHKERRQ(ierr); 2508a0ba757dSStefano Zampini for(j=0;j<temp_buffer_size;j++){ 2509a0ba757dSStefano Zampini if(!add_to_where[j]){ /* found a new cc */ 2510a0ba757dSStefano Zampini global_where_counter++; 2511a0ba757dSStefano Zampini add_to_where[j]=global_where_counter; 2512a0ba757dSStefano Zampini for(k=j+1;k<temp_buffer_size;k++){ /* check for other nodes in new cc */ 2513a0ba757dSStefano Zampini same_set=PETSC_TRUE; 2514a0ba757dSStefano Zampini for(s=0;s<cum_recv_counts[i+1]-cum_recv_counts[i];s++){ 2515a0ba757dSStefano Zampini if(temp_buffer[j][s]!=temp_buffer[k][s]) { 2516a0ba757dSStefano Zampini same_set=PETSC_FALSE; 2517a0ba757dSStefano Zampini break; 2518a0ba757dSStefano Zampini } 2519a0ba757dSStefano Zampini } 2520a0ba757dSStefano Zampini if(same_set) add_to_where[k]=global_where_counter; 2521a0ba757dSStefano Zampini } 2522a0ba757dSStefano Zampini } 2523a0ba757dSStefano Zampini } 2524a0ba757dSStefano Zampini /* insert new data in where array */ 2525a0ba757dSStefano Zampini temp_buffer_size=0; 2526a0ba757dSStefano Zampini for(j=0;j<mat_graph->nvtxs;j++){ 2527a0ba757dSStefano Zampini if(mat_graph->where[j]==i+1) { 2528a0ba757dSStefano Zampini mat_graph->where[j]=where_values+add_to_where[temp_buffer_size]; 2529a0ba757dSStefano Zampini temp_buffer_size++; 2530a0ba757dSStefano Zampini } 2531a0ba757dSStefano Zampini } 2532a0ba757dSStefano Zampini ierr = PetscFree(temp_buffer[0]);CHKERRQ(ierr); 2533a0ba757dSStefano Zampini ierr = PetscFree(temp_buffer);CHKERRQ(ierr); 2534a0ba757dSStefano Zampini ierr = PetscFree(add_to_where);CHKERRQ(ierr); 2535a0ba757dSStefano Zampini } 2536a0ba757dSStefano Zampini } 2537a0ba757dSStefano Zampini ierr = PetscFree(nodes_to_temp_buffer_indices);CHKERRQ(ierr); 2538a0ba757dSStefano Zampini ierr = PetscFree(sizes_of_sends);CHKERRQ(ierr); 2539a0ba757dSStefano Zampini ierr = PetscFree(send_requests);CHKERRQ(ierr); 2540a0ba757dSStefano Zampini ierr = PetscFree(recv_requests);CHKERRQ(ierr); 2541a0ba757dSStefano Zampini ierr = PetscFree(petsc_buffer);CHKERRQ(ierr); 2542a0ba757dSStefano Zampini ierr = PetscFree(recv_buffer);CHKERRQ(ierr); 2543a0ba757dSStefano Zampini ierr = PetscFree(recv_buffer_where);CHKERRQ(ierr); 2544a0ba757dSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 2545a0ba757dSStefano Zampini ierr = PetscFree(cum_recv_counts);CHKERRQ(ierr); 2546a0ba757dSStefano Zampini ierr = PetscFree(where_to_nodes_indices);CHKERRQ(ierr); 2547a0ba757dSStefano Zampini /* We are ready to evaluate consistent connected components on each part of the shared interface */ 2548a0ba757dSStefano Zampini if(global_where_counter) { 2549a0ba757dSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){ mat_graph->touched[i]=PETSC_FALSE; } 2550a0ba757dSStefano Zampini global_where_counter=0; 2551a0ba757dSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){ 2552a0ba757dSStefano Zampini if(mat_graph->where[i] && !mat_graph->touched[i]) { 2553a0ba757dSStefano Zampini global_where_counter++; 2554a0ba757dSStefano Zampini for(j=i+1;j<mat_graph->nvtxs;j++){ 2555a0ba757dSStefano Zampini if(!mat_graph->touched[j] && mat_graph->where[j]==mat_graph->where[i]) { 2556a0ba757dSStefano Zampini mat_graph->where[j]=global_where_counter; 2557a0ba757dSStefano Zampini mat_graph->touched[j]=PETSC_TRUE; 2558a0ba757dSStefano Zampini } 2559a0ba757dSStefano Zampini } 2560a0ba757dSStefano Zampini mat_graph->where[i]=global_where_counter; 2561a0ba757dSStefano Zampini mat_graph->touched[i]=PETSC_TRUE; 2562a0ba757dSStefano Zampini } 2563a0ba757dSStefano Zampini } 2564a0ba757dSStefano Zampini where_values=global_where_counter; 2565a0ba757dSStefano Zampini } 2566a0ba757dSStefano Zampini if(global_where_counter) { 2567a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->cptr,(mat_graph->nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 2568a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->queue,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2569a0ba757dSStefano Zampini ierr = PetscFree(mat_graph->where_ncmps);CHKERRQ(ierr); 2570a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscMPIInt),&mat_graph->where_ncmps);CHKERRQ(ierr); 2571a0ba757dSStefano Zampini ierr = PCBDDCFindConnectedComponents(mat_graph, where_values); 2572a0ba757dSStefano Zampini for(i=0;i<mat_graph->ncmps;i++) { 2573a0ba757dSStefano 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); 2574a0ba757dSStefano 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); 2575a0ba757dSStefano Zampini } 2576a0ba757dSStefano Zampini } 25770c7d97c5SJed Brown } 25780c7d97c5SJed Brown 2579a0ba757dSStefano Zampini /* count vertices, edges and faces */ 25800c7d97c5SJed Brown PetscInt nfc=0; 25810c7d97c5SJed Brown PetscInt nec=0; 25820c7d97c5SJed Brown PetscInt nvc=0; 25830c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 25840c7d97c5SJed Brown if( !pcbddc->vertices_flag ) { 25850c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > 1 ){ 25860c7d97c5SJed Brown if(mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]==2){ 25870c7d97c5SJed Brown nfc++; 25880c7d97c5SJed Brown } else { 25890c7d97c5SJed Brown nec++; 25900c7d97c5SJed Brown } 25910c7d97c5SJed Brown } 25920c7d97c5SJed Brown } 25930c7d97c5SJed Brown if( !pcbddc->constraints_flag ){ 25940c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] == 1 ){ 25950c7d97c5SJed Brown nvc++; 25960c7d97c5SJed Brown } 25970c7d97c5SJed Brown } 25980c7d97c5SJed Brown } 25990c7d97c5SJed Brown 26000c7d97c5SJed Brown pcbddc->n_constraints = nec+nfc; 26010c7d97c5SJed Brown pcbddc->n_vertices = nvc; 26020c7d97c5SJed Brown 26030c7d97c5SJed Brown if(pcbddc->n_constraints){ 26040c7d97c5SJed Brown /* allocate space for local constraints of BDDC */ 26050c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->n_constraints*sizeof(PetscInt*),&pcbddc->indices_to_constraint);CHKERRQ(ierr); 26060c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->n_constraints*sizeof(PetscScalar*),&pcbddc->quadrature_constraint);CHKERRQ(ierr); 26070c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->n_constraints*sizeof(PetscInt),&pcbddc->sizes_of_constraint);CHKERRQ(ierr); 26080c7d97c5SJed Brown k=0; 26090c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 26100c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > 1 ){ 26110c7d97c5SJed Brown pcbddc->sizes_of_constraint[k] = mat_graph->cptr[i+1]-mat_graph->cptr[i]; 26120c7d97c5SJed Brown k++; 26130c7d97c5SJed Brown } 26140c7d97c5SJed Brown } 26150c7d97c5SJed Brown k=0; 26160c7d97c5SJed Brown for (i=0; i<pcbddc->n_constraints; i++) k+=pcbddc->sizes_of_constraint[i]; 26170c7d97c5SJed Brown ierr = PetscMalloc (k*sizeof(PetscInt),&pcbddc->indices_to_constraint[0]);CHKERRQ(ierr); 26180c7d97c5SJed Brown ierr = PetscMalloc (k*sizeof(PetscScalar),&pcbddc->quadrature_constraint[0]);CHKERRQ(ierr); 26190c7d97c5SJed Brown for (i=1; i<pcbddc->n_constraints; i++) { 26200c7d97c5SJed Brown pcbddc->indices_to_constraint[i] = pcbddc->indices_to_constraint[i-1] + pcbddc->sizes_of_constraint[i-1]; 26210c7d97c5SJed Brown pcbddc->quadrature_constraint[i] = pcbddc->quadrature_constraint[i-1] + pcbddc->sizes_of_constraint[i-1]; 26220c7d97c5SJed Brown } 26230c7d97c5SJed Brown k=0; 26240c7d97c5SJed Brown PetscScalar quad_value; 26250c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 26260c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > 1 ){ 2627a0ba757dSStefano Zampini quad_value=1.0/( (PetscReal) (mat_graph->cptr[i+1]-mat_graph->cptr[i]) ); 26280c7d97c5SJed Brown for(j=0;j<mat_graph->cptr[i+1]-mat_graph->cptr[i];j++) { 26290c7d97c5SJed Brown pcbddc->indices_to_constraint[k][j] = mat_graph->queue[mat_graph->cptr[i]+j]; 26300c7d97c5SJed Brown pcbddc->quadrature_constraint[k][j] = quad_value; 26310c7d97c5SJed Brown } 26320c7d97c5SJed Brown k++; 26330c7d97c5SJed Brown } 26340c7d97c5SJed Brown } 26350c7d97c5SJed Brown } 26360c7d97c5SJed Brown if(pcbddc->n_vertices){ 26370c7d97c5SJed Brown /* allocate space for local vertices of BDDC */ 26380c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->n_vertices*sizeof(PetscInt),&pcbddc->vertices);CHKERRQ(ierr); 26390c7d97c5SJed Brown k=0; 26400c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 26410c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] == 1 ){ 26420c7d97c5SJed Brown pcbddc->vertices[k] = mat_graph->queue[mat_graph->cptr[i]]; 26430c7d97c5SJed Brown k++; 26440c7d97c5SJed Brown } 26450c7d97c5SJed Brown } 2646a0ba757dSStefano Zampini /* sort vertex set (by local ordering) */ 26470c7d97c5SJed Brown ierr = PetscSortInt(pcbddc->n_vertices,pcbddc->vertices);CHKERRQ(ierr); 26480c7d97c5SJed Brown } 26490c7d97c5SJed Brown 2650e269702eSStefano Zampini if(pcbddc->dbg_flag) { 2651e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 2652e269702eSStefano Zampini 2653d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2654d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Details from PCBDDCManageLocalBoundaries for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 2655d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2656a0ba757dSStefano Zampini /* ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Graph (adjacency structure) of local Neumann mat\n");CHKERRQ(ierr); 2657a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2658e269702eSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++) { 2659a0ba757dSStefano 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); 2660e269702eSStefano Zampini for(j=mat_graph->xadj[i];j<mat_graph->xadj[i+1];j++){ 2661a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d ",mat_graph->adjncy[j]);CHKERRQ(ierr); 2662e269702eSStefano Zampini } 2663a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n--------------------------------------------------------------\n");CHKERRQ(ierr); 2664a0ba757dSStefano Zampini }*/ 2665d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Matrix graph has %d connected components", mat_graph->ncmps);CHKERRQ(ierr); 26660c7d97c5SJed Brown for(i=0;i<mat_graph->ncmps;i++) { 2667d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\nSize and count for connected component %02d : %04d %01d\n", i,mat_graph->cptr[i+1]-mat_graph->cptr[i],mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]);CHKERRQ(ierr); 26680c7d97c5SJed Brown for (j=mat_graph->cptr[i]; j<mat_graph->cptr[i+1]; j++){ 26693828260eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d (%d), ",queue_in_global_numbering[j],mat_graph->queue[j]);CHKERRQ(ierr); 26700c7d97c5SJed Brown } 26710c7d97c5SJed Brown } 2672d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n--------------------------------------------------------------\n");CHKERRQ(ierr); 2673d49ef151SStefano Zampini if( pcbddc->n_vertices ) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local vertices\n",PetscGlobalRank,pcbddc->n_vertices);CHKERRQ(ierr); } 2674d49ef151SStefano Zampini if( nfc ) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local faces\n",PetscGlobalRank,nfc);CHKERRQ(ierr); } 2675d49ef151SStefano Zampini if( nec ) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local edges\n",PetscGlobalRank,nec);CHKERRQ(ierr); } 2676a0ba757dSStefano Zampini if( pcbddc->n_vertices ) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Global indices for subdomain vertices follows\n",PetscGlobalRank,pcbddc->n_vertices);CHKERRQ(ierr); } 26773828260eSStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,pcbddc->n_vertices,pcbddc->vertices,queue_in_global_numbering);CHKERRQ(ierr); 26783828260eSStefano Zampini for(i=0;i<pcbddc->n_vertices;i++){ ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d ",queue_in_global_numbering[i]);CHKERRQ(ierr); } 2679d49ef151SStefano Zampini if( pcbddc->n_vertices ) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); } 2680d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 26810c7d97c5SJed Brown } 26820c7d97c5SJed Brown 2683a0ba757dSStefano Zampini /* Restore CSR structure into sequantial matrix and free memory space no longer needed */ 2684a0ba757dSStefano Zampini ierr = MatRestoreRowIJ(mat_adj,0,symmetrize_rowij,compressed_rowij,&mat_graph->nvtxs,&mat_graph->xadj,&mat_graph->adjncy,&flg_row);CHKERRQ(ierr); 26850c7d97c5SJed Brown if(!flg_row) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called from PCBDDCManageLocalBoundaries.\n"); 2686a0ba757dSStefano Zampini ierr = MatDestroy(&mat_adj);CHKERRQ(ierr); 2687a0ba757dSStefano Zampini /* Free graph structure */ 26880c7d97c5SJed Brown if(mat_graph->nvtxs){ 2689a0ba757dSStefano Zampini ierr = PetscFree(neighbours_set[0]);CHKERRQ(ierr); 2690a0ba757dSStefano Zampini ierr = PetscFree(neighbours_set);CHKERRQ(ierr); 2691a0ba757dSStefano Zampini ierr = PetscFree4(mat_graph->where,mat_graph->count,mat_graph->cptr,mat_graph->queue);CHKERRQ(ierr); 2692a0ba757dSStefano Zampini ierr = PetscFree3(mat_graph->which_dof,mat_graph->touched,queue_in_global_numbering);CHKERRQ(ierr); 2693a0ba757dSStefano Zampini ierr = PetscFree(mat_graph->where_ncmps);CHKERRQ(ierr); 26940c7d97c5SJed Brown } 26950c7d97c5SJed Brown ierr = PetscFree(mat_graph);CHKERRQ(ierr); 26960c7d97c5SJed Brown 26970c7d97c5SJed Brown PetscFunctionReturn(0); 26980c7d97c5SJed Brown 26990c7d97c5SJed Brown } 27000c7d97c5SJed Brown 27010c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 27020c7d97c5SJed Brown 27030c7d97c5SJed Brown /* The following code has been adapted from function IsConnectedSubdomain contained 27040c7d97c5SJed Brown in source file contig.c of METIS library (version 5.0.1) */ 27050c7d97c5SJed Brown 27060c7d97c5SJed Brown #undef __FUNCT__ 27070c7d97c5SJed Brown #define __FUNCT__ "PCBDDCFindConnectedComponents" 2708a0ba757dSStefano Zampini static PetscErrorCode PCBDDCFindConnectedComponents(PCBDDCGraph graph, PetscInt n_dist )//, PetscInt *dist_vals) 27090c7d97c5SJed Brown { 27100c7d97c5SJed Brown PetscInt i, j, k, nvtxs, first, last, nleft, ncmps,pid,cum_queue,n,ncmps_pid; 27110c7d97c5SJed Brown PetscInt *xadj, *adjncy, *where, *queue; 27120c7d97c5SJed Brown PetscInt *cptr; 27130c7d97c5SJed Brown PetscBool *touched; 27140c7d97c5SJed Brown 27150c7d97c5SJed Brown PetscFunctionBegin; 27160c7d97c5SJed Brown 27170c7d97c5SJed Brown nvtxs = graph->nvtxs; 27180c7d97c5SJed Brown xadj = graph->xadj; 27190c7d97c5SJed Brown adjncy = graph->adjncy; 27200c7d97c5SJed Brown where = graph->where; 27210c7d97c5SJed Brown touched = graph->touched; 27220c7d97c5SJed Brown queue = graph->queue; 27230c7d97c5SJed Brown cptr = graph->cptr; 27240c7d97c5SJed Brown 27250c7d97c5SJed Brown for (i=0; i<nvtxs; i++) 27260c7d97c5SJed Brown touched[i] = PETSC_FALSE; 27270c7d97c5SJed Brown 27280c7d97c5SJed Brown cum_queue=0; 27290c7d97c5SJed Brown ncmps=0; 27300c7d97c5SJed Brown 27310c7d97c5SJed Brown for(n=0; n<n_dist; n++) { 2732a0ba757dSStefano Zampini //pid = dist_vals[n]; 2733a0ba757dSStefano Zampini pid = n+1; 27340c7d97c5SJed Brown nleft = 0; 27350c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 27360c7d97c5SJed Brown if (where[i] == pid) 27370c7d97c5SJed Brown nleft++; 27380c7d97c5SJed Brown } 27390c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 27400c7d97c5SJed Brown if (where[i] == pid) 27410c7d97c5SJed Brown break; 27420c7d97c5SJed Brown } 27430c7d97c5SJed Brown touched[i] = PETSC_TRUE; 27440c7d97c5SJed Brown queue[cum_queue] = i; 27450c7d97c5SJed Brown first = 0; last = 1; 27460c7d97c5SJed Brown cptr[ncmps] = cum_queue; /* This actually points to queue */ 27470c7d97c5SJed Brown ncmps_pid = 0; 27480c7d97c5SJed Brown while (first != nleft) { 27490c7d97c5SJed Brown if (first == last) { /* Find another starting vertex */ 27500c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 27510c7d97c5SJed Brown ncmps_pid++; 27520c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 27530c7d97c5SJed Brown if (where[i] == pid && !touched[i]) 27540c7d97c5SJed Brown break; 27550c7d97c5SJed Brown } 27560c7d97c5SJed Brown queue[cum_queue+last] = i; 27570c7d97c5SJed Brown last++; 27580c7d97c5SJed Brown touched[i] = PETSC_TRUE; 27590c7d97c5SJed Brown } 27600c7d97c5SJed Brown i = queue[cum_queue+first]; 27610c7d97c5SJed Brown first++; 27620c7d97c5SJed Brown for (j=xadj[i]; j<xadj[i+1]; j++) { 27630c7d97c5SJed Brown k = adjncy[j]; 27640c7d97c5SJed Brown if (where[k] == pid && !touched[k]) { 27650c7d97c5SJed Brown queue[cum_queue+last] = k; 27660c7d97c5SJed Brown last++; 27670c7d97c5SJed Brown touched[k] = PETSC_TRUE; 27680c7d97c5SJed Brown } 27690c7d97c5SJed Brown } 27700c7d97c5SJed Brown } 27710c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 27720c7d97c5SJed Brown ncmps_pid++; 27730c7d97c5SJed Brown cum_queue=cptr[ncmps]; 2774a0ba757dSStefano Zampini graph->where_ncmps[n] = ncmps_pid; 27750c7d97c5SJed Brown } 27760c7d97c5SJed Brown graph->ncmps = ncmps; 27770c7d97c5SJed Brown 27780c7d97c5SJed Brown PetscFunctionReturn(0); 27790c7d97c5SJed Brown } 27800c7d97c5SJed Brown 2781