153cdbc3dSStefano Zampini /* TODOLIST 2*da1bb401SStefano Zampini DofSplitting and DM attached to pc? 3*da1bb401SStefano Zampini Change SetNeumannBoundaries to SetNeumannBoundariesLocal and provide new SetNeumannBoundaries (same Dirichlet) 4*da1bb401SStefano Zampini Exact solvers: Solve local saddle point directly 5831a100dSStefano Zampini - change prec_type to switch_inexact_prec_type 6831a100dSStefano Zampini - add bool solve_exact_saddle_point slot to pdbddc data 73b03a366Sstefano_zampini Inexact solvers: global preconditioner application is ready, ask to developers (Jed?) on how to best implement Dohrmann's approach (PCSHELL?) 8a0ba757dSStefano Zampini change how to deal with the coarse problem (PCBDDCSetCoarseEnvironment): 9a0ba757dSStefano Zampini - mind the problem with coarsening_factor 10a0ba757dSStefano Zampini - simplify coarse problem structure -> PCBDDC or PCREDUDANT, nothing else -> same comm for all levels? 11a0ba757dSStefano Zampini - remove coarse enums and allow use of PCBDDCGetCoarseKSP 12a0ba757dSStefano Zampini - remove metis dependency -> use MatPartitioning for multilevel -> Assemble serial adjacency in ManageLocalBoundaries? 133b03a366Sstefano_zampini - Add levels' slot to bddc data structure and associated Set/Get functions 14a0ba757dSStefano Zampini code refactoring: 15a0ba757dSStefano Zampini - pick up better names for static functions 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 man pages 2153cdbc3dSStefano Zampini */ 220c7d97c5SJed Brown 2353cdbc3dSStefano Zampini /* ---------------------------------------------------------------------------------------------------------------------------------------------- 240c7d97c5SJed Brown Implementation of BDDC preconditioner based on: 250c7d97c5SJed Brown C. Dohrmann "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 2653cdbc3dSStefano Zampini ---------------------------------------------------------------------------------------------------------------------------------------------- */ 2753cdbc3dSStefano Zampini 2853cdbc3dSStefano Zampini #include "bddc.h" /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 293b03a366Sstefano_zampini #include <petscblaslapack.h> 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 */ 44*da1bb401SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_vertices_only" ,"Use only vertices in coarse space (i.e. discard constraints)","none",pcbddc->vertices_flag ,&pcbddc->vertices_flag ,PETSC_NULL);CHKERRQ(ierr); 45*da1bb401SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_constraints_only","Use only constraints in coarse space (i.e. discard vertices)","none",pcbddc->constraints_flag,&pcbddc->constraints_flag,PETSC_NULL);CHKERRQ(ierr); 46*da1bb401SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_faces_only" ,"Use only faces among constraints of coarse space (i.e. discard edges)" ,"none",pcbddc->faces_flag ,&pcbddc->faces_flag ,PETSC_NULL);CHKERRQ(ierr); 47*da1bb401SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_edges_only" ,"Use only edges among constraints of coarse space (i.e. discard faces)" ,"none",pcbddc->edges_flag ,&pcbddc->edges_flag ,PETSC_NULL);CHKERRQ(ierr); 480c7d97c5SJed Brown /* Coarse solver context */ 49*da1bb401SStefano Zampini 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 EXTERN_C_BEGIN 590c7d97c5SJed Brown #undef __FUNCT__ 600c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType_BDDC" 6153cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetCoarseProblemType_BDDC(PC pc, CoarseProblemType CPT) 620c7d97c5SJed Brown { 630c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 640c7d97c5SJed Brown 650c7d97c5SJed Brown PetscFunctionBegin; 660c7d97c5SJed Brown pcbddc->coarse_problem_type = CPT; 670c7d97c5SJed Brown PetscFunctionReturn(0); 680c7d97c5SJed Brown } 690c7d97c5SJed Brown EXTERN_C_END 700c7d97c5SJed Brown #undef __FUNCT__ 710c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType" 7253cdbc3dSStefano Zampini /*@ 739c0446d6SStefano Zampini PCBDDCSetCoarseProblemType - Set coarse problem type in PCBDDC. 7453cdbc3dSStefano Zampini 759c0446d6SStefano Zampini Not collective 7653cdbc3dSStefano Zampini 7753cdbc3dSStefano Zampini Input Parameters: 7853cdbc3dSStefano Zampini + pc - the preconditioning context 7953cdbc3dSStefano Zampini - CoarseProblemType - pick a better name and explain what this is 8053cdbc3dSStefano Zampini 8153cdbc3dSStefano Zampini Level: intermediate 8253cdbc3dSStefano Zampini 8353cdbc3dSStefano Zampini Notes: 84*da1bb401SStefano Zampini Not collective but all procs must call with same arguments. 8553cdbc3dSStefano Zampini 8653cdbc3dSStefano Zampini .seealso: PCBDDC 8753cdbc3dSStefano Zampini @*/ 880c7d97c5SJed Brown PetscErrorCode PCBDDCSetCoarseProblemType(PC pc, CoarseProblemType CPT) 890c7d97c5SJed Brown { 900c7d97c5SJed Brown PetscErrorCode ierr; 910c7d97c5SJed Brown 920c7d97c5SJed Brown PetscFunctionBegin; 930c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 940c7d97c5SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetCoarseProblemType_C",(PC,CoarseProblemType),(pc,CPT));CHKERRQ(ierr); 950c7d97c5SJed Brown PetscFunctionReturn(0); 960c7d97c5SJed Brown } 970c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 980c7d97c5SJed Brown EXTERN_C_BEGIN 990c7d97c5SJed Brown #undef __FUNCT__ 1003b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC" 1013b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 1023b03a366Sstefano_zampini { 1033b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1043b03a366Sstefano_zampini PetscErrorCode ierr; 1053b03a366Sstefano_zampini 1063b03a366Sstefano_zampini PetscFunctionBegin; 1073b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 10836e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 10936e030ebSStefano Zampini pcbddc->DirichletBoundaries=DirichletBoundaries; 1103b03a366Sstefano_zampini PetscFunctionReturn(0); 1113b03a366Sstefano_zampini } 1123b03a366Sstefano_zampini EXTERN_C_END 1133b03a366Sstefano_zampini #undef __FUNCT__ 1143b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries" 1153b03a366Sstefano_zampini /*@ 116*da1bb401SStefano Zampini PCBDDCSetDirichletBoundaries - Set index set defining subdomain part (in local ordering) 117*da1bb401SStefano Zampini of Dirichlet boundaries for the global problem. 1183b03a366Sstefano_zampini 1193b03a366Sstefano_zampini Not collective 1203b03a366Sstefano_zampini 1213b03a366Sstefano_zampini Input Parameters: 1223b03a366Sstefano_zampini + pc - the preconditioning context 1233b03a366Sstefano_zampini - DirichletBoundaries - sequential index set defining the subdomain part of Dirichlet boundaries (can be PETSC_NULL) 1243b03a366Sstefano_zampini 1253b03a366Sstefano_zampini Level: intermediate 1263b03a366Sstefano_zampini 1273b03a366Sstefano_zampini Notes: 1283b03a366Sstefano_zampini 1293b03a366Sstefano_zampini .seealso: PCBDDC 1303b03a366Sstefano_zampini @*/ 1313b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 1323b03a366Sstefano_zampini { 1333b03a366Sstefano_zampini PetscErrorCode ierr; 1343b03a366Sstefano_zampini 1353b03a366Sstefano_zampini PetscFunctionBegin; 1363b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1373b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 1383b03a366Sstefano_zampini PetscFunctionReturn(0); 1393b03a366Sstefano_zampini } 1403b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 1413b03a366Sstefano_zampini EXTERN_C_BEGIN 1423b03a366Sstefano_zampini #undef __FUNCT__ 1430c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 14453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 1450c7d97c5SJed Brown { 1460c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 14753cdbc3dSStefano Zampini PetscErrorCode ierr; 1480c7d97c5SJed Brown 1490c7d97c5SJed Brown PetscFunctionBegin; 15053cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 15136e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 15236e030ebSStefano Zampini pcbddc->NeumannBoundaries=NeumannBoundaries; 1530c7d97c5SJed Brown PetscFunctionReturn(0); 1540c7d97c5SJed Brown } 1550c7d97c5SJed Brown EXTERN_C_END 1560c7d97c5SJed Brown #undef __FUNCT__ 1570c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 15857527edcSJed Brown /*@ 159*da1bb401SStefano Zampini PCBDDCSetNeumannBoundaries - Set index set defining subdomain part (in local ordering) 160*da1bb401SStefano Zampini of Neumann boundaries for the global problem. 16157527edcSJed Brown 1629c0446d6SStefano Zampini Not collective 16357527edcSJed Brown 16457527edcSJed Brown Input Parameters: 16557527edcSJed Brown + pc - the preconditioning context 1669c0446d6SStefano Zampini - NeumannBoundaries - sequential index set defining the subdomain part of Neumann boundaries (can be PETSC_NULL) 16757527edcSJed Brown 16857527edcSJed Brown Level: intermediate 16957527edcSJed Brown 17057527edcSJed Brown Notes: 17157527edcSJed Brown 17257527edcSJed Brown .seealso: PCBDDC 17357527edcSJed Brown @*/ 17453cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 1750c7d97c5SJed Brown { 1760c7d97c5SJed Brown PetscErrorCode ierr; 1770c7d97c5SJed Brown 1780c7d97c5SJed Brown PetscFunctionBegin; 1790c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 18053cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 18153cdbc3dSStefano Zampini PetscFunctionReturn(0); 18253cdbc3dSStefano Zampini } 18353cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 18453cdbc3dSStefano Zampini EXTERN_C_BEGIN 18553cdbc3dSStefano Zampini #undef __FUNCT__ 186*da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC" 187*da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 188*da1bb401SStefano Zampini { 189*da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 190*da1bb401SStefano Zampini 191*da1bb401SStefano Zampini PetscFunctionBegin; 192*da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 193*da1bb401SStefano Zampini PetscFunctionReturn(0); 194*da1bb401SStefano Zampini } 195*da1bb401SStefano Zampini EXTERN_C_END 196*da1bb401SStefano Zampini #undef __FUNCT__ 197*da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries" 198*da1bb401SStefano Zampini /*@ 199*da1bb401SStefano Zampini PCBDDCGetDirichletBoundaries - Get index set defining subdomain part (in local ordering) 200*da1bb401SStefano Zampini of Dirichlet boundaries for the global problem. 201*da1bb401SStefano Zampini 202*da1bb401SStefano Zampini Not collective 203*da1bb401SStefano Zampini 204*da1bb401SStefano Zampini Input Parameters: 205*da1bb401SStefano Zampini + pc - the preconditioning context 206*da1bb401SStefano Zampini 207*da1bb401SStefano Zampini Output Parameters: 208*da1bb401SStefano Zampini + DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 209*da1bb401SStefano Zampini 210*da1bb401SStefano Zampini Level: intermediate 211*da1bb401SStefano Zampini 212*da1bb401SStefano Zampini Notes: 213*da1bb401SStefano Zampini 214*da1bb401SStefano Zampini .seealso: PCBDDC 215*da1bb401SStefano Zampini @*/ 216*da1bb401SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 217*da1bb401SStefano Zampini { 218*da1bb401SStefano Zampini PetscErrorCode ierr; 219*da1bb401SStefano Zampini 220*da1bb401SStefano Zampini PetscFunctionBegin; 221*da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 222*da1bb401SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 223*da1bb401SStefano Zampini PetscFunctionReturn(0); 224*da1bb401SStefano Zampini } 225*da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 226*da1bb401SStefano Zampini EXTERN_C_BEGIN 227*da1bb401SStefano Zampini #undef __FUNCT__ 22853cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 22953cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 23053cdbc3dSStefano Zampini { 23153cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 23253cdbc3dSStefano Zampini 23353cdbc3dSStefano Zampini PetscFunctionBegin; 23453cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 23553cdbc3dSStefano Zampini PetscFunctionReturn(0); 23653cdbc3dSStefano Zampini } 23753cdbc3dSStefano Zampini EXTERN_C_END 23853cdbc3dSStefano Zampini #undef __FUNCT__ 23953cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 24053cdbc3dSStefano Zampini /*@ 241*da1bb401SStefano Zampini PCBDDCGetNeumannBoundaries - Get index set defining subdomain part (in local ordering) 242*da1bb401SStefano Zampini of Neumann boundaries for the global problem. 24353cdbc3dSStefano Zampini 2449c0446d6SStefano Zampini Not collective 24553cdbc3dSStefano Zampini 24653cdbc3dSStefano Zampini Input Parameters: 24753cdbc3dSStefano Zampini + pc - the preconditioning context 24853cdbc3dSStefano Zampini 24953cdbc3dSStefano Zampini Output Parameters: 25053cdbc3dSStefano Zampini + NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 25153cdbc3dSStefano Zampini 25253cdbc3dSStefano Zampini Level: intermediate 25353cdbc3dSStefano Zampini 25453cdbc3dSStefano Zampini Notes: 25553cdbc3dSStefano Zampini 25653cdbc3dSStefano Zampini .seealso: PCBDDC 25753cdbc3dSStefano Zampini @*/ 25853cdbc3dSStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 25953cdbc3dSStefano Zampini { 26053cdbc3dSStefano Zampini PetscErrorCode ierr; 26153cdbc3dSStefano Zampini 26253cdbc3dSStefano Zampini PetscFunctionBegin; 26353cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 26453cdbc3dSStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 2650c7d97c5SJed Brown PetscFunctionReturn(0); 2660c7d97c5SJed Brown } 26736e030ebSStefano Zampini /* -------------------------------------------------------------------------- */ 26836e030ebSStefano Zampini EXTERN_C_BEGIN 26936e030ebSStefano Zampini #undef __FUNCT__ 270*da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC" 271*da1bb401SStefano Zampini static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs, PetscInt xadj[], PetscInt adjncy[], PetscCopyMode copymode) 27236e030ebSStefano Zampini { 27336e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 274*da1bb401SStefano Zampini PCBDDCGraph mat_graph=pcbddc->mat_graph; 275*da1bb401SStefano Zampini PetscErrorCode ierr; 27636e030ebSStefano Zampini 27736e030ebSStefano Zampini PetscFunctionBegin; 278*da1bb401SStefano Zampini mat_graph->nvtxs=nvtxs; 279*da1bb401SStefano Zampini ierr = PetscFree(mat_graph->xadj);CHKERRQ(ierr); 280*da1bb401SStefano Zampini ierr = PetscFree(mat_graph->adjncy);CHKERRQ(ierr); 281*da1bb401SStefano Zampini if(copymode == PETSC_COPY_VALUES) { 282*da1bb401SStefano Zampini ierr = PetscMalloc((mat_graph->nvtxs+1)*sizeof(PetscInt),&mat_graph->xadj);CHKERRQ(ierr); 283*da1bb401SStefano Zampini ierr = PetscMalloc(xadj[mat_graph->nvtxs]*sizeof(PetscInt),&mat_graph->adjncy);CHKERRQ(ierr); 284*da1bb401SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(mat_graph->nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 285*da1bb401SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[mat_graph->nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 286*da1bb401SStefano Zampini } else if(copymode == PETSC_OWN_POINTER) { 287*da1bb401SStefano Zampini mat_graph->xadj=xadj; 288*da1bb401SStefano Zampini mat_graph->adjncy=adjncy; 289*da1bb401SStefano Zampini } else { 290*da1bb401SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d in %s\n",copymode,__FUNCT__); 291*da1bb401SStefano Zampini } 29236e030ebSStefano Zampini PetscFunctionReturn(0); 29336e030ebSStefano Zampini } 29436e030ebSStefano Zampini EXTERN_C_END 29536e030ebSStefano Zampini #undef __FUNCT__ 296*da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph" 29736e030ebSStefano Zampini /*@ 298*da1bb401SStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set CSR graph of local matrix for use of PCBDDC. 29936e030ebSStefano Zampini 30036e030ebSStefano Zampini Not collective 30136e030ebSStefano Zampini 30236e030ebSStefano Zampini Input Parameters: 30336e030ebSStefano Zampini + pc - the preconditioning context 304*da1bb401SStefano Zampini - nvtxs - number of local vertices of the graph 305*da1bb401SStefano Zampini - xadj, adjncy - the CSR graph 306*da1bb401SStefano Zampini - copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER. In the former case the user must free the array passed in; 307*da1bb401SStefano Zampini in the latter case, memory must be obtained with PetscMalloc. 30836e030ebSStefano Zampini 30936e030ebSStefano Zampini Level: intermediate 31036e030ebSStefano Zampini 31136e030ebSStefano Zampini Notes: 31236e030ebSStefano Zampini 31336e030ebSStefano Zampini .seealso: PCBDDC 31436e030ebSStefano Zampini @*/ 315*da1bb401SStefano Zampini PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,PetscInt xadj[],PetscInt adjncy[], PetscCopyMode copymode) 31636e030ebSStefano Zampini { 317*da1bb401SStefano Zampini PetscInt nrows,ncols; 318*da1bb401SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 31936e030ebSStefano Zampini PetscErrorCode ierr; 32036e030ebSStefano Zampini 32136e030ebSStefano Zampini PetscFunctionBegin; 32236e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 323*da1bb401SStefano Zampini ierr = MatGetSize(matis->A,&nrows,&ncols);CHKERRQ(ierr); 324*da1bb401SStefano Zampini if(nvtxs != nrows) { 325*da1bb401SStefano Zampini SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local adjacency size %d passed in %s differs from local problem size %d!\n",nvtxs,__FUNCT__,nrows); 326*da1bb401SStefano Zampini } else { 327*da1bb401SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,PetscInt[],PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 328*da1bb401SStefano Zampini } 32936e030ebSStefano Zampini PetscFunctionReturn(0); 33036e030ebSStefano Zampini } 3319c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 3329c0446d6SStefano Zampini EXTERN_C_BEGIN 3339c0446d6SStefano Zampini #undef __FUNCT__ 3349c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 3359c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 3369c0446d6SStefano Zampini { 3379c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3389c0446d6SStefano Zampini PetscInt i; 3399c0446d6SStefano Zampini PetscErrorCode ierr; 3409c0446d6SStefano Zampini 3419c0446d6SStefano Zampini PetscFunctionBegin; 342*da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 3439c0446d6SStefano Zampini for(i=0;i<pcbddc->n_ISForDofs;i++) { 3449c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 3459c0446d6SStefano Zampini } 346d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 347*da1bb401SStefano Zampini /* allocate space then set */ 3489c0446d6SStefano Zampini ierr = PetscMalloc(n_is*sizeof(IS),&pcbddc->ISForDofs);CHKERRQ(ierr); 3499c0446d6SStefano Zampini for(i=0;i<n_is;i++) { 350*da1bb401SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 351*da1bb401SStefano Zampini pcbddc->ISForDofs[i]=ISForDofs[i]; 3529c0446d6SStefano Zampini } 3539c0446d6SStefano Zampini pcbddc->n_ISForDofs=n_is; 3549c0446d6SStefano Zampini PetscFunctionReturn(0); 3559c0446d6SStefano Zampini } 3569c0446d6SStefano Zampini EXTERN_C_END 3579c0446d6SStefano Zampini #undef __FUNCT__ 3589c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 3599c0446d6SStefano Zampini /*@ 360*da1bb401SStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of local mat. 3619c0446d6SStefano Zampini 3629c0446d6SStefano Zampini Not collective 3639c0446d6SStefano Zampini 3649c0446d6SStefano Zampini Input Parameters: 3659c0446d6SStefano Zampini + pc - the preconditioning context 366*da1bb401SStefano Zampini - n - number of index sets defining the fields 367*da1bb401SStefano Zampini - IS[] - array of IS describing the fields 3689c0446d6SStefano Zampini 3699c0446d6SStefano Zampini Level: intermediate 3709c0446d6SStefano Zampini 3719c0446d6SStefano Zampini Notes: 3729c0446d6SStefano Zampini 3739c0446d6SStefano Zampini .seealso: PCBDDC 3749c0446d6SStefano Zampini @*/ 3759c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 3769c0446d6SStefano Zampini { 3779c0446d6SStefano Zampini PetscErrorCode ierr; 3789c0446d6SStefano Zampini 3799c0446d6SStefano Zampini PetscFunctionBegin; 3809c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 3819c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 3829c0446d6SStefano Zampini PetscFunctionReturn(0); 3839c0446d6SStefano Zampini } 384*da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 3859c0446d6SStefano Zampini 38653cdbc3dSStefano Zampini #undef __FUNCT__ 38753cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 3880c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 3890c7d97c5SJed Brown /* 3900c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 3910c7d97c5SJed Brown by setting data structures and options. 3920c7d97c5SJed Brown 3930c7d97c5SJed Brown Input Parameter: 39453cdbc3dSStefano Zampini + pc - the preconditioner context 3950c7d97c5SJed Brown 3960c7d97c5SJed Brown Application Interface Routine: PCSetUp() 3970c7d97c5SJed Brown 3980c7d97c5SJed Brown Notes: 3990c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 4000c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 4010c7d97c5SJed Brown */ 40253cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 4030c7d97c5SJed Brown { 4040c7d97c5SJed Brown PetscErrorCode ierr; 4050c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4060c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 4070c7d97c5SJed Brown 4080c7d97c5SJed Brown PetscFunctionBegin; 4090c7d97c5SJed Brown if (!pc->setupcalled) { 4103b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 4119c0446d6SStefano Zampini So, we set to pcnone the Neumann problem of pcis in order to avoid unneeded computation 4120c7d97c5SJed Brown Also, we decide to directly build the (same) Dirichlet problem */ 4130c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localN_pc_type","none");CHKERRQ(ierr); 4140c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localD_pc_type","none");CHKERRQ(ierr); 4150c7d97c5SJed Brown /* Set up all the "iterative substructuring" common block */ 4160c7d97c5SJed Brown ierr = PCISSetUp(pc);CHKERRQ(ierr); 4173b03a366Sstefano_zampini /* Get stdout for dbg */ 418e269702eSStefano Zampini if(pcbddc->dbg_flag) { 419e269702eSStefano Zampini ierr = PetscViewerASCIIGetStdout(((PetscObject)pc)->comm,&pcbddc->dbg_viewer);CHKERRQ(ierr); 420e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 421e269702eSStefano Zampini } 4223b03a366Sstefano_zampini /* TODO MOVE CODE FRAGMENT */ 4230c7d97c5SJed Brown PetscInt im_active=0; 4240c7d97c5SJed Brown if(pcis->n) im_active = 1; 42553cdbc3dSStefano Zampini ierr = MPI_Allreduce(&im_active,&pcbddc->active_procs,1,MPIU_INT,MPI_SUM,((PetscObject)pc)->comm);CHKERRQ(ierr); 4263b03a366Sstefano_zampini /* Analyze local interface */ 4270c7d97c5SJed Brown ierr = PCBDDCManageLocalBoundaries(pc);CHKERRQ(ierr); 4283b03a366Sstefano_zampini /* Set up local constraint matrix */ 4293b03a366Sstefano_zampini ierr = PCBDDCCreateConstraintMatrix(pc);CHKERRQ(ierr); 4300c7d97c5SJed Brown /* Create coarse and local stuffs used for evaluating action of preconditioner */ 4310c7d97c5SJed Brown ierr = PCBDDCCoarseSetUp(pc);CHKERRQ(ierr); 4323b03a366Sstefano_zampini /* Processes fakely involved in multilevel should not call ISLocalToGlobalMappingRestoreInfo */ 4333b03a366Sstefano_zampini if ( !pcis->n_neigh ) pcis->ISLocalToGlobalMappingGetInfoWasCalled=PETSC_FALSE; 4340c7d97c5SJed Brown } 4350c7d97c5SJed Brown PetscFunctionReturn(0); 4360c7d97c5SJed Brown } 4370c7d97c5SJed Brown 4380c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 4390c7d97c5SJed Brown /* 4400c7d97c5SJed Brown PCApply_BDDC - Applies the BDDC preconditioner to a vector. 4410c7d97c5SJed Brown 4420c7d97c5SJed Brown Input Parameters: 4430c7d97c5SJed Brown . pc - the preconditioner context 4440c7d97c5SJed Brown . r - input vector (global) 4450c7d97c5SJed Brown 4460c7d97c5SJed Brown Output Parameter: 4470c7d97c5SJed Brown . z - output vector (global) 4480c7d97c5SJed Brown 4490c7d97c5SJed Brown Application Interface Routine: PCApply() 4500c7d97c5SJed Brown */ 4510c7d97c5SJed Brown #undef __FUNCT__ 4520c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 45353cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 4540c7d97c5SJed Brown { 4550c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 4560c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 4570c7d97c5SJed Brown PetscErrorCode ierr; 4583b03a366Sstefano_zampini const PetscScalar one = 1.0; 4593b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 4600c7d97c5SJed Brown 4610c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 4620c7d97c5SJed Brown NN interface preconditioner changed to BDDC 4630c7d97c5SJed Brown Added support for M_3 preconditioenr in the reference article (code is active if pcbddc->prec_type = PETSC_TRUE) */ 4640c7d97c5SJed Brown 4650c7d97c5SJed Brown PetscFunctionBegin; 4660c7d97c5SJed Brown /* First Dirichlet solve */ 4670c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4680c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 46953cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 4700c7d97c5SJed Brown /* 4710c7d97c5SJed Brown Assembling right hand side for BDDC operator 4720c7d97c5SJed Brown - vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE) 4730c7d97c5SJed Brown - the interface part of the global vector z 4740c7d97c5SJed Brown */ 4750c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 4760c7d97c5SJed Brown ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 4770c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 4780c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 4790c7d97c5SJed Brown ierr = VecCopy(r,z);CHKERRQ(ierr); 4800c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4810c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4820c7d97c5SJed Brown 4830c7d97c5SJed Brown /* 4840c7d97c5SJed Brown Apply interface preconditioner 4850c7d97c5SJed Brown Results are stored in: 4860c7d97c5SJed Brown - vec1_D (if needed, i.e. with prec_type = PETSC_TRUE) 4870c7d97c5SJed Brown - the interface part of the global vector z 4880c7d97c5SJed Brown */ 4890c7d97c5SJed Brown ierr = PCBDDCApplyInterfacePreconditioner(pc,z);CHKERRQ(ierr); 4900c7d97c5SJed Brown 4913b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 4920c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4930c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4940c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 4950c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 49653cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr); 4970c7d97c5SJed Brown ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr); 4980c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); } 4990c7d97c5SJed Brown ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr); 5000c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5010c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5020c7d97c5SJed Brown 5030c7d97c5SJed Brown PetscFunctionReturn(0); 5040c7d97c5SJed Brown 5050c7d97c5SJed Brown } 506*da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 507*da1bb401SStefano Zampini #undef __FUNCT__ 508*da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC" 509*da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 510*da1bb401SStefano Zampini { 511*da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 512*da1bb401SStefano Zampini PetscErrorCode ierr; 513*da1bb401SStefano Zampini 514*da1bb401SStefano Zampini PetscFunctionBegin; 515*da1bb401SStefano Zampini /* free data created by PCIS */ 516*da1bb401SStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 517*da1bb401SStefano Zampini /* free BDDC data */ 518*da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 519*da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_rhs);CHKERRQ(ierr); 520*da1bb401SStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 521*da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_mat);CHKERRQ(ierr); 522*da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 523*da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 524*da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 525*da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 526*da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 527*da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 528*da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 529*da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 530*da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->vec4_D);CHKERRQ(ierr); 531*da1bb401SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 532*da1bb401SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 533*da1bb401SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 534*da1bb401SStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 535*da1bb401SStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 536*da1bb401SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 537*da1bb401SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 538*da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 539*da1bb401SStefano Zampini ierr = PetscFree(pcbddc->local_primal_indices);CHKERRQ(ierr); 540*da1bb401SStefano Zampini ierr = PetscFree(pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 541*da1bb401SStefano Zampini if (pcbddc->replicated_local_primal_values) { free(pcbddc->replicated_local_primal_values); } 542*da1bb401SStefano Zampini ierr = PetscFree(pcbddc->local_primal_displacements);CHKERRQ(ierr); 543*da1bb401SStefano Zampini ierr = PetscFree(pcbddc->local_primal_sizes);CHKERRQ(ierr); 544*da1bb401SStefano Zampini PetscInt i; 545*da1bb401SStefano Zampini for(i=0;i<pcbddc->n_ISForDofs;i++) { ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); } 546*da1bb401SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 547*da1bb401SStefano Zampini for(i=0;i<pcbddc->n_ISForFaces;i++) { ierr = ISDestroy(&pcbddc->ISForFaces[i]);CHKERRQ(ierr); } 548*da1bb401SStefano Zampini ierr = PetscFree(pcbddc->ISForFaces);CHKERRQ(ierr); 549*da1bb401SStefano Zampini for(i=0;i<pcbddc->n_ISForEdges;i++) { ierr = ISDestroy(&pcbddc->ISForEdges[i]);CHKERRQ(ierr); } 550*da1bb401SStefano Zampini ierr = PetscFree(pcbddc->ISForEdges);CHKERRQ(ierr); 551*da1bb401SStefano Zampini ierr = ISDestroy(&pcbddc->ISForVertices);CHKERRQ(ierr); 552*da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->xadj);CHKERRQ(ierr); 553*da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->adjncy);CHKERRQ(ierr); 554*da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->neighbours_set[0]);CHKERRQ(ierr); 555*da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->neighbours_set);CHKERRQ(ierr); 556*da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr); 557*da1bb401SStefano Zampini /* Free the private data structure that was hanging off the PC */ 558*da1bb401SStefano Zampini ierr = PetscFree(pcbddc);CHKERRQ(ierr); 559*da1bb401SStefano Zampini PetscFunctionReturn(0); 560*da1bb401SStefano Zampini } 5610c7d97c5SJed Brown 5620c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 563*da1bb401SStefano Zampini /*MC 564*da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 5650c7d97c5SJed Brown 566*da1bb401SStefano Zampini Options Database Keys: 567*da1bb401SStefano Zampini . -pcbddc ??? - 568*da1bb401SStefano Zampini 569*da1bb401SStefano Zampini Level: intermediate 570*da1bb401SStefano Zampini 571*da1bb401SStefano Zampini Notes: The matrix used with this preconditioner must be of type MATIS 572*da1bb401SStefano Zampini 573*da1bb401SStefano Zampini Unlike more 'conventional' interface preconditioners, this iterates over ALL the 574*da1bb401SStefano Zampini degrees of freedom, NOT just those on the interface (this allows the use of approximate solvers 575*da1bb401SStefano Zampini on the subdomains). 576*da1bb401SStefano Zampini 577*da1bb401SStefano Zampini Options for the coarse grid preconditioner can be set with - 578*da1bb401SStefano Zampini Options for the Dirichlet subproblem can be set with - 579*da1bb401SStefano Zampini Options for the Neumann subproblem can be set with - 580*da1bb401SStefano Zampini 581*da1bb401SStefano Zampini Contributed by Stefano Zampini 582*da1bb401SStefano Zampini 583*da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 584*da1bb401SStefano Zampini M*/ 585*da1bb401SStefano Zampini EXTERN_C_BEGIN 586*da1bb401SStefano Zampini #undef __FUNCT__ 587*da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC" 588*da1bb401SStefano Zampini PetscErrorCode PCCreate_BDDC(PC pc) 589*da1bb401SStefano Zampini { 590*da1bb401SStefano Zampini PetscErrorCode ierr; 591*da1bb401SStefano Zampini PC_BDDC *pcbddc; 592*da1bb401SStefano Zampini PCBDDCGraph mat_graph; 593*da1bb401SStefano Zampini 594*da1bb401SStefano Zampini PetscFunctionBegin; 595*da1bb401SStefano Zampini /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 596*da1bb401SStefano Zampini ierr = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr); 597*da1bb401SStefano Zampini pc->data = (void*)pcbddc; 598*da1bb401SStefano Zampini 599*da1bb401SStefano Zampini /* create PCIS data structure */ 600*da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 601*da1bb401SStefano Zampini 602*da1bb401SStefano Zampini /* BDDC specific */ 603*da1bb401SStefano Zampini pcbddc->coarse_vec = 0; 604*da1bb401SStefano Zampini pcbddc->coarse_rhs = 0; 605*da1bb401SStefano Zampini pcbddc->coarse_ksp = 0; 606*da1bb401SStefano Zampini pcbddc->coarse_phi_B = 0; 607*da1bb401SStefano Zampini pcbddc->coarse_phi_D = 0; 608*da1bb401SStefano Zampini pcbddc->vec1_P = 0; 609*da1bb401SStefano Zampini pcbddc->vec1_R = 0; 610*da1bb401SStefano Zampini pcbddc->vec2_R = 0; 611*da1bb401SStefano Zampini pcbddc->local_auxmat1 = 0; 612*da1bb401SStefano Zampini pcbddc->local_auxmat2 = 0; 613*da1bb401SStefano Zampini pcbddc->R_to_B = 0; 614*da1bb401SStefano Zampini pcbddc->R_to_D = 0; 615*da1bb401SStefano Zampini pcbddc->ksp_D = 0; 616*da1bb401SStefano Zampini pcbddc->ksp_R = 0; 617*da1bb401SStefano Zampini pcbddc->local_primal_indices = 0; 618*da1bb401SStefano Zampini pcbddc->prec_type = PETSC_FALSE; 619*da1bb401SStefano Zampini pcbddc->NeumannBoundaries = 0; 620*da1bb401SStefano Zampini pcbddc->ISForDofs = 0; 621*da1bb401SStefano Zampini pcbddc->ISForVertices = 0; 622*da1bb401SStefano Zampini pcbddc->n_ISForFaces = 0; 623*da1bb401SStefano Zampini pcbddc->n_ISForEdges = 0; 624*da1bb401SStefano Zampini pcbddc->ConstraintMatrix = 0; 625*da1bb401SStefano Zampini pcbddc->use_nnsp_true = PETSC_FALSE; 626*da1bb401SStefano Zampini pcbddc->local_primal_sizes = 0; 627*da1bb401SStefano Zampini pcbddc->local_primal_displacements = 0; 628*da1bb401SStefano Zampini pcbddc->replicated_local_primal_indices = 0; 629*da1bb401SStefano Zampini pcbddc->replicated_local_primal_values = 0; 630*da1bb401SStefano Zampini pcbddc->coarse_loc_to_glob = 0; 631*da1bb401SStefano Zampini pcbddc->dbg_flag = PETSC_FALSE; 632*da1bb401SStefano Zampini pcbddc->coarsening_ratio = 8; 633*da1bb401SStefano Zampini 634*da1bb401SStefano Zampini /* allocate and initialize needed graph structure */ 635*da1bb401SStefano Zampini ierr = PetscMalloc(sizeof(*mat_graph),&pcbddc->mat_graph);CHKERRQ(ierr); 636*da1bb401SStefano Zampini pcbddc->mat_graph->xadj = 0; 637*da1bb401SStefano Zampini pcbddc->mat_graph->adjncy = 0; 638*da1bb401SStefano Zampini 639*da1bb401SStefano Zampini /* function pointers */ 640*da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 641*da1bb401SStefano Zampini pc->ops->applytranspose = 0; 642*da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 643*da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 644*da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 645*da1bb401SStefano Zampini pc->ops->view = 0; 646*da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 647*da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 648*da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 649*da1bb401SStefano Zampini 650*da1bb401SStefano Zampini /* composing function */ 651*da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C","PCBDDCSetDirichletBoundaries_BDDC", 652*da1bb401SStefano Zampini PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 653*da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C","PCBDDCSetNeumannBoundaries_BDDC", 654*da1bb401SStefano Zampini PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 655*da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C","PCBDDCGetDirichletBoundaries_BDDC", 656*da1bb401SStefano Zampini PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 657*da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C","PCBDDCGetNeumannBoundaries_BDDC", 658*da1bb401SStefano Zampini PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 659*da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetCoarseProblemType_C","PCBDDCSetCoarseProblemType_BDDC", 660*da1bb401SStefano Zampini PCBDDCSetCoarseProblemType_BDDC);CHKERRQ(ierr); 661*da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetDofsSplitting_C","PCBDDCSetDofsSplitting_BDDC", 662*da1bb401SStefano Zampini PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 663*da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C","PCBDDCSetLocalAdjacencyGraph_BDDC", 664*da1bb401SStefano Zampini PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 665*da1bb401SStefano Zampini PetscFunctionReturn(0); 666*da1bb401SStefano Zampini } 667*da1bb401SStefano Zampini EXTERN_C_END 668*da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 669*da1bb401SStefano Zampini /* All static functions from now on */ 670*da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 671*da1bb401SStefano Zampini #undef __FUNCT__ 672*da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetupLocalAdjacencyGraph" 673*da1bb401SStefano Zampini static PetscErrorCode PCBDDCSetupLocalAdjacencyGraph(PC pc) 674*da1bb401SStefano Zampini { 675*da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 676*da1bb401SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 677*da1bb401SStefano Zampini PetscInt nvtxs,*xadj,*adjncy; 678*da1bb401SStefano Zampini Mat mat_adj; 679*da1bb401SStefano Zampini PetscBool symmetrize_rowij=PETSC_TRUE,compressed_rowij=PETSC_FALSE,flg_row=PETSC_TRUE; 680*da1bb401SStefano Zampini PCBDDCGraph mat_graph=pcbddc->mat_graph; 681*da1bb401SStefano Zampini PetscErrorCode ierr; 682*da1bb401SStefano Zampini 683*da1bb401SStefano Zampini PetscFunctionBegin; 684*da1bb401SStefano Zampini /* get CSR adjacency from local matrix if user has not yet provided local graph using PCBDDCSetLocalAdjacencyGraph function */ 685*da1bb401SStefano Zampini if(!mat_graph->xadj) { 686*da1bb401SStefano Zampini ierr = MatConvert(matis->A,MATMPIADJ,MAT_INITIAL_MATRIX,&mat_adj);CHKERRQ(ierr); 687*da1bb401SStefano Zampini ierr = MatGetRowIJ(mat_adj,0,symmetrize_rowij,compressed_rowij,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 688*da1bb401SStefano Zampini if(!flg_row) { 689*da1bb401SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatGetRowIJ called in %s\n",__FUNCT__); 690*da1bb401SStefano Zampini } 691*da1bb401SStefano Zampini /* Get adjacency into BDDC workspace */ 692*da1bb401SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 693*da1bb401SStefano Zampini ierr = MatRestoreRowIJ(mat_adj,0,symmetrize_rowij,compressed_rowij,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 694*da1bb401SStefano Zampini if(!flg_row) { 695*da1bb401SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called in %s\n",__FUNCT__); 696*da1bb401SStefano Zampini } 697*da1bb401SStefano Zampini ierr = MatDestroy(&mat_adj);CHKERRQ(ierr); 698*da1bb401SStefano Zampini } 699*da1bb401SStefano Zampini PetscFunctionReturn(0); 700*da1bb401SStefano Zampini } 701*da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 7020c7d97c5SJed Brown #undef __FUNCT__ 7030c7d97c5SJed Brown #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 70453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, Vec z) 7050c7d97c5SJed Brown { 7060c7d97c5SJed Brown PetscErrorCode ierr; 7070c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 7080c7d97c5SJed Brown PC_IS* pcis = (PC_IS*) (pc->data); 7093b03a366Sstefano_zampini const PetscScalar zero = 0.0; 7100c7d97c5SJed Brown 7110c7d97c5SJed Brown PetscFunctionBegin; 7120c7d97c5SJed Brown /* Get Local boundary and apply partition of unity */ 7130c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7140c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7150c7d97c5SJed Brown ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 7160c7d97c5SJed Brown 7170c7d97c5SJed Brown /* Application of PHI^T */ 7180c7d97c5SJed Brown ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 7190c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 7200c7d97c5SJed Brown 7210c7d97c5SJed Brown /* Scatter data of coarse_rhs */ 7220c7d97c5SJed Brown if(pcbddc->coarse_rhs) ierr = VecSet(pcbddc->coarse_rhs,zero);CHKERRQ(ierr); 7230c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7240c7d97c5SJed Brown 7250c7d97c5SJed Brown /* Local solution on R nodes */ 7260c7d97c5SJed Brown ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 7270c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7280c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7290c7d97c5SJed Brown if(pcbddc->prec_type) { 7300c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7310c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7320c7d97c5SJed Brown } 7330c7d97c5SJed Brown ierr = PCBDDCSolveSaddlePoint(pc);CHKERRQ(ierr); 7340c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 7350c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7360c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7370c7d97c5SJed Brown if(pcbddc->prec_type) { 7380c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7390c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7400c7d97c5SJed Brown } 7410c7d97c5SJed Brown 7420c7d97c5SJed Brown /* Coarse solution */ 7430c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 74453cdbc3dSStefano Zampini if(pcbddc->coarse_rhs) ierr = KSPSolve(pcbddc->coarse_ksp,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 7450c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7460c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd (pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7470c7d97c5SJed Brown 7480c7d97c5SJed Brown /* Sum contributions from two levels */ 7490c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 7500c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 751*da1bb401SStefano Zampini 752*da1bb401SStefano Zampini /* Apply partition of unity and sum boundary values */ 753*da1bb401SStefano Zampini ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 7540c7d97c5SJed Brown ierr = VecSet(z,zero);CHKERRQ(ierr); 7550c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7560c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7570c7d97c5SJed Brown PetscFunctionReturn(0); 7580c7d97c5SJed Brown } 7590c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 7600c7d97c5SJed Brown #undef __FUNCT__ 7610c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSolveSaddlePoint" 76253cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSolveSaddlePoint(PC pc) 7630c7d97c5SJed Brown { 7640c7d97c5SJed Brown PetscErrorCode ierr; 7650c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 7660c7d97c5SJed Brown 7670c7d97c5SJed Brown PetscFunctionBegin; 76853cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 7690c7d97c5SJed Brown if(pcbddc->n_constraints) { 7700c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec2_R,pcbddc->vec1_C);CHKERRQ(ierr); 7710c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 7720c7d97c5SJed Brown } 7730c7d97c5SJed Brown PetscFunctionReturn(0); 7740c7d97c5SJed Brown } 7750c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 7760c7d97c5SJed Brown #undef __FUNCT__ 7770c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 77853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,Vec vec_from, Vec vec_to, InsertMode imode, ScatterMode smode) 7790c7d97c5SJed Brown { 7800c7d97c5SJed Brown PetscErrorCode ierr; 7810c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 7820c7d97c5SJed Brown 7830c7d97c5SJed Brown PetscFunctionBegin; 7840c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 7850c7d97c5SJed Brown case SCATTERS_BDDC: 7860c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 7870c7d97c5SJed Brown break; 7880c7d97c5SJed Brown case GATHERS_BDDC: 7890c7d97c5SJed Brown break; 7900c7d97c5SJed Brown } 7910c7d97c5SJed Brown PetscFunctionReturn(0); 7920c7d97c5SJed Brown } 7930c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 7940c7d97c5SJed Brown #undef __FUNCT__ 7950c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 79653cdbc3dSStefano Zampini static PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc,Vec vec_from, Vec vec_to, InsertMode imode, ScatterMode smode) 7970c7d97c5SJed Brown { 7980c7d97c5SJed Brown PetscErrorCode ierr; 7990c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 8000c7d97c5SJed Brown PetscScalar* array_to; 8010c7d97c5SJed Brown PetscScalar* array_from; 8020c7d97c5SJed Brown MPI_Comm comm=((PetscObject)pc)->comm; 8030c7d97c5SJed Brown PetscInt i; 8040c7d97c5SJed Brown 8050c7d97c5SJed Brown PetscFunctionBegin; 8060c7d97c5SJed Brown 8070c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 8080c7d97c5SJed Brown case SCATTERS_BDDC: 8090c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 8100c7d97c5SJed Brown break; 8110c7d97c5SJed Brown case GATHERS_BDDC: 8120c7d97c5SJed Brown if(vec_from) VecGetArray(vec_from,&array_from); 8130c7d97c5SJed Brown if(vec_to) VecGetArray(vec_to,&array_to); 8140c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 8150c7d97c5SJed Brown case SEQUENTIAL_BDDC: 8160c7d97c5SJed Brown if(smode == SCATTER_FORWARD) { 81753cdbc3dSStefano 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); 8180c7d97c5SJed Brown if(vec_to) { 8190c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 8200c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 8210c7d97c5SJed Brown } 8220c7d97c5SJed Brown } else { 8230c7d97c5SJed Brown if(vec_from) 8240c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 8250c7d97c5SJed Brown pcbddc->replicated_local_primal_values[i]=array_from[pcbddc->replicated_local_primal_indices[i]]; 82653cdbc3dSStefano 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); 8270c7d97c5SJed Brown } 8280c7d97c5SJed Brown break; 8290c7d97c5SJed Brown case REPLICATED_BDDC: 8300c7d97c5SJed Brown if(smode == SCATTER_FORWARD) { 83153cdbc3dSStefano 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); 8320c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 8330c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 8340c7d97c5SJed Brown } else { /* no communications needed for SCATTER_REVERSE since needed data is already present */ 8350c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_size;i++) 8360c7d97c5SJed Brown array_to[i]=array_from[pcbddc->local_primal_indices[i]]; 8370c7d97c5SJed Brown } 8380c7d97c5SJed Brown break; 83953cdbc3dSStefano Zampini case MULTILEVEL_BDDC: 84053cdbc3dSStefano Zampini break; 84153cdbc3dSStefano Zampini case PARALLEL_BDDC: 84253cdbc3dSStefano Zampini break; 8430c7d97c5SJed Brown } 8440c7d97c5SJed Brown if(vec_from) VecRestoreArray(vec_from,&array_from); 8450c7d97c5SJed Brown if(vec_to) VecRestoreArray(vec_to,&array_to); 8460c7d97c5SJed Brown break; 8470c7d97c5SJed Brown } 8480c7d97c5SJed Brown PetscFunctionReturn(0); 8490c7d97c5SJed Brown } 8500c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 851de534f79Sstefano_zampini #ifdef BDDC_USE_POD 852de534f79Sstefano_zampini #if !defined(PETSC_MISSING_LAPACK_GESVD) 8533b03a366Sstefano_zampini #define PETSC_MISSING_LAPACK_GESVD 1 854de534f79Sstefano_zampini #define UNDEF_PETSC_MISSING_LAPACK_GESVD 1 855de534f79Sstefano_zampini #endif 8563b03a366Sstefano_zampini #endif 8573b03a366Sstefano_zampini 8583b03a366Sstefano_zampini #undef __FUNCT__ 8593b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCCreateConstraintMatrix" 8603b03a366Sstefano_zampini static PetscErrorCode PCBDDCCreateConstraintMatrix(PC pc) 8613b03a366Sstefano_zampini { 8623b03a366Sstefano_zampini PetscErrorCode ierr; 8633b03a366Sstefano_zampini PC_IS* pcis = (PC_IS*)(pc->data); 8643b03a366Sstefano_zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 8653b03a366Sstefano_zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 8663b03a366Sstefano_zampini PetscInt *nnz,*vertices,*is_indices; 8673b03a366Sstefano_zampini PetscScalar *temp_quadrature_constraint; 8683b03a366Sstefano_zampini PetscInt *temp_indices,*temp_indices_to_constraint; 8693b03a366Sstefano_zampini PetscInt local_primal_size,i,j,k,total_counts,max_size_of_constraint; 8703b03a366Sstefano_zampini PetscInt n_constraints,n_vertices,size_of_constraint; 8713b03a366Sstefano_zampini PetscReal quad_value; 8723b03a366Sstefano_zampini PetscBool nnsp_has_cnst=PETSC_FALSE,use_nnsp_true=pcbddc->use_nnsp_true; 8733b03a366Sstefano_zampini PetscInt nnsp_size=0,nnsp_addone=0,temp_constraints,temp_start_ptr; 8743b03a366Sstefano_zampini IS *used_IS; 8753b03a366Sstefano_zampini const MatType impMatType=MATSEQAIJ; 8763b03a366Sstefano_zampini PetscBLASInt Bs,Bt,lwork,lierr; 8773b03a366Sstefano_zampini PetscReal tol=1.0e-8; 878fcda91b4SJed Brown MatNullSpace nearnullsp; 879fcda91b4SJed Brown const Vec *nearnullvecs; 8803b03a366Sstefano_zampini Vec *localnearnullsp; 8813b03a366Sstefano_zampini PetscScalar *work,*temp_basis,*array_vector,*correlation_mat; 8823b03a366Sstefano_zampini PetscReal *rwork,*singular_vals; 883de534f79Sstefano_zampini PetscBLASInt Bone=1; 884de534f79Sstefano_zampini /* some ugly conditional declarations */ 8853b03a366Sstefano_zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 8863b03a366Sstefano_zampini PetscScalar dot_result; 8873b03a366Sstefano_zampini PetscScalar one=1.0,zero=0.0; 8883b03a366Sstefano_zampini PetscInt ii; 8893b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 8903b03a366Sstefano_zampini PetscScalar val1,val2; 8913b03a366Sstefano_zampini #endif 8923b03a366Sstefano_zampini #else 8933b03a366Sstefano_zampini PetscBLASInt dummy_int; 8943b03a366Sstefano_zampini PetscScalar dummy_scalar; 8953b03a366Sstefano_zampini #endif 8963b03a366Sstefano_zampini 8973b03a366Sstefano_zampini PetscFunctionBegin; 8983b03a366Sstefano_zampini /* check if near null space is attached to global mat */ 899fcda91b4SJed Brown ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 900fcda91b4SJed Brown if (nearnullsp) { 901fcda91b4SJed Brown ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 9023b03a366Sstefano_zampini } else { /* if near null space is not provided it uses constants */ 9033b03a366Sstefano_zampini nnsp_has_cnst = PETSC_TRUE; 9043b03a366Sstefano_zampini use_nnsp_true = PETSC_TRUE; 9053b03a366Sstefano_zampini } 9063b03a366Sstefano_zampini if(nnsp_has_cnst) { 9073b03a366Sstefano_zampini nnsp_addone = 1; 9083b03a366Sstefano_zampini } 9093b03a366Sstefano_zampini /* 9103b03a366Sstefano_zampini Evaluate maximum storage size needed by the procedure 9113b03a366Sstefano_zampini - temp_indices will contain start index of each constraint stored as follows 9123b03a366Sstefano_zampini - temp_indices_to_constraint[temp_indices[i],...,temp[indices[i+1]-1] will contain the indices (in local numbering) on which the constraint acts 9133b03a366Sstefano_zampini - temp_quadrature_constraint[temp_indices[i],...,temp[indices[i+1]-1] will contain the scalars representing the constraint itself 9143b03a366Sstefano_zampini */ 915*da1bb401SStefano Zampini 9163b03a366Sstefano_zampini total_counts = pcbddc->n_ISForFaces+pcbddc->n_ISForEdges; 9173b03a366Sstefano_zampini total_counts *= (nnsp_addone+nnsp_size); 918*da1bb401SStefano Zampini ierr = ISGetSize(pcbddc->ISForVertices,&n_vertices);CHKERRQ(ierr); 919*da1bb401SStefano Zampini total_counts += n_vertices; 9203b03a366Sstefano_zampini ierr = PetscMalloc((total_counts+1)*sizeof(PetscInt),&temp_indices);CHKERRQ(ierr); 9213b03a366Sstefano_zampini total_counts = 0; 9223b03a366Sstefano_zampini max_size_of_constraint = 0; 9233b03a366Sstefano_zampini for(i=0;i<pcbddc->n_ISForEdges+pcbddc->n_ISForFaces;i++){ 9243b03a366Sstefano_zampini if(i<pcbddc->n_ISForEdges){ 9253b03a366Sstefano_zampini used_IS = &pcbddc->ISForEdges[i]; 9263b03a366Sstefano_zampini } else { 9273b03a366Sstefano_zampini used_IS = &pcbddc->ISForFaces[i-pcbddc->n_ISForEdges]; 9283b03a366Sstefano_zampini } 9293b03a366Sstefano_zampini ierr = ISGetSize(*used_IS,&j);CHKERRQ(ierr); 9303b03a366Sstefano_zampini total_counts += j; 9313b03a366Sstefano_zampini if(j>max_size_of_constraint) max_size_of_constraint=j; 9323b03a366Sstefano_zampini } 9333b03a366Sstefano_zampini total_counts *= (nnsp_addone+nnsp_size); 934*da1bb401SStefano Zampini total_counts += n_vertices; 9353b03a366Sstefano_zampini ierr = PetscMalloc(total_counts*sizeof(PetscScalar),&temp_quadrature_constraint);CHKERRQ(ierr); 9363b03a366Sstefano_zampini ierr = PetscMalloc(total_counts*sizeof(PetscInt),&temp_indices_to_constraint);CHKERRQ(ierr); 9373b03a366Sstefano_zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd or LAPACKsyev/LAPACKheev */ 9383b03a366Sstefano_zampini rwork = 0; 9393b03a366Sstefano_zampini work = 0; 9403b03a366Sstefano_zampini singular_vals = 0; 9413b03a366Sstefano_zampini temp_basis = 0; 9423b03a366Sstefano_zampini correlation_mat = 0; 9433b03a366Sstefano_zampini if(!pcbddc->use_nnsp_true) { 9443b03a366Sstefano_zampini PetscScalar temp_work; 9453b03a366Sstefano_zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 9463b03a366Sstefano_zampini /* POD */ 9473b03a366Sstefano_zampini PetscInt max_n; 9483b03a366Sstefano_zampini max_n = nnsp_addone+nnsp_size; 9493b03a366Sstefano_zampini /* using some techniques borrowed from Proper Orthogonal Decomposition */ 9503b03a366Sstefano_zampini ierr = PetscMalloc(max_n*max_n*sizeof(PetscScalar),&correlation_mat);CHKERRQ(ierr); 9513b03a366Sstefano_zampini ierr = PetscMalloc(max_n*sizeof(PetscReal),&singular_vals);CHKERRQ(ierr); 9523b03a366Sstefano_zampini ierr = PetscMalloc(max_size_of_constraint*(nnsp_addone+nnsp_size)*sizeof(PetscScalar),&temp_basis);CHKERRQ(ierr); 9533b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 9543b03a366Sstefano_zampini ierr = PetscMalloc(3*max_n*sizeof(PetscReal),&rwork);CHKERRQ(ierr); 9553b03a366Sstefano_zampini #endif 9563b03a366Sstefano_zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 9573b03a366Sstefano_zampini Bt = PetscBLASIntCast(max_n); 9583b03a366Sstefano_zampini lwork=-1; 9593b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 9603b03a366Sstefano_zampini LAPACKsyev_("V","U",&Bt,correlation_mat,&Bt,singular_vals,&temp_work,&lwork,&lierr); 9613b03a366Sstefano_zampini #else 9623b03a366Sstefano_zampini LAPACKsyev_("V","U",&Bt,correlation_mat,&Bt,singular_vals,&temp_work,&lwork,rwork,&lierr); 9633b03a366Sstefano_zampini #endif 9643b03a366Sstefano_zampini #else /* on missing GESVD */ 9653b03a366Sstefano_zampini /* SVD */ 9663b03a366Sstefano_zampini PetscInt max_n,min_n; 9673b03a366Sstefano_zampini max_n = max_size_of_constraint; 9683b03a366Sstefano_zampini min_n = nnsp_addone+nnsp_size; 9693b03a366Sstefano_zampini if(max_size_of_constraint < ( nnsp_addone+nnsp_size ) ) { 9703b03a366Sstefano_zampini min_n = max_size_of_constraint; 9713b03a366Sstefano_zampini max_n = nnsp_addone+nnsp_size; 9723b03a366Sstefano_zampini } 9733b03a366Sstefano_zampini ierr = PetscMalloc(min_n*sizeof(PetscReal),&singular_vals);CHKERRQ(ierr); 9743b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 9753b03a366Sstefano_zampini ierr = PetscMalloc(5*min_n*sizeof(PetscReal),&rwork);CHKERRQ(ierr); 9763b03a366Sstefano_zampini #endif 9773b03a366Sstefano_zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 9783b03a366Sstefano_zampini lwork=-1; 9793b03a366Sstefano_zampini Bs = PetscBLASIntCast(max_n); 9803b03a366Sstefano_zampini Bt = PetscBLASIntCast(min_n); 9813b03a366Sstefano_zampini dummy_int = Bs; 982670f3ff9SJed Brown ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 9833b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 9843b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[0],&Bs,singular_vals, 9853b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,&temp_work,&lwork,&lierr); 9863b03a366Sstefano_zampini #else 9873b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[0],&Bs,singular_vals, 9883b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,&temp_work,&lwork,rwork,&lierr); 9893b03a366Sstefano_zampini #endif 9903b03a366Sstefano_zampini if ( lierr ) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SVD Lapack routine %d",(int)lierr); 991670f3ff9SJed Brown ierr = PetscFPTrapPop();CHKERRQ(ierr); 9923b03a366Sstefano_zampini #endif 9933b03a366Sstefano_zampini /* Allocate optimal workspace */ 9943b03a366Sstefano_zampini lwork = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work)); 9953b03a366Sstefano_zampini total_counts = (PetscInt)lwork; 9963b03a366Sstefano_zampini ierr = PetscMalloc(total_counts*sizeof(PetscScalar),&work);CHKERRQ(ierr); 9973b03a366Sstefano_zampini } 9983b03a366Sstefano_zampini /* get local part of global near null space vectors */ 9993b03a366Sstefano_zampini ierr = PetscMalloc(nnsp_size*sizeof(Vec),&localnearnullsp);CHKERRQ(ierr); 10003b03a366Sstefano_zampini for(k=0;k<nnsp_size;k++) { 10013b03a366Sstefano_zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 1002fcda91b4SJed Brown ierr = VecScatterBegin(matis->ctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1003fcda91b4SJed Brown ierr = VecScatterEnd (matis->ctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 10043b03a366Sstefano_zampini } 10053b03a366Sstefano_zampini /* Now we can loop on constraining sets */ 10063b03a366Sstefano_zampini total_counts=0; 10073b03a366Sstefano_zampini temp_indices[0]=0; 1008*da1bb401SStefano Zampini /* vertices */ 1009*da1bb401SStefano Zampini PetscBool used_vertex; 1010*da1bb401SStefano Zampini ierr = PetscMalloc(n_vertices*sizeof(PetscInt),&vertices);CHKERRQ(ierr); 1011*da1bb401SStefano Zampini ierr = ISGetIndices(pcbddc->ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1012*da1bb401SStefano Zampini if(nnsp_has_cnst) { /* consider all vertices */ 1013*da1bb401SStefano Zampini for(i=0;i<n_vertices;i++) { 1014*da1bb401SStefano Zampini temp_indices_to_constraint[temp_indices[total_counts]]=is_indices[i]; 1015*da1bb401SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]]=1.0; 1016*da1bb401SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+1; 1017*da1bb401SStefano Zampini vertices[total_counts]=is_indices[i]; 1018*da1bb401SStefano Zampini total_counts++; 1019*da1bb401SStefano Zampini } 1020*da1bb401SStefano Zampini } else { /* consider vertices for which exist at least a localnearnullsp which is not null there */ 1021*da1bb401SStefano Zampini for(i=0;i<n_vertices;i++) { 1022*da1bb401SStefano Zampini used_vertex=PETSC_FALSE; 1023*da1bb401SStefano Zampini k=0; 1024*da1bb401SStefano Zampini while(!used_vertex && k<nnsp_size) { 1025*da1bb401SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array_vector);CHKERRQ(ierr); 1026*da1bb401SStefano Zampini if(PetscAbsScalar(array_vector[is_indices[i]])>0.0) { 1027*da1bb401SStefano Zampini temp_indices_to_constraint[temp_indices[total_counts]]=is_indices[i]; 1028*da1bb401SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]]=1.0; 1029*da1bb401SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+1; 1030*da1bb401SStefano Zampini vertices[total_counts]=is_indices[i]; 1031*da1bb401SStefano Zampini total_counts++; 1032*da1bb401SStefano Zampini used_vertex=PETSC_TRUE; 1033*da1bb401SStefano Zampini } 1034*da1bb401SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array_vector);CHKERRQ(ierr); 1035*da1bb401SStefano Zampini k++; 1036*da1bb401SStefano Zampini } 1037*da1bb401SStefano Zampini } 1038*da1bb401SStefano Zampini } 1039*da1bb401SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1040*da1bb401SStefano Zampini n_vertices=total_counts; 1041*da1bb401SStefano Zampini /* edges and faces */ 10423b03a366Sstefano_zampini for(i=0;i<pcbddc->n_ISForEdges+pcbddc->n_ISForFaces;i++){ 10433b03a366Sstefano_zampini if(i<pcbddc->n_ISForEdges){ 10443b03a366Sstefano_zampini used_IS = &pcbddc->ISForEdges[i]; 10453b03a366Sstefano_zampini } else { 10463b03a366Sstefano_zampini used_IS = &pcbddc->ISForFaces[i-pcbddc->n_ISForEdges]; 10473b03a366Sstefano_zampini } 10483b03a366Sstefano_zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 10493b03a366Sstefano_zampini temp_start_ptr = total_counts; /* need to know the starting index of constraints stored */ 10503b03a366Sstefano_zampini ierr = ISGetSize(*used_IS,&size_of_constraint);CHKERRQ(ierr); 10513b03a366Sstefano_zampini ierr = ISGetIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 10523b03a366Sstefano_zampini if(nnsp_has_cnst) { 10533b03a366Sstefano_zampini temp_constraints++; 10543b03a366Sstefano_zampini quad_value = 1.0/PetscSqrtReal((PetscReal)size_of_constraint); 10553b03a366Sstefano_zampini for(j=0;j<size_of_constraint;j++) { 10563b03a366Sstefano_zampini temp_indices_to_constraint[temp_indices[total_counts]+j]=is_indices[j]; 10573b03a366Sstefano_zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=quad_value; 10583b03a366Sstefano_zampini } 10593b03a366Sstefano_zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 10603b03a366Sstefano_zampini total_counts++; 10613b03a366Sstefano_zampini } 10623b03a366Sstefano_zampini for(k=0;k<nnsp_size;k++) { 10633b03a366Sstefano_zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array_vector);CHKERRQ(ierr); 10643b03a366Sstefano_zampini for(j=0;j<size_of_constraint;j++) { 10653b03a366Sstefano_zampini temp_indices_to_constraint[temp_indices[total_counts]+j]=is_indices[j]; 10663b03a366Sstefano_zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=array_vector[is_indices[j]]; 10673b03a366Sstefano_zampini } 10683b03a366Sstefano_zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array_vector);CHKERRQ(ierr); 1069de534f79Sstefano_zampini quad_value = 1.0; 1070de534f79Sstefano_zampini if( use_nnsp_true ) { /* check if array is null on the connected component in case use_nnsp_true has been requested */ 1071de534f79Sstefano_zampini Bs = PetscBLASIntCast(size_of_constraint); 1072de534f79Sstefano_zampini quad_value = BLASasum_(&Bs,&temp_quadrature_constraint[temp_indices[total_counts]],&Bone); 1073de534f79Sstefano_zampini } 1074de534f79Sstefano_zampini if ( quad_value > 0.0 ) { /* keep indices and values */ 1075de534f79Sstefano_zampini temp_constraints++; 10763b03a366Sstefano_zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 10773b03a366Sstefano_zampini total_counts++; 10783b03a366Sstefano_zampini } 1079de534f79Sstefano_zampini } 10803b03a366Sstefano_zampini ierr = ISRestoreIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1081de534f79Sstefano_zampini /* perform SVD on the constraint if use_nnsp_true has not be requested by the user */ 10823b03a366Sstefano_zampini if(!use_nnsp_true) { 1083de534f79Sstefano_zampini 10843b03a366Sstefano_zampini Bs = PetscBLASIntCast(size_of_constraint); 10853b03a366Sstefano_zampini Bt = PetscBLASIntCast(temp_constraints); 1086de534f79Sstefano_zampini 10873b03a366Sstefano_zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 10883b03a366Sstefano_zampini ierr = PetscMemzero(correlation_mat,Bt*Bt*sizeof(PetscScalar));CHKERRQ(ierr); 10893b03a366Sstefano_zampini /* Store upper triangular part of correlation matrix */ 10903b03a366Sstefano_zampini for(j=0;j<temp_constraints;j++) { 10913b03a366Sstefano_zampini for(k=0;k<j+1;k++) { 10923b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 10933b03a366Sstefano_zampini /* hand made complex dot product */ 10943b03a366Sstefano_zampini dot_result = 0.0; 10953b03a366Sstefano_zampini for (ii=0; ii<size_of_constraint; ii++) { 10963b03a366Sstefano_zampini val1 = temp_quadrature_constraint[temp_indices[temp_start_ptr+j]+ii]; 10973b03a366Sstefano_zampini val2 = temp_quadrature_constraint[temp_indices[temp_start_ptr+k]+ii]; 10983b03a366Sstefano_zampini dot_result += val1*PetscConj(val2); 10993b03a366Sstefano_zampini } 11003b03a366Sstefano_zampini #else 11013b03a366Sstefano_zampini dot_result = BLASdot_(&Bs,&temp_quadrature_constraint[temp_indices[temp_start_ptr+j]],&Bone, 11023b03a366Sstefano_zampini &temp_quadrature_constraint[temp_indices[temp_start_ptr+k]],&Bone); 11033b03a366Sstefano_zampini #endif 11043b03a366Sstefano_zampini correlation_mat[j*temp_constraints+k]=dot_result; 11053b03a366Sstefano_zampini } 11063b03a366Sstefano_zampini } 11073b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 11083b03a366Sstefano_zampini LAPACKsyev_("V","U",&Bt,correlation_mat,&Bt,singular_vals,work,&lwork,&lierr); 11093b03a366Sstefano_zampini #else 11103b03a366Sstefano_zampini LAPACKsyev_("V","U",&Bt,correlation_mat,&Bt,singular_vals,work,&lwork,rwork,&lierr); 11113b03a366Sstefano_zampini #endif 11123b03a366Sstefano_zampini if ( lierr ) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in EV Lapack routine %d",(int)lierr); 11133b03a366Sstefano_zampini /* retain eigenvalues greater than tol: note that lapack SYEV gives eigs in ascending order */ 11143b03a366Sstefano_zampini j=0; 11153b03a366Sstefano_zampini while( j < Bt && singular_vals[j] < tol) j++; 11163b03a366Sstefano_zampini total_counts=total_counts-j; 11173b03a366Sstefano_zampini if(j<temp_constraints) { 11183b03a366Sstefano_zampini for(k=j;k<Bt;k++) { singular_vals[k]=1.0/PetscSqrtReal(singular_vals[k]); } 11193b03a366Sstefano_zampini BLASgemm_("N","N",&Bs,&Bt,&Bt,&one,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Bs,correlation_mat,&Bt,&zero,temp_basis,&Bs); 11203b03a366Sstefano_zampini /* copy POD basis into used quadrature memory */ 11213b03a366Sstefano_zampini for(k=0;k<Bt-j;k++) { 11223b03a366Sstefano_zampini for(ii=0;ii<size_of_constraint;ii++) { 11233b03a366Sstefano_zampini temp_quadrature_constraint[temp_indices[temp_start_ptr+k]+ii]=singular_vals[Bt-1-k]*temp_basis[(Bt-1-k)*size_of_constraint+ii]; 11243b03a366Sstefano_zampini } 11253b03a366Sstefano_zampini } 11263b03a366Sstefano_zampini } 1127de534f79Sstefano_zampini 11283b03a366Sstefano_zampini #else /* on missing GESVD */ 1129de534f79Sstefano_zampini 11303b03a366Sstefano_zampini PetscInt min_n = temp_constraints; 11313b03a366Sstefano_zampini if(min_n > size_of_constraint) min_n = size_of_constraint; 11323b03a366Sstefano_zampini dummy_int = Bs; 1133670f3ff9SJed Brown ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 11343b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 11353b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Bs,singular_vals, 11363b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,work,&lwork,&lierr); 11373b03a366Sstefano_zampini #else 11383b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Bs,singular_vals, 11393b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,work,&lwork,rwork,&lierr); 11403b03a366Sstefano_zampini #endif 11413b03a366Sstefano_zampini if ( lierr ) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SVD Lapack routine %d",(int)lierr); 1142670f3ff9SJed Brown ierr = PetscFPTrapPop();CHKERRQ(ierr); 11433b03a366Sstefano_zampini /* retain eigenvalues greater than tol: note that lapack SVD gives eigs in descending order */ 11443b03a366Sstefano_zampini j=0; 11453b03a366Sstefano_zampini while( j < min_n && singular_vals[min_n-j-1] < tol) j++; 11463b03a366Sstefano_zampini total_counts = total_counts-(PetscInt)Bt+(min_n-j); 1147de534f79Sstefano_zampini 11483b03a366Sstefano_zampini #endif 11493b03a366Sstefano_zampini } 11503b03a366Sstefano_zampini } 1151*da1bb401SStefano Zampini n_constraints=total_counts-n_vertices; 1152*da1bb401SStefano Zampini local_primal_size = total_counts; 11533b03a366Sstefano_zampini ierr = PetscMalloc(local_primal_size*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 11543b03a366Sstefano_zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 11553b03a366Sstefano_zampini ierr = MatSetType(pcbddc->ConstraintMatrix,impMatType);CHKERRQ(ierr); 11563b03a366Sstefano_zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,local_primal_size,pcis->n,local_primal_size,pcis->n);CHKERRQ(ierr); 1157*da1bb401SStefano Zampini for(i=0;i<local_primal_size;i++) { 1158*da1bb401SStefano Zampini nnz[i]=temp_indices[i+1]-temp_indices[i]; 1159*da1bb401SStefano Zampini } 11603b03a366Sstefano_zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 1161*da1bb401SStefano Zampini for(i=0;i<local_primal_size;i++) { 11623b03a366Sstefano_zampini size_of_constraint=temp_indices[i+1]-temp_indices[i]; 1163*da1bb401SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&i,size_of_constraint,&temp_indices_to_constraint[temp_indices[i]],&temp_quadrature_constraint[temp_indices[i]],INSERT_VALUES);CHKERRQ(ierr); 11643b03a366Sstefano_zampini } 11653b03a366Sstefano_zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11663b03a366Sstefano_zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11673b03a366Sstefano_zampini /* set quantities in pcbddc data structure */ 11683b03a366Sstefano_zampini pcbddc->n_vertices = n_vertices; 11693b03a366Sstefano_zampini pcbddc->n_constraints = n_constraints; 1170*da1bb401SStefano Zampini pcbddc->local_primal_size = local_primal_size; 11713b03a366Sstefano_zampini /* free workspace no longer needed */ 11723b03a366Sstefano_zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 11733b03a366Sstefano_zampini ierr = PetscFree(work);CHKERRQ(ierr); 11743b03a366Sstefano_zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 11753b03a366Sstefano_zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 11763b03a366Sstefano_zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 11773b03a366Sstefano_zampini ierr = PetscFree(temp_indices);CHKERRQ(ierr); 11783b03a366Sstefano_zampini ierr = PetscFree(temp_indices_to_constraint);CHKERRQ(ierr); 11793b03a366Sstefano_zampini ierr = PetscFree(temp_quadrature_constraint);CHKERRQ(ierr); 11803b03a366Sstefano_zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 1181*da1bb401SStefano Zampini for(k=0;k<nnsp_size;k++) { 1182*da1bb401SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 1183*da1bb401SStefano Zampini } 11843b03a366Sstefano_zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 11853b03a366Sstefano_zampini PetscFunctionReturn(0); 11863b03a366Sstefano_zampini } 1187de534f79Sstefano_zampini #ifdef UNDEF_PETSC_MISSING_LAPACK_GESVD 11883b03a366Sstefano_zampini #undef PETSC_MISSING_LAPACK_GESVD 11893b03a366Sstefano_zampini #endif 11903b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 11910c7d97c5SJed Brown #undef __FUNCT__ 11920c7d97c5SJed Brown #define __FUNCT__ "PCBDDCCoarseSetUp" 119353cdbc3dSStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC pc) 11940c7d97c5SJed Brown { 11950c7d97c5SJed Brown PetscErrorCode ierr; 11960c7d97c5SJed Brown 11970c7d97c5SJed Brown PC_IS* pcis = (PC_IS*)(pc->data); 11980c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 11990c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 12000c7d97c5SJed Brown IS is_R_local; 12010c7d97c5SJed Brown IS is_V_local; 12020c7d97c5SJed Brown IS is_C_local; 12030c7d97c5SJed Brown IS is_aux1; 12040c7d97c5SJed Brown IS is_aux2; 12050c7d97c5SJed Brown const VecType impVecType; 12060c7d97c5SJed Brown const MatType impMatType; 12070c7d97c5SJed Brown PetscInt n_R=0; 12080c7d97c5SJed Brown PetscInt n_D=0; 12090c7d97c5SJed Brown PetscInt n_B=0; 12100c7d97c5SJed Brown PetscScalar zero=0.0; 12110c7d97c5SJed Brown PetscScalar one=1.0; 12120c7d97c5SJed Brown PetscScalar m_one=-1.0; 12130c7d97c5SJed Brown PetscScalar* array; 12140c7d97c5SJed Brown PetscScalar *coarse_submat_vals; 12150c7d97c5SJed Brown PetscInt *idx_R_local; 12160c7d97c5SJed Brown PetscInt *idx_V_B; 12170c7d97c5SJed Brown PetscScalar *coarsefunctions_errors; 12180c7d97c5SJed Brown PetscScalar *constraints_errors; 12190c7d97c5SJed Brown /* auxiliary indices */ 1220*da1bb401SStefano Zampini PetscInt i,j; 1221e269702eSStefano Zampini /* for verbose output of bddc */ 1222e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 1223e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 1224a0ba757dSStefano Zampini /* for counting coarse dofs */ 12253b03a366Sstefano_zampini PetscInt n_vertices=pcbddc->n_vertices,n_constraints=pcbddc->n_constraints; 12263b03a366Sstefano_zampini PetscInt size_of_constraint; 12273b03a366Sstefano_zampini PetscInt *row_cmat_indices; 12283b03a366Sstefano_zampini PetscScalar *row_cmat_values; 1229*da1bb401SStefano Zampini PetscInt *vertices; 12300c7d97c5SJed Brown 12310c7d97c5SJed Brown PetscFunctionBegin; 12320c7d97c5SJed Brown /* Set Non-overlapping dimensions */ 12330c7d97c5SJed Brown n_B = pcis->n_B; n_D = pcis->n - n_B; 12343b03a366Sstefano_zampini 1235*da1bb401SStefano Zampini /* get vertex indices from constraint matrix */ 1236*da1bb401SStefano Zampini ierr = PetscMalloc(pcbddc->n_vertices*sizeof(PetscInt),&vertices);CHKERRQ(ierr); 1237*da1bb401SStefano Zampini j=0; 1238*da1bb401SStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) { 1239*da1bb401SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 1240*da1bb401SStefano Zampini if(size_of_constraint == 1) { 1241*da1bb401SStefano Zampini vertices[j]=row_cmat_indices[0]; 1242*da1bb401SStefano Zampini j++; 1243a0ba757dSStefano Zampini } 1244*da1bb401SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 1245a0ba757dSStefano Zampini } 1246a0ba757dSStefano Zampini 12470c7d97c5SJed Brown /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 12480c7d97c5SJed Brown ierr = VecSet(pcis->vec1_N,one);CHKERRQ(ierr); 12490c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 12503b03a366Sstefano_zampini for (i=0;i<n_vertices;i++) { array[ vertices[i] ] = zero; } 12513b03a366Sstefano_zampini ierr = PetscMalloc(( pcis->n - n_vertices )*sizeof(PetscInt),&idx_R_local);CHKERRQ(ierr); 12520c7d97c5SJed Brown for (i=0, n_R=0; i<pcis->n; i++) { if (array[i] == one) { idx_R_local[n_R] = i; n_R++; } } 12530c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1254e269702eSStefano Zampini if(dbg_flag) { 12550c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 12560c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 12570c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 12580c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 12593b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"r_size = %d, v_size = %d, constraints = %d, local_primal_size = %d\n",n_R,n_vertices,n_constraints,pcbddc->local_primal_size);CHKERRQ(ierr); 12600c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 12610c7d97c5SJed Brown } 12620c7d97c5SJed Brown /* Allocate needed vectors */ 12630c7d97c5SJed Brown /* Set Mat type for local matrices needed by BDDC precondtioner */ 12640c7d97c5SJed Brown impMatType = MATSEQDENSE; 12650c7d97c5SJed Brown impVecType = VECSEQ; 12660c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_D,&pcbddc->vec4_D);CHKERRQ(ierr); 12670c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_R);CHKERRQ(ierr); 12680c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_R,n_R,n_R);CHKERRQ(ierr); 12690c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 1270d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 12710c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_P);CHKERRQ(ierr); 12720c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_P,pcbddc->local_primal_size,pcbddc->local_primal_size);CHKERRQ(ierr); 12730c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 12740c7d97c5SJed Brown 12750c7d97c5SJed Brown /* Creating some index sets needed */ 12760c7d97c5SJed Brown /* For submatrices */ 1277*da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n_R,idx_R_local,PETSC_OWN_POINTER,&is_R_local);CHKERRQ(ierr); 12783b03a366Sstefano_zampini if(n_vertices) { 1279*da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n_vertices,vertices,PETSC_OWN_POINTER,&is_V_local);CHKERRQ(ierr); 12803b03a366Sstefano_zampini } 1281*da1bb401SStefano Zampini if(n_constraints) { 1282*da1bb401SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_C_local);CHKERRQ(ierr); 1283*da1bb401SStefano Zampini } 1284*da1bb401SStefano Zampini 12850c7d97c5SJed Brown /* For VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 12860c7d97c5SJed Brown { 12870c7d97c5SJed Brown PetscInt *aux_array1; 12880c7d97c5SJed Brown PetscInt *aux_array2; 12890c7d97c5SJed Brown 12903b03a366Sstefano_zampini ierr = PetscMalloc( (pcis->n_B-n_vertices)*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 12913b03a366Sstefano_zampini ierr = PetscMalloc( (pcis->n_B-n_vertices)*sizeof(PetscInt),&aux_array2);CHKERRQ(ierr); 12920c7d97c5SJed Brown 1293d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 12940c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 12950c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 12960c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12970c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12980c7d97c5SJed Brown ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12990c7d97c5SJed Brown ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13000c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1301*da1bb401SStefano Zampini for (i=0, j=0; i<n_R; i++) { if (array[idx_R_local[i]] > one) { aux_array1[j] = i; j++; } } 13020c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1303*da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 13040c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1305*da1bb401SStefano Zampini for (i=0, j=0; i<n_B; i++) { if (array[i] > one) { aux_array2[j] = i; j++; } } 13063828260eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1307*da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_COPY_VALUES,&is_aux2);CHKERRQ(ierr); 13080c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 13090c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 13100c7d97c5SJed Brown ierr = PetscFree(aux_array2);CHKERRQ(ierr); 13110c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 13120c7d97c5SJed Brown ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 13130c7d97c5SJed Brown 1314e269702eSStefano Zampini if(pcbddc->prec_type || dbg_flag ) { 13150c7d97c5SJed Brown ierr = PetscMalloc(n_D*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 13160c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1317*da1bb401SStefano Zampini for (i=0, j=0; i<n_R; i++) { if (array[idx_R_local[i]] == one) { aux_array1[j] = i; j++; } } 13180c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1319*da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 13200c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 13210c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 13220c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 13230c7d97c5SJed Brown } 13240c7d97c5SJed Brown } 13250c7d97c5SJed Brown 13260c7d97c5SJed Brown /* vertices in boundary numbering */ 13273b03a366Sstefano_zampini if(n_vertices) { 1328d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,m_one);CHKERRQ(ierr); 13290c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 13303b03a366Sstefano_zampini for (i=0; i<n_vertices; i++) { array[ vertices[i] ] = i; } 13310c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1332d49ef151SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1333d49ef151SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13343b03a366Sstefano_zampini ierr = PetscMalloc(n_vertices*sizeof(PetscInt),&idx_V_B);CHKERRQ(ierr); 13350c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 13363b03a366Sstefano_zampini for (i=0; i<n_vertices; i++) { 1337*da1bb401SStefano Zampini j=0; 1338*da1bb401SStefano Zampini while (array[j] != i ) {j++;} 1339*da1bb401SStefano Zampini idx_V_B[i]=j; 13400c7d97c5SJed Brown } 13410c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 13420c7d97c5SJed Brown } 13430c7d97c5SJed Brown 13440c7d97c5SJed Brown /* Creating PC contexts for local Dirichlet and Neumann problems */ 13450c7d97c5SJed Brown { 13460c7d97c5SJed Brown Mat A_RR; 134753cdbc3dSStefano Zampini PC pc_temp; 13480c7d97c5SJed Brown /* Matrix for Dirichlet problem is A_II -> we already have it from pcis.c code */ 134953cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 135053cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 135153cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II,SAME_PRECONDITIONER);CHKERRQ(ierr); 135253cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 1353*da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,"dirichlet_");CHKERRQ(ierr); 13540c7d97c5SJed Brown /* default */ 135553cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 135653cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 13570c7d97c5SJed Brown /* Allow user's customization */ 135853cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 135953cdbc3dSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 136053cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 1361*da1bb401SStefano Zampini if(pcbddc->dbg_flag) ierr = KSPView(pcbddc->ksp_D,PETSC_VIEWER_STDOUT_SELF); 13620c7d97c5SJed Brown /* Matrix for Neumann problem is A_RR -> we need to create it */ 13630c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_R_local,is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 136453cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 136553cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 136653cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR,SAME_PRECONDITIONER);CHKERRQ(ierr); 136753cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 1368*da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,"neumann_");CHKERRQ(ierr); 13690c7d97c5SJed Brown /* default */ 137053cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 137153cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 13720c7d97c5SJed Brown /* Allow user's customization */ 137353cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 137453cdbc3dSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 137553cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 1376*da1bb401SStefano Zampini if(pcbddc->dbg_flag) ierr = KSPView(pcbddc->ksp_R,PETSC_VIEWER_STDOUT_SELF); 1377a0ba757dSStefano Zampini /* check Dirichlet and Neumann solvers */ 1378e269702eSStefano Zampini if(pcbddc->dbg_flag) { 13790c7d97c5SJed Brown Vec temp_vec; 13800c7d97c5SJed Brown PetscScalar value; 13810c7d97c5SJed Brown 1382a0ba757dSStefano Zampini ierr = VecDuplicate(pcis->vec1_D,&temp_vec);CHKERRQ(ierr); 1383a0ba757dSStefano Zampini ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL);CHKERRQ(ierr); 1384a0ba757dSStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 1385a0ba757dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,temp_vec);CHKERRQ(ierr); 1386a0ba757dSStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcis->vec1_D);CHKERRQ(ierr); 1387a0ba757dSStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 1388a0ba757dSStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1389a0ba757dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1390a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1391a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Checking solution of Dirichlet and Neumann problems\n");CHKERRQ(ierr); 1392a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Dirichlet solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 1393d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&temp_vec);CHKERRQ(ierr); 1394d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 1395d49ef151SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 1396d49ef151SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,temp_vec);CHKERRQ(ierr); 1397d49ef151SStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 1398d49ef151SStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 1399e269702eSStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 14000c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Neumann solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 1401d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 14020c7d97c5SJed Brown } 14030c7d97c5SJed Brown /* free Neumann problem's matrix */ 14040c7d97c5SJed Brown ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 14050c7d97c5SJed Brown } 14060c7d97c5SJed Brown 14070c7d97c5SJed Brown /* Assemble all remaining stuff needed to apply BDDC */ 14080c7d97c5SJed Brown { 14090c7d97c5SJed Brown Mat A_RV,A_VR,A_VV; 14100c7d97c5SJed Brown Mat M1,M2; 14110c7d97c5SJed Brown Mat C_CR; 14123b03a366Sstefano_zampini Mat AUXMAT; 14130c7d97c5SJed Brown Vec vec1_C; 14140c7d97c5SJed Brown Vec vec2_C; 14150c7d97c5SJed Brown Vec vec1_V; 14160c7d97c5SJed Brown Vec vec2_V; 14170c7d97c5SJed Brown PetscInt *nnz; 14180c7d97c5SJed Brown PetscInt *auxindices; 141953cdbc3dSStefano Zampini PetscInt index; 14200c7d97c5SJed Brown PetscScalar* array2; 14210c7d97c5SJed Brown MatFactorInfo matinfo; 14220c7d97c5SJed Brown 14230c7d97c5SJed Brown /* Allocating some extra storage just to be safe */ 14240c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 14250c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&auxindices);CHKERRQ(ierr); 14260c7d97c5SJed Brown for(i=0;i<pcis->n;i++) {auxindices[i]=i;} 14270c7d97c5SJed Brown 14280c7d97c5SJed Brown /* some work vectors on vertices and/or constraints */ 14293b03a366Sstefano_zampini if(n_vertices) { 14300c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_V);CHKERRQ(ierr); 14313b03a366Sstefano_zampini ierr = VecSetSizes(vec1_V,n_vertices,n_vertices);CHKERRQ(ierr); 14320c7d97c5SJed Brown ierr = VecSetType(vec1_V,impVecType);CHKERRQ(ierr); 14330c7d97c5SJed Brown ierr = VecDuplicate(vec1_V,&vec2_V);CHKERRQ(ierr); 14340c7d97c5SJed Brown } 14350c7d97c5SJed Brown if(pcbddc->n_constraints) { 14360c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_C);CHKERRQ(ierr); 14370c7d97c5SJed Brown ierr = VecSetSizes(vec1_C,pcbddc->n_constraints,pcbddc->n_constraints);CHKERRQ(ierr); 14380c7d97c5SJed Brown ierr = VecSetType(vec1_C,impVecType);CHKERRQ(ierr); 14390c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&vec2_C);CHKERRQ(ierr); 14400c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&pcbddc->vec1_C);CHKERRQ(ierr); 14410c7d97c5SJed Brown } 14420c7d97c5SJed Brown /* Precompute stuffs needed for preprocessing and application of BDDC*/ 14433b03a366Sstefano_zampini if(n_constraints) { 14440c7d97c5SJed Brown /* some work vectors */ 14450c7d97c5SJed Brown ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->local_auxmat2);CHKERRQ(ierr); 14463b03a366Sstefano_zampini ierr = MatSetSizes(pcbddc->local_auxmat2,n_R,n_constraints,n_R,n_constraints);CHKERRQ(ierr); 14470c7d97c5SJed Brown ierr = MatSetType(pcbddc->local_auxmat2,impMatType);CHKERRQ(ierr); 14483b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(pcbddc->local_auxmat2,PETSC_NULL);CHKERRQ(ierr); 14490c7d97c5SJed Brown 14500c7d97c5SJed Brown /* Assemble local_auxmat2 = - A_{RR}^{-1} C^T_{CR} needed by BDDC application */ 14513b03a366Sstefano_zampini for(i=0;i<n_constraints;i++) { 1452d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 14533b03a366Sstefano_zampini ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 14543b03a366Sstefano_zampini /* Get row of constraint matrix in R numbering */ 14550c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14563b03a366Sstefano_zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,n_vertices+i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 14573b03a366Sstefano_zampini for(j=0;j<size_of_constraint;j++) { array[ row_cmat_indices[j] ] = - row_cmat_values[j]; } 14583b03a366Sstefano_zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,n_vertices+i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 14590c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 14600c7d97c5SJed Brown for(j=0;j<n_R;j++) { array2[j] = array[ idx_R_local[j] ]; } 14610c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14620c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 14633b03a366Sstefano_zampini /* Solve for row of constraint matrix in R numbering */ 146453cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 14653b03a366Sstefano_zampini /* Set values */ 14660c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 14673b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->local_auxmat2,n_R,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 14680c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 14690c7d97c5SJed Brown } 14700c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14710c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14720c7d97c5SJed Brown 14730c7d97c5SJed Brown /* Create Constraint matrix on R nodes: C_{CR} */ 14743b03a366Sstefano_zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_C_local,is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 14750c7d97c5SJed Brown ierr = ISDestroy(&is_C_local);CHKERRQ(ierr); 14760c7d97c5SJed Brown 14770c7d97c5SJed Brown /* Assemble AUXMAT = ( LUFactor )( -C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 14780c7d97c5SJed Brown ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AUXMAT);CHKERRQ(ierr); 1479d49ef151SStefano Zampini ierr = MatFactorInfoInitialize(&matinfo);CHKERRQ(ierr); 14803b03a366Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,0,1,&is_aux1);CHKERRQ(ierr); 14810c7d97c5SJed Brown ierr = MatLUFactor(AUXMAT,is_aux1,is_aux1,&matinfo);CHKERRQ(ierr); 14820c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 14830c7d97c5SJed Brown 14843b03a366Sstefano_zampini /* Assemble explicitly M1 = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} needed in preproc */ 1485d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M1);CHKERRQ(ierr); 14863b03a366Sstefano_zampini ierr = MatSetSizes(M1,n_constraints,n_constraints,n_constraints,n_constraints);CHKERRQ(ierr); 14870c7d97c5SJed Brown ierr = MatSetType(M1,impMatType);CHKERRQ(ierr); 14883b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(M1,PETSC_NULL);CHKERRQ(ierr); 14893b03a366Sstefano_zampini for(i=0;i<n_constraints;i++) { 14900c7d97c5SJed Brown ierr = VecSet(vec1_C,zero);CHKERRQ(ierr); 14910c7d97c5SJed Brown ierr = VecSetValue(vec1_C,i,one,INSERT_VALUES);CHKERRQ(ierr); 14920c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_C);CHKERRQ(ierr); 14930c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_C);CHKERRQ(ierr); 14940c7d97c5SJed Brown ierr = MatSolve(AUXMAT,vec1_C,vec2_C);CHKERRQ(ierr); 14950c7d97c5SJed Brown ierr = VecScale(vec2_C,m_one);CHKERRQ(ierr); 14960c7d97c5SJed Brown ierr = VecGetArray(vec2_C,&array);CHKERRQ(ierr); 14973b03a366Sstefano_zampini ierr = MatSetValues(M1,n_constraints,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 14980c7d97c5SJed Brown ierr = VecRestoreArray(vec2_C,&array);CHKERRQ(ierr); 14990c7d97c5SJed Brown } 15000c7d97c5SJed Brown ierr = MatAssemblyBegin(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 15010c7d97c5SJed Brown ierr = MatAssemblyEnd(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 15020c7d97c5SJed Brown ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 15030c7d97c5SJed Brown /* Assemble local_auxmat1 = M1*C_{CR} needed by BDDC application in KSP and in preproc */ 15040c7d97c5SJed Brown ierr = MatMatMult(M1,C_CR,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 15050c7d97c5SJed Brown 15060c7d97c5SJed Brown } 15070c7d97c5SJed Brown 15080c7d97c5SJed Brown /* Get submatrices from subdomain matrix */ 15093b03a366Sstefano_zampini if(n_vertices){ 15100c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_R_local,is_V_local,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 15110c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_V_local,is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 15120c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_V_local,is_V_local,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 15130c7d97c5SJed Brown /* Assemble M2 = A_RR^{-1}A_RV */ 1514d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M2);CHKERRQ(ierr); 15153b03a366Sstefano_zampini ierr = MatSetSizes(M2,n_R,n_vertices,n_R,n_vertices);CHKERRQ(ierr); 15160c7d97c5SJed Brown ierr = MatSetType(M2,impMatType);CHKERRQ(ierr); 15173b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(M2,PETSC_NULL);CHKERRQ(ierr); 15183b03a366Sstefano_zampini for(i=0;i<n_vertices;i++) { 15190c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 15200c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 15210c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 15220c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 15230c7d97c5SJed Brown ierr = MatMult(A_RV,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 152453cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 15250c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 15263b03a366Sstefano_zampini ierr = MatSetValues(M2,n_R,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 15270c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 15280c7d97c5SJed Brown } 15290c7d97c5SJed Brown ierr = MatAssemblyBegin(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 15300c7d97c5SJed Brown ierr = MatAssemblyEnd(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 15310c7d97c5SJed Brown } 15320c7d97c5SJed Brown 15330c7d97c5SJed Brown /* Matrix of coarse basis functions (local) */ 1534d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 15350c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 15360c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_B,impMatType);CHKERRQ(ierr); 15373b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_phi_B,PETSC_NULL);CHKERRQ(ierr); 1538e269702eSStefano Zampini if(pcbddc->prec_type || dbg_flag ) { 1539d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 15400c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 15410c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_D,impMatType);CHKERRQ(ierr); 15423b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_phi_D,PETSC_NULL);CHKERRQ(ierr); 15430c7d97c5SJed Brown } 15440c7d97c5SJed Brown 1545e269702eSStefano Zampini if(dbg_flag) { 15460c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&coarsefunctions_errors);CHKERRQ(ierr); 15470c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&constraints_errors);CHKERRQ(ierr); 15480c7d97c5SJed Brown } 15493b03a366Sstefano_zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 15500c7d97c5SJed Brown ierr = PetscMalloc ((pcbddc->local_primal_size)*(pcbddc->local_primal_size)*sizeof(PetscScalar),&coarse_submat_vals);CHKERRQ(ierr); 15510c7d97c5SJed Brown 15520c7d97c5SJed Brown /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 15533b03a366Sstefano_zampini for(i=0;i<n_vertices;i++){ 15540c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 15550c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 15560c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 15570c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 15580c7d97c5SJed Brown /* solution of saddle point problem */ 15590c7d97c5SJed Brown ierr = MatMult(M2,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 15600c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_R,m_one);CHKERRQ(ierr); 15613b03a366Sstefano_zampini if(n_constraints) { 15620c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec1_R,vec1_C);CHKERRQ(ierr); 15630c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 15640c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 15650c7d97c5SJed Brown } 15660c7d97c5SJed Brown ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); 15670c7d97c5SJed Brown ierr = MatMultAdd(A_VV,vec1_V,vec2_V,vec2_V);CHKERRQ(ierr); 15680c7d97c5SJed Brown 15690c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 15700c7d97c5SJed Brown /* coarse basis functions */ 15710c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 15720c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15730c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15740c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 15753b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 15760c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 15770c7d97c5SJed Brown ierr = MatSetValue(pcbddc->coarse_phi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 1578e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 15790c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15800c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15810c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 15823b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 15830c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 15840c7d97c5SJed Brown } 15850c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 15860c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 1587*da1bb401SStefano Zampini for(j=0;j<n_vertices;j++) { coarse_submat_vals[i*pcbddc->local_primal_size+j] = array[j]; } /* WARNING -> column major ordering */ 15880c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 15893b03a366Sstefano_zampini if(n_constraints) { 15900c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 1591*da1bb401SStefano Zampini for(j=0;j<n_constraints;j++) { coarse_submat_vals[i*pcbddc->local_primal_size+j+n_vertices] = array[j]; } /* WARNING -> column major ordering */ 15920c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 15930c7d97c5SJed Brown } 15940c7d97c5SJed Brown 1595e269702eSStefano Zampini if( dbg_flag ) { 15960c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 1597d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 15980c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 15990c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 16000c7d97c5SJed Brown for(j=0;j<n_R;j++) { array[idx_R_local[j]] = array2[j]; } 16013b03a366Sstefano_zampini array[ vertices[i] ] = one; 16020c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 16030c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 16040c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers (i.e. primal nodes) */ 1605d49ef151SStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 16060c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 16070c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 16083b03a366Sstefano_zampini for(j=0;j<n_vertices;j++) { array2[j]=array[j]; } 16090c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 16103b03a366Sstefano_zampini if(n_constraints) { 16110c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 16123b03a366Sstefano_zampini for(j=0;j<n_constraints;j++) { array2[j+n_vertices]=array[j]; } 16130c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 16140c7d97c5SJed Brown } 16150c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 16160c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_P,m_one);CHKERRQ(ierr); 16170c7d97c5SJed Brown /* check saddle point solution */ 16180c7d97c5SJed Brown ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 16193b03a366Sstefano_zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 16203b03a366Sstefano_zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[i]);CHKERRQ(ierr); 16213b03a366Sstefano_zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 16220c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 16233b03a366Sstefano_zampini array[i]=array[i]+m_one; /* shift by the identity matrix */ 16240c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 16253b03a366Sstefano_zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[i]);CHKERRQ(ierr); 16260c7d97c5SJed Brown } 16270c7d97c5SJed Brown } 16280c7d97c5SJed Brown 16293b03a366Sstefano_zampini for(i=0;i<n_constraints;i++){ 1630d49ef151SStefano Zampini ierr = VecSet(vec2_C,zero);CHKERRQ(ierr); 16310c7d97c5SJed Brown ierr = VecSetValue(vec2_C,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 16320c7d97c5SJed Brown ierr = VecAssemblyBegin(vec2_C);CHKERRQ(ierr); 16330c7d97c5SJed Brown ierr = VecAssemblyEnd(vec2_C);CHKERRQ(ierr); 16340c7d97c5SJed Brown /* solution of saddle point problem */ 16350c7d97c5SJed Brown ierr = MatMult(M1,vec2_C,vec1_C);CHKERRQ(ierr); 16360c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 16370c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 16383b03a366Sstefano_zampini if(n_vertices) { ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); } 16390c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 16400c7d97c5SJed Brown /* coarse basis functions */ 16413b03a366Sstefano_zampini index=i+n_vertices; 16420c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 16430c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16440c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16450c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 164653cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 16470c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1648e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 16490c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16500c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16510c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 165253cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 16530c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 16540c7d97c5SJed Brown } 16550c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 16563b03a366Sstefano_zampini if(n_vertices) { 16570c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 1658*da1bb401SStefano Zampini for(j=0;j<n_vertices;j++) {coarse_submat_vals[index*pcbddc->local_primal_size+j]=array[j];} /* WARNING -> column major ordering */ 16590c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 16600c7d97c5SJed Brown } 16610c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 1662*da1bb401SStefano Zampini for(j=0;j<n_constraints;j++) {coarse_submat_vals[index*pcbddc->local_primal_size+j+n_vertices]=array[j];} /* WARNING -> column major ordering */ 16630c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 16640c7d97c5SJed Brown 1665e269702eSStefano Zampini if( dbg_flag ) { 16660c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 166753cdbc3dSStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 16680c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 16690c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 16700c7d97c5SJed Brown for(j=0;j<n_R;j++){ array[ idx_R_local[j] ] = array2[j]; } 16710c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 16720c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 16730c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers */ 167453cdbc3dSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 16750c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 16763b03a366Sstefano_zampini if( n_vertices) { 16770c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 16783b03a366Sstefano_zampini for(j=0;j<n_vertices;j++) {array2[j]=-array[j];} 16790c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 16800c7d97c5SJed Brown } 16810c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 16823b03a366Sstefano_zampini for(j=0;j<n_constraints;j++) {array2[j+n_vertices]=-array[j];} 16830c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 16840c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 16850c7d97c5SJed Brown /* check saddle point solution */ 16860c7d97c5SJed Brown ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 16873b03a366Sstefano_zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 168853cdbc3dSStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[index]);CHKERRQ(ierr); 16893b03a366Sstefano_zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 16900c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 169153cdbc3dSStefano Zampini array[index]=array[index]+m_one; /* shift by the identity matrix */ 16920c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 169353cdbc3dSStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[index]);CHKERRQ(ierr); 16940c7d97c5SJed Brown } 16950c7d97c5SJed Brown } 16960c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16970c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1698e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 16990c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17000c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17010c7d97c5SJed Brown } 17020c7d97c5SJed Brown /* Checking coarse_sub_mat and coarse basis functios */ 17030c7d97c5SJed Brown /* It shuld be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 17049d2fce94SStefano Zampini if(dbg_flag) { 17050c7d97c5SJed Brown 17060c7d97c5SJed Brown Mat coarse_sub_mat; 17070c7d97c5SJed Brown Mat TM1,TM2,TM3,TM4; 17080c7d97c5SJed Brown Mat coarse_phi_D,coarse_phi_B,A_II,A_BB,A_IB,A_BI; 1709a0ba757dSStefano Zampini const MatType checkmattype=MATSEQAIJ; 17100c7d97c5SJed Brown PetscScalar value; 17110c7d97c5SJed Brown 1712c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 1713c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 1714c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 1715c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 1716c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 1717c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 1718c042a7c3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 1719c042a7c3SStefano Zampini ierr = MatConvert(coarse_sub_mat,checkmattype,MAT_REUSE_MATRIX,&coarse_sub_mat);CHKERRQ(ierr); 17200c7d97c5SJed Brown 1721*da1bb401SStefano Zampini /*PetscViewer view_out; 1722*da1bb401SStefano Zampini PetscMPIInt myrank; 1723*da1bb401SStefano Zampini char filename[256]; 1724*da1bb401SStefano Zampini MPI_Comm_rank(((PetscObject)pc)->comm,&myrank); 1725*da1bb401SStefano Zampini sprintf(filename,"coarsesubmat_%04d.m",myrank); 1726*da1bb401SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&view_out);CHKERRQ(ierr); 1727*da1bb401SStefano Zampini ierr = PetscViewerSetFormat(view_out,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1728*da1bb401SStefano Zampini ierr = MatView(coarse_sub_mat,view_out);CHKERRQ(ierr); 1729*da1bb401SStefano Zampini ierr = PetscViewerDestroy(&view_out);CHKERRQ(ierr);*/ 1730*da1bb401SStefano Zampini 17310c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 17320c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Check coarse sub mat and local basis functions\n");CHKERRQ(ierr); 17330c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 173453cdbc3dSStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 173553cdbc3dSStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 173653cdbc3dSStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1737c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 173853cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 173953cdbc3dSStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1740c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 174153cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 174253cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 174353cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 174453cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 174553cdbc3dSStefano Zampini ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 174653cdbc3dSStefano Zampini ierr = MatNorm(TM1,NORM_INFINITY,&value);CHKERRQ(ierr); 17470c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"----------------------------------\n");CHKERRQ(ierr); 17480c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d \n",PetscGlobalRank);CHKERRQ(ierr); 17490c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"matrix error = % 1.14e\n",value);CHKERRQ(ierr); 17500c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"coarse functions errors\n");CHKERRQ(ierr); 175153cdbc3dSStefano 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); } 17520c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"constraints errors\n");CHKERRQ(ierr); 175353cdbc3dSStefano 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); } 17540c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 175553cdbc3dSStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 175653cdbc3dSStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 175753cdbc3dSStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 175853cdbc3dSStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 175953cdbc3dSStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 176053cdbc3dSStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 176153cdbc3dSStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 176253cdbc3dSStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 176353cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 176453cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 176553cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 17660c7d97c5SJed Brown ierr = PetscFree(coarsefunctions_errors);CHKERRQ(ierr); 17670c7d97c5SJed Brown ierr = PetscFree(constraints_errors);CHKERRQ(ierr); 17680c7d97c5SJed Brown } 17690c7d97c5SJed Brown 17700c7d97c5SJed Brown /* create coarse matrix and data structures for message passing associated actual choice of coarse problem type */ 17710c7d97c5SJed Brown ierr = PCBDDCSetupCoarseEnvironment(pc,coarse_submat_vals);CHKERRQ(ierr); 17720c7d97c5SJed Brown /* free memory */ 17730c7d97c5SJed Brown ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 17740c7d97c5SJed Brown ierr = PetscFree(auxindices);CHKERRQ(ierr); 17750c7d97c5SJed Brown ierr = PetscFree(nnz);CHKERRQ(ierr); 17763b03a366Sstefano_zampini if(n_vertices) { 17770c7d97c5SJed Brown ierr = VecDestroy(&vec1_V);CHKERRQ(ierr); 17780c7d97c5SJed Brown ierr = VecDestroy(&vec2_V);CHKERRQ(ierr); 17790c7d97c5SJed Brown ierr = MatDestroy(&M2);CHKERRQ(ierr); 17800c7d97c5SJed Brown ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 17810c7d97c5SJed Brown ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 17820c7d97c5SJed Brown ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 17830c7d97c5SJed Brown } 17840c7d97c5SJed Brown if(pcbddc->n_constraints) { 17850c7d97c5SJed Brown ierr = VecDestroy(&vec1_C);CHKERRQ(ierr); 17860c7d97c5SJed Brown ierr = VecDestroy(&vec2_C);CHKERRQ(ierr); 17870c7d97c5SJed Brown ierr = MatDestroy(&M1);CHKERRQ(ierr); 17880c7d97c5SJed Brown ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 17890c7d97c5SJed Brown } 17900c7d97c5SJed Brown } 17910c7d97c5SJed Brown /* free memory */ 17923b03a366Sstefano_zampini if(n_vertices) { 17930c7d97c5SJed Brown ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 17940c7d97c5SJed Brown ierr = ISDestroy(&is_V_local);CHKERRQ(ierr); 17950c7d97c5SJed Brown } 17960c7d97c5SJed Brown ierr = ISDestroy(&is_R_local);CHKERRQ(ierr); 17970c7d97c5SJed Brown 17980c7d97c5SJed Brown PetscFunctionReturn(0); 17990c7d97c5SJed Brown } 18000c7d97c5SJed Brown 18010c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 18020c7d97c5SJed Brown 18030c7d97c5SJed Brown #undef __FUNCT__ 18040c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetupCoarseEnvironment" 180553cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetupCoarseEnvironment(PC pc,PetscScalar* coarse_submat_vals) 18060c7d97c5SJed Brown { 18070c7d97c5SJed Brown 18080c7d97c5SJed Brown 18090c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 18100c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 18110c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 18120c7d97c5SJed Brown MPI_Comm prec_comm = ((PetscObject)pc)->comm; 18130c7d97c5SJed Brown MPI_Comm coarse_comm; 18140c7d97c5SJed Brown 18150c7d97c5SJed Brown /* common to all choiches */ 18160c7d97c5SJed Brown PetscScalar *temp_coarse_mat_vals; 18170c7d97c5SJed Brown PetscScalar *ins_coarse_mat_vals; 18180c7d97c5SJed Brown PetscInt *ins_local_primal_indices; 18190c7d97c5SJed Brown PetscMPIInt *localsizes2,*localdispl2; 18200c7d97c5SJed Brown PetscMPIInt size_prec_comm; 18210c7d97c5SJed Brown PetscMPIInt rank_prec_comm; 18220c7d97c5SJed Brown PetscMPIInt active_rank=MPI_PROC_NULL; 18230c7d97c5SJed Brown PetscMPIInt master_proc=0; 18240c7d97c5SJed Brown PetscInt ins_local_primal_size; 18250c7d97c5SJed Brown /* specific to MULTILEVEL_BDDC */ 18260c7d97c5SJed Brown PetscMPIInt *ranks_recv; 18270c7d97c5SJed Brown PetscMPIInt count_recv=0; 18280c7d97c5SJed Brown PetscMPIInt rank_coarse_proc_send_to; 18290c7d97c5SJed Brown PetscMPIInt coarse_color = MPI_UNDEFINED; 18300c7d97c5SJed Brown ISLocalToGlobalMapping coarse_ISLG; 18310c7d97c5SJed Brown /* some other variables */ 18320c7d97c5SJed Brown PetscErrorCode ierr; 18330c7d97c5SJed Brown const MatType coarse_mat_type; 18340c7d97c5SJed Brown const PCType coarse_pc_type; 183553cdbc3dSStefano Zampini const KSPType coarse_ksp_type; 183653cdbc3dSStefano Zampini PC pc_temp; 18370c7d97c5SJed Brown PetscInt i,j,k,bs; 18383b03a366Sstefano_zampini PetscInt max_it_coarse_ksp=1; /* don't increase this value */ 1839e269702eSStefano Zampini /* verbose output viewer */ 1840e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 1841e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 18420c7d97c5SJed Brown 18430c7d97c5SJed Brown PetscFunctionBegin; 18440c7d97c5SJed Brown 18450c7d97c5SJed Brown ins_local_primal_indices = 0; 18460c7d97c5SJed Brown ins_coarse_mat_vals = 0; 18470c7d97c5SJed Brown localsizes2 = 0; 18480c7d97c5SJed Brown localdispl2 = 0; 18490c7d97c5SJed Brown temp_coarse_mat_vals = 0; 18500c7d97c5SJed Brown coarse_ISLG = 0; 18510c7d97c5SJed Brown 185253cdbc3dSStefano Zampini ierr = MPI_Comm_size(prec_comm,&size_prec_comm);CHKERRQ(ierr); 185353cdbc3dSStefano Zampini ierr = MPI_Comm_rank(prec_comm,&rank_prec_comm);CHKERRQ(ierr); 18540c7d97c5SJed Brown ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 18550c7d97c5SJed Brown 1856beed3852SStefano Zampini /* Assign global numbering to coarse dofs */ 1857beed3852SStefano Zampini { 1858a0ba757dSStefano Zampini PetscScalar one=1.,zero=0.; 1859beed3852SStefano Zampini PetscScalar *array; 1860beed3852SStefano Zampini PetscMPIInt *auxlocal_primal; 1861beed3852SStefano Zampini PetscMPIInt *auxglobal_primal; 1862beed3852SStefano Zampini PetscMPIInt *all_auxglobal_primal; 1863beed3852SStefano Zampini PetscMPIInt *all_auxglobal_primal_dummy; 1864beed3852SStefano Zampini PetscMPIInt mpi_local_primal_size = (PetscMPIInt)pcbddc->local_primal_size; 1865*da1bb401SStefano Zampini PetscInt *row_cmat_indices; 18663b03a366Sstefano_zampini PetscInt size_of_constraint; 1867*da1bb401SStefano Zampini PetscScalar coarsesum; 1868beed3852SStefano Zampini 1869beed3852SStefano Zampini /* Construct needed data structures for message passing */ 1870beed3852SStefano Zampini ierr = PetscMalloc(mpi_local_primal_size*sizeof(PetscMPIInt),&pcbddc->local_primal_indices);CHKERRQ(ierr); 1871beed3852SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&pcbddc->local_primal_sizes);CHKERRQ(ierr); 1872beed3852SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 1873beed3852SStefano Zampini /* Gather local_primal_size information for all processes */ 18745619798eSStefano Zampini ierr = MPI_Allgather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,prec_comm);CHKERRQ(ierr); 1875beed3852SStefano Zampini pcbddc->replicated_primal_size = 0; 1876beed3852SStefano Zampini for (i=0; i<size_prec_comm; i++) { 1877beed3852SStefano Zampini pcbddc->local_primal_displacements[i] = pcbddc->replicated_primal_size ; 1878beed3852SStefano Zampini pcbddc->replicated_primal_size += pcbddc->local_primal_sizes[i]; 1879beed3852SStefano Zampini } 18805619798eSStefano Zampini if(rank_prec_comm == 0) { 1881beed3852SStefano Zampini /* allocate some auxiliary space */ 1882beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->replicated_primal_size*sizeof(*all_auxglobal_primal),&all_auxglobal_primal);CHKERRQ(ierr); 1883beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->replicated_primal_size*sizeof(*all_auxglobal_primal_dummy),&all_auxglobal_primal_dummy);CHKERRQ(ierr); 1884beed3852SStefano Zampini } 1885beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscMPIInt),&auxlocal_primal);CHKERRQ(ierr); 1886beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscMPIInt),&auxglobal_primal);CHKERRQ(ierr); 1887beed3852SStefano Zampini 1888*da1bb401SStefano Zampini /* First let's count coarse dofs. 1889beed3852SStefano Zampini This code fragment assumes that the number of local constraints per connected component 1890beed3852SStefano Zampini is not greater than the number of nodes defined for the connected component 1891beed3852SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 18923b03a366Sstefano_zampini /* auxlocal_primal : primal indices in local nodes numbering (internal and interface) with complete queue sorted by global ordering */ 1893beed3852SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 1894beed3852SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1895*da1bb401SStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) { 1896*da1bb401SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 18973b03a366Sstefano_zampini for (j=0; j<size_of_constraint; j++) { 18983b03a366Sstefano_zampini k = row_cmat_indices[j]; 1899beed3852SStefano Zampini if( array[k] == zero ) { 1900beed3852SStefano Zampini array[k] = one; 1901*da1bb401SStefano Zampini auxlocal_primal[i] = k; 1902beed3852SStefano Zampini break; 1903beed3852SStefano Zampini } 1904beed3852SStefano Zampini } 1905*da1bb401SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 1906beed3852SStefano Zampini } 1907beed3852SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1908*da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 1909*da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1910*da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1911*da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1912*da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1913*da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1914*da1bb401SStefano Zampini for(i=0;i<pcis->n;i++) { if( array[i] > zero) array[i] = one/array[i]; } 1915*da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1916*da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 1917*da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1918*da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1919*da1bb401SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 1920*da1bb401SStefano Zampini pcbddc->coarse_size = (PetscInt) coarsesum; 1921a0ba757dSStefano Zampini 1922beed3852SStefano Zampini /* Now assign them a global numbering */ 1923beed3852SStefano Zampini /* auxglobal_primal contains indices in global nodes numbering (internal and interface) */ 1924beed3852SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,pcbddc->local_primal_size,auxlocal_primal,auxglobal_primal);CHKERRQ(ierr); 1925beed3852SStefano Zampini /* all_auxglobal_primal contains all primal nodes indices in global nodes numbering (internal and interface) */ 1926beed3852SStefano 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); 1927beed3852SStefano Zampini 1928beed3852SStefano Zampini /* After this block all_auxglobal_primal should contains one copy of each primal node's indices in global nodes numbering */ 1929beed3852SStefano Zampini /* It implements a function similar to PetscSortRemoveDupsInt */ 1930beed3852SStefano Zampini if(rank_prec_comm==0) { 1931beed3852SStefano Zampini /* dummy argument since PetscSortMPIInt doesn't exist! */ 1932beed3852SStefano Zampini ierr = PetscSortMPIIntWithArray(pcbddc->replicated_primal_size,all_auxglobal_primal,all_auxglobal_primal_dummy);CHKERRQ(ierr); 1933beed3852SStefano Zampini k=1; 1934beed3852SStefano Zampini j=all_auxglobal_primal[0]; /* first dof in global numbering */ 1935beed3852SStefano Zampini for(i=1;i< pcbddc->replicated_primal_size ;i++) { 1936beed3852SStefano Zampini if(j != all_auxglobal_primal[i] ) { 1937beed3852SStefano Zampini all_auxglobal_primal[k]=all_auxglobal_primal[i]; 1938beed3852SStefano Zampini k++; 1939beed3852SStefano Zampini j=all_auxglobal_primal[i]; 1940beed3852SStefano Zampini } 1941beed3852SStefano Zampini } 1942beed3852SStefano Zampini } else { 1943beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscMPIInt),&all_auxglobal_primal);CHKERRQ(ierr); 1944beed3852SStefano Zampini } 19455619798eSStefano Zampini /* We only need to broadcast the indices from 0 to pcbddc->coarse_size. Remaning elements of array all_aux_global_primal are garbage. */ 1946beed3852SStefano Zampini ierr = MPI_Bcast(all_auxglobal_primal,pcbddc->coarse_size,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 1947beed3852SStefano Zampini 1948beed3852SStefano Zampini /* Now get global coarse numbering of local primal nodes */ 1949beed3852SStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) { 1950beed3852SStefano Zampini k=0; 1951beed3852SStefano Zampini while( all_auxglobal_primal[k] != auxglobal_primal[i] ) { k++;} 1952beed3852SStefano Zampini pcbddc->local_primal_indices[i]=k; 1953beed3852SStefano Zampini } 1954e269702eSStefano Zampini if(dbg_flag) { 1955e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1956*da1bb401SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem %d\n",pcbddc->coarse_size);CHKERRQ(ierr); 1957e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1958e269702eSStefano Zampini } 1959beed3852SStefano Zampini /* free allocated memory */ 1960beed3852SStefano Zampini ierr = PetscFree(auxlocal_primal);CHKERRQ(ierr); 1961beed3852SStefano Zampini ierr = PetscFree(auxglobal_primal);CHKERRQ(ierr); 1962beed3852SStefano Zampini ierr = PetscFree(all_auxglobal_primal);CHKERRQ(ierr); 1963e269702eSStefano Zampini if(rank_prec_comm == 0) { 1964beed3852SStefano Zampini ierr = PetscFree(all_auxglobal_primal_dummy);CHKERRQ(ierr); 1965beed3852SStefano Zampini } 1966e269702eSStefano Zampini } 1967beed3852SStefano Zampini 19680c7d97c5SJed Brown /* adapt coarse problem type */ 19690c7d97c5SJed Brown if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC && pcbddc->active_procs < MIN_PROCS_FOR_BDDC ) 19700c7d97c5SJed Brown pcbddc->coarse_problem_type = PARALLEL_BDDC; 19710c7d97c5SJed Brown 19720c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 19730c7d97c5SJed Brown 1974*da1bb401SStefano Zampini case(MULTILEVEL_BDDC): /* we define a coarse mesh where subdomains are elements */ 19750c7d97c5SJed Brown { 19760c7d97c5SJed Brown /* we need additional variables */ 19770c7d97c5SJed Brown MetisInt n_subdomains,n_parts,objval,ncon,faces_nvtxs; 19780c7d97c5SJed Brown MetisInt *metis_coarse_subdivision; 19790c7d97c5SJed Brown MetisInt options[METIS_NOPTIONS]; 19800c7d97c5SJed Brown PetscMPIInt size_coarse_comm,rank_coarse_comm; 19810c7d97c5SJed Brown PetscMPIInt procs_jumps_coarse_comm; 19820c7d97c5SJed Brown PetscMPIInt *coarse_subdivision; 19830c7d97c5SJed Brown PetscMPIInt *total_count_recv; 19840c7d97c5SJed Brown PetscMPIInt *total_ranks_recv; 19850c7d97c5SJed Brown PetscMPIInt *displacements_recv; 19860c7d97c5SJed Brown PetscMPIInt *my_faces_connectivity; 19870c7d97c5SJed Brown PetscMPIInt *petsc_faces_adjncy; 19880c7d97c5SJed Brown MetisInt *faces_adjncy; 19890c7d97c5SJed Brown MetisInt *faces_xadj; 19900c7d97c5SJed Brown PetscMPIInt *number_of_faces; 19910c7d97c5SJed Brown PetscMPIInt *faces_displacements; 19920c7d97c5SJed Brown PetscInt *array_int; 19930c7d97c5SJed Brown PetscMPIInt my_faces=0; 19940c7d97c5SJed Brown PetscMPIInt total_faces=0; 19953828260eSStefano Zampini PetscInt ranks_stretching_ratio; 19960c7d97c5SJed Brown 19970c7d97c5SJed Brown /* define some quantities */ 19980c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 19990c7d97c5SJed Brown coarse_mat_type = MATIS; 20000c7d97c5SJed Brown coarse_pc_type = PCBDDC; 20016c9de887SHong Zhang coarse_ksp_type = KSPCHEBYSHEV; 20020c7d97c5SJed Brown 20030c7d97c5SJed Brown /* details of coarse decomposition */ 20040c7d97c5SJed Brown n_subdomains = pcbddc->active_procs; 20050c7d97c5SJed Brown n_parts = n_subdomains/pcbddc->coarsening_ratio; 20063828260eSStefano Zampini ranks_stretching_ratio = size_prec_comm/pcbddc->active_procs; 20073828260eSStefano Zampini procs_jumps_coarse_comm = pcbddc->coarsening_ratio*ranks_stretching_ratio; 20083828260eSStefano Zampini 2009*da1bb401SStefano Zampini /*printf("Coarse algorithm details: \n"); 2010*da1bb401SStefano 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));*/ 20110c7d97c5SJed Brown 20120c7d97c5SJed Brown /* build CSR graph of subdomains' connectivity through faces */ 20130c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&array_int);CHKERRQ(ierr); 20143828260eSStefano Zampini ierr = PetscMemzero(array_int,pcis->n*sizeof(PetscInt));CHKERRQ(ierr); 20150c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){/* i=1 so I don't count myself -> faces nodes counts to 1 */ 20160c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 20170c7d97c5SJed Brown array_int[ pcis->shared[i][j] ]+=1; 20180c7d97c5SJed Brown } 20190c7d97c5SJed Brown } 20200c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){ 20210c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 20220c7d97c5SJed Brown if(array_int[ pcis->shared[i][j] ] == 1 ){ 20230c7d97c5SJed Brown my_faces++; 20240c7d97c5SJed Brown break; 20250c7d97c5SJed Brown } 20260c7d97c5SJed Brown } 20270c7d97c5SJed Brown } 20280c7d97c5SJed Brown 202953cdbc3dSStefano Zampini ierr = MPI_Reduce(&my_faces,&total_faces,1,MPIU_INT,MPI_SUM,master_proc,prec_comm);CHKERRQ(ierr); 20300c7d97c5SJed Brown ierr = PetscMalloc (my_faces*sizeof(PetscInt),&my_faces_connectivity);CHKERRQ(ierr); 20310c7d97c5SJed Brown my_faces=0; 20320c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){ 20330c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 20340c7d97c5SJed Brown if(array_int[ pcis->shared[i][j] ] == 1 ){ 20350c7d97c5SJed Brown my_faces_connectivity[my_faces]=pcis->neigh[i]; 20360c7d97c5SJed Brown my_faces++; 20370c7d97c5SJed Brown break; 20380c7d97c5SJed Brown } 20390c7d97c5SJed Brown } 20400c7d97c5SJed Brown } 20410c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 20420c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(PetscMPIInt),&petsc_faces_adjncy);CHKERRQ(ierr); 20430c7d97c5SJed Brown ierr = PetscMalloc (size_prec_comm*sizeof(PetscMPIInt),&number_of_faces);CHKERRQ(ierr); 20440c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(MetisInt),&faces_adjncy);CHKERRQ(ierr); 20450c7d97c5SJed Brown ierr = PetscMalloc ((n_subdomains+1)*sizeof(MetisInt),&faces_xadj);CHKERRQ(ierr); 20460c7d97c5SJed Brown ierr = PetscMalloc ((size_prec_comm+1)*sizeof(PetscMPIInt),&faces_displacements);CHKERRQ(ierr); 20470c7d97c5SJed Brown } 204853cdbc3dSStefano Zampini ierr = MPI_Gather(&my_faces,1,MPIU_INT,&number_of_faces[0],1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 20490c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 20500c7d97c5SJed Brown faces_xadj[0]=0; 20510c7d97c5SJed Brown faces_displacements[0]=0; 20520c7d97c5SJed Brown j=0; 20530c7d97c5SJed Brown for(i=1;i<size_prec_comm+1;i++) { 20540c7d97c5SJed Brown faces_displacements[i]=faces_displacements[i-1]+number_of_faces[i-1]; 20550c7d97c5SJed Brown if(number_of_faces[i-1]) { 20560c7d97c5SJed Brown j++; 20570c7d97c5SJed Brown faces_xadj[j]=faces_xadj[j-1]+number_of_faces[i-1]; 20580c7d97c5SJed Brown } 20590c7d97c5SJed Brown } 2060*da1bb401SStefano Zampini /*printf("The J I count is %d and should be %d\n",j,n_subdomains); 2061*da1bb401SStefano Zampini printf("Total faces seem %d and should be %d\n",faces_xadj[j],total_faces);*/ 20620c7d97c5SJed Brown } 206353cdbc3dSStefano 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); 20640c7d97c5SJed Brown ierr = PetscFree(my_faces_connectivity);CHKERRQ(ierr); 20650c7d97c5SJed Brown ierr = PetscFree(array_int);CHKERRQ(ierr); 20660c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 20673828260eSStefano Zampini for(i=0;i<total_faces;i++) faces_adjncy[i]=(MetisInt)(petsc_faces_adjncy[i]/ranks_stretching_ratio); /* cast to MetisInt */ 2068*da1bb401SStefano Zampini /*printf("This is the face connectivity (actual ranks)\n"); 20690c7d97c5SJed Brown for(i=0;i<n_subdomains;i++){ 20700c7d97c5SJed Brown printf("proc %d is connected with \n",i); 20710c7d97c5SJed Brown for(j=faces_xadj[i];j<faces_xadj[i+1];j++) 20720c7d97c5SJed Brown printf("%d ",faces_adjncy[j]); 20730c7d97c5SJed Brown printf("\n"); 2074*da1bb401SStefano Zampini }*/ 20750c7d97c5SJed Brown ierr = PetscFree(faces_displacements);CHKERRQ(ierr); 20760c7d97c5SJed Brown ierr = PetscFree(number_of_faces);CHKERRQ(ierr); 20770c7d97c5SJed Brown ierr = PetscFree(petsc_faces_adjncy);CHKERRQ(ierr); 20780c7d97c5SJed Brown } 20790c7d97c5SJed Brown 20800c7d97c5SJed Brown if( rank_prec_comm == master_proc ) { 20810c7d97c5SJed Brown 20823828260eSStefano Zampini PetscInt heuristic_for_metis=3; 20833828260eSStefano Zampini 20840c7d97c5SJed Brown ncon=1; 20850c7d97c5SJed Brown faces_nvtxs=n_subdomains; 20860c7d97c5SJed Brown /* partition graoh induced by face connectivity */ 20870c7d97c5SJed Brown ierr = PetscMalloc (n_subdomains*sizeof(MetisInt),&metis_coarse_subdivision);CHKERRQ(ierr); 20880c7d97c5SJed Brown ierr = METIS_SetDefaultOptions(options); 20890c7d97c5SJed Brown /* we need a contiguous partition of the coarse mesh */ 20900c7d97c5SJed Brown options[METIS_OPTION_CONTIG]=1; 20910c7d97c5SJed Brown options[METIS_OPTION_DBGLVL]=1; 20920c7d97c5SJed Brown options[METIS_OPTION_NITER]=30; 20933828260eSStefano Zampini if(n_subdomains>n_parts*heuristic_for_metis) { 20943828260eSStefano Zampini options[METIS_OPTION_IPTYPE]=METIS_IPTYPE_EDGE; 20953828260eSStefano Zampini options[METIS_OPTION_OBJTYPE]=METIS_OBJTYPE_CUT; 20960c7d97c5SJed Brown ierr = METIS_PartGraphKway(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 20973828260eSStefano Zampini } else { 20983828260eSStefano Zampini ierr = METIS_PartGraphRecursive(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 20993828260eSStefano Zampini } 21000c7d97c5SJed 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); 21010c7d97c5SJed Brown ierr = PetscFree(faces_xadj);CHKERRQ(ierr); 21020c7d97c5SJed Brown ierr = PetscFree(faces_adjncy);CHKERRQ(ierr); 21030c7d97c5SJed Brown coarse_subdivision = (PetscMPIInt*)calloc(size_prec_comm,sizeof(PetscMPIInt)); /* calloc for contiguous memory since we need to scatter these values later */ 21040c7d97c5SJed Brown /* copy/cast values avoiding possible type conflicts between PETSc, MPI and METIS */ 21053828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) coarse_subdivision[i]=MPI_PROC_NULL; 21063828260eSStefano Zampini for(i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=(PetscInt)(metis_coarse_subdivision[i]); 21070c7d97c5SJed Brown ierr = PetscFree(metis_coarse_subdivision);CHKERRQ(ierr); 21080c7d97c5SJed Brown } 21090c7d97c5SJed Brown 21100c7d97c5SJed Brown /* Create new communicator for coarse problem splitting the old one */ 21110c7d97c5SJed Brown if( !(rank_prec_comm%procs_jumps_coarse_comm) && rank_prec_comm < procs_jumps_coarse_comm*n_parts ){ 2112*da1bb401SStefano Zampini coarse_color=0; /* for communicator splitting */ 2113*da1bb401SStefano Zampini active_rank=rank_prec_comm; /* for insertion of matrix values */ 21140c7d97c5SJed Brown } 2115*da1bb401SStefano Zampini /* procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 2116*da1bb401SStefano Zampini key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator */ 211753cdbc3dSStefano Zampini ierr = MPI_Comm_split(prec_comm,coarse_color,rank_prec_comm,&coarse_comm);CHKERRQ(ierr); 21180c7d97c5SJed Brown 21190c7d97c5SJed Brown if( coarse_color == 0 ) { 212053cdbc3dSStefano Zampini ierr = MPI_Comm_size(coarse_comm,&size_coarse_comm);CHKERRQ(ierr); 212153cdbc3dSStefano Zampini ierr = MPI_Comm_rank(coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 2122*da1bb401SStefano Zampini /*printf("Details of coarse comm\n"); 21233828260eSStefano Zampini printf("size = %d, myrank = %d\n",size_coarse_comm,rank_coarse_comm); 2124*da1bb401SStefano Zampini printf("jumps = %d, coarse_color = %d, n_parts = %d\n",procs_jumps_coarse_comm,coarse_color,n_parts);*/ 21250c7d97c5SJed Brown } else { 21260c7d97c5SJed Brown rank_coarse_comm = MPI_PROC_NULL; 21270c7d97c5SJed Brown } 21280c7d97c5SJed Brown 21290c7d97c5SJed Brown /* master proc take care of arranging and distributing coarse informations */ 21300c7d97c5SJed Brown if(rank_coarse_comm == master_proc) { 21310c7d97c5SJed Brown ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&displacements_recv);CHKERRQ(ierr); 2132*da1bb401SStefano Zampini /*ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&total_count_recv);CHKERRQ(ierr); 2133*da1bb401SStefano Zampini ierr = PetscMalloc (n_subdomains*sizeof(PetscMPIInt),&total_ranks_recv);CHKERRQ(ierr);*/ 21340c7d97c5SJed Brown total_count_recv = (PetscMPIInt*)calloc(size_prec_comm,sizeof(PetscMPIInt)); 21350c7d97c5SJed Brown total_ranks_recv = (PetscMPIInt*)calloc(n_subdomains,sizeof(PetscMPIInt)); 21360c7d97c5SJed Brown /* some initializations */ 21370c7d97c5SJed Brown displacements_recv[0]=0; 2138*da1bb401SStefano Zampini /* PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt)); not needed -> calloc initializes to zero */ 21390c7d97c5SJed Brown /* count from how many processes the j-th process of the coarse decomposition will receive data */ 21400c7d97c5SJed Brown for(j=0;j<size_coarse_comm;j++) 21413828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) 21420c7d97c5SJed Brown if(coarse_subdivision[i]==j) 21430c7d97c5SJed Brown total_count_recv[j]++; 21440c7d97c5SJed Brown /* displacements needed for scatterv of total_ranks_recv */ 21450c7d97c5SJed Brown for(i=1;i<size_coarse_comm;i++) displacements_recv[i]=displacements_recv[i-1]+total_count_recv[i-1]; 21460c7d97c5SJed Brown /* Now fill properly total_ranks_recv -> each coarse process will receive the ranks (in prec_comm communicator) of its friend (sending) processes */ 21470c7d97c5SJed Brown ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 21480c7d97c5SJed Brown for(j=0;j<size_coarse_comm;j++) { 21493828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) { 21500c7d97c5SJed Brown if(coarse_subdivision[i]==j) { 21510c7d97c5SJed Brown total_ranks_recv[displacements_recv[j]+total_count_recv[j]]=i; 21523828260eSStefano Zampini total_count_recv[j]+=1; 21530c7d97c5SJed Brown } 21540c7d97c5SJed Brown } 21550c7d97c5SJed Brown } 2156*da1bb401SStefano Zampini /*for(j=0;j<size_coarse_comm;j++) { 21573828260eSStefano Zampini printf("process %d in new rank will receive from %d processes (original ranks follows)\n",j,total_count_recv[j]); 21583828260eSStefano Zampini for(i=0;i<total_count_recv[j];i++) { 21593828260eSStefano Zampini printf("%d ",total_ranks_recv[displacements_recv[j]+i]); 21603828260eSStefano Zampini } 21613828260eSStefano Zampini printf("\n"); 2162*da1bb401SStefano Zampini }*/ 21630c7d97c5SJed Brown 21640c7d97c5SJed Brown /* identify new decomposition in terms of ranks in the old communicator */ 21653828260eSStefano Zampini for(i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=coarse_subdivision[ranks_stretching_ratio*i]*procs_jumps_coarse_comm; 2166*da1bb401SStefano Zampini /*printf("coarse_subdivision in old end new ranks\n"); 21670c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) 21683828260eSStefano Zampini if(coarse_subdivision[i]!=MPI_PROC_NULL) { 21693828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]/procs_jumps_coarse_comm); 21703828260eSStefano Zampini } else { 21713828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]); 21723828260eSStefano Zampini } 2173*da1bb401SStefano Zampini printf("\n");*/ 21740c7d97c5SJed Brown } 21750c7d97c5SJed Brown 21760c7d97c5SJed Brown /* Scatter new decomposition for send details */ 217753cdbc3dSStefano Zampini ierr = MPI_Scatter(&coarse_subdivision[0],1,MPIU_INT,&rank_coarse_proc_send_to,1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 21780c7d97c5SJed Brown /* Scatter receiving details to members of coarse decomposition */ 21790c7d97c5SJed Brown if( coarse_color == 0) { 218053cdbc3dSStefano Zampini ierr = MPI_Scatter(&total_count_recv[0],1,MPIU_INT,&count_recv,1,MPIU_INT,master_proc,coarse_comm);CHKERRQ(ierr); 21810c7d97c5SJed Brown ierr = PetscMalloc (count_recv*sizeof(PetscMPIInt),&ranks_recv);CHKERRQ(ierr); 218253cdbc3dSStefano 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); 21830c7d97c5SJed Brown } 21840c7d97c5SJed Brown 2185*da1bb401SStefano Zampini /*printf("I will send my matrix data to proc %d\n",rank_coarse_proc_send_to); 2186*da1bb401SStefano Zampini if(coarse_color == 0) { 2187*da1bb401SStefano Zampini printf("I will receive some matrix data from %d processes (ranks follows)\n",count_recv); 2188*da1bb401SStefano Zampini for(i=0;i<count_recv;i++) 2189*da1bb401SStefano Zampini printf("%d ",ranks_recv[i]); 2190*da1bb401SStefano Zampini printf("\n"); 2191*da1bb401SStefano Zampini }*/ 21920c7d97c5SJed Brown 21930c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 2194*da1bb401SStefano Zampini /*ierr = PetscFree(coarse_subdivision);CHKERRQ(ierr); 2195*da1bb401SStefano Zampini ierr = PetscFree(total_count_recv);CHKERRQ(ierr); 2196*da1bb401SStefano Zampini ierr = PetscFree(total_ranks_recv);CHKERRQ(ierr);*/ 21970c7d97c5SJed Brown free(coarse_subdivision); 21980c7d97c5SJed Brown free(total_count_recv); 21990c7d97c5SJed Brown free(total_ranks_recv); 22000c7d97c5SJed Brown ierr = PetscFree(displacements_recv);CHKERRQ(ierr); 22010c7d97c5SJed Brown } 22020c7d97c5SJed Brown break; 22030c7d97c5SJed Brown } 22040c7d97c5SJed Brown 22050c7d97c5SJed Brown case(REPLICATED_BDDC): 22060c7d97c5SJed Brown 22070c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 22080c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 22090c7d97c5SJed Brown coarse_pc_type = PCLU; 221053cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 22110c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 22120c7d97c5SJed Brown active_rank = rank_prec_comm; 22130c7d97c5SJed Brown break; 22140c7d97c5SJed Brown 22150c7d97c5SJed Brown case(PARALLEL_BDDC): 22160c7d97c5SJed Brown 22170c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 22180c7d97c5SJed Brown coarse_mat_type = MATMPIAIJ; 22190c7d97c5SJed Brown coarse_pc_type = PCREDUNDANT; 222053cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 22210c7d97c5SJed Brown coarse_comm = prec_comm; 22220c7d97c5SJed Brown active_rank = rank_prec_comm; 22230c7d97c5SJed Brown break; 22240c7d97c5SJed Brown 22250c7d97c5SJed Brown case(SEQUENTIAL_BDDC): 22260c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 22270c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 22280c7d97c5SJed Brown coarse_pc_type = PCLU; 222953cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 22300c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 22310c7d97c5SJed Brown active_rank = master_proc; 22320c7d97c5SJed Brown break; 22330c7d97c5SJed Brown } 22340c7d97c5SJed Brown 22350c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 22360c7d97c5SJed Brown 22370c7d97c5SJed Brown case(SCATTERS_BDDC): 22380c7d97c5SJed Brown { 22390c7d97c5SJed Brown if(pcbddc->coarse_problem_type==MULTILEVEL_BDDC) { 22400c7d97c5SJed Brown 22410c7d97c5SJed Brown PetscMPIInt send_size; 22420c7d97c5SJed Brown PetscInt *aux_ins_indices; 22430c7d97c5SJed Brown PetscInt ii,jj; 22440c7d97c5SJed Brown MPI_Request *requests; 22450c7d97c5SJed Brown 22460c7d97c5SJed Brown /* allocate auxiliary space */ 22475619798eSStefano Zampini ierr = PetscMalloc (pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 22485619798eSStefano 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); 22490c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->coarse_size*sizeof(PetscInt),&aux_ins_indices);CHKERRQ(ierr); 22500c7d97c5SJed Brown ierr = PetscMemzero(aux_ins_indices,pcbddc->coarse_size*sizeof(PetscInt));CHKERRQ(ierr); 22510c7d97c5SJed Brown /* allocate stuffs for message massing */ 22520c7d97c5SJed Brown ierr = PetscMalloc ( (count_recv+1)*sizeof(MPI_Request),&requests);CHKERRQ(ierr); 22530c7d97c5SJed Brown for(i=0;i<count_recv+1;i++) requests[i]=MPI_REQUEST_NULL; 22540c7d97c5SJed Brown ierr = PetscMalloc ( count_recv*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 22550c7d97c5SJed Brown ierr = PetscMalloc ( count_recv*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 22560c7d97c5SJed Brown /* fill up quantities */ 22570c7d97c5SJed Brown j=0; 22580c7d97c5SJed Brown for(i=0;i<count_recv;i++){ 22590c7d97c5SJed Brown ii = ranks_recv[i]; 22600c7d97c5SJed Brown localsizes2[i]=pcbddc->local_primal_sizes[ii]*pcbddc->local_primal_sizes[ii]; 22610c7d97c5SJed Brown localdispl2[i]=j; 22620c7d97c5SJed Brown j+=localsizes2[i]; 22630c7d97c5SJed Brown jj = pcbddc->local_primal_displacements[ii]; 2264*da1bb401SStefano Zampini 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 */ 22650c7d97c5SJed Brown } 2266*da1bb401SStefano Zampini /*printf("aux_ins_indices 1\n"); 2267*da1bb401SStefano Zampini for(i=0;i<pcbddc->coarse_size;i++) 2268*da1bb401SStefano Zampini printf("%d ",aux_ins_indices[i]); 2269*da1bb401SStefano Zampini printf("\n");*/ 22700c7d97c5SJed Brown /* temp_coarse_mat_vals used to store temporarly received matrix values */ 22710c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 22720c7d97c5SJed Brown /* evaluate how many values I will insert in coarse mat */ 22730c7d97c5SJed Brown ins_local_primal_size=0; 22740c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++) 22750c7d97c5SJed Brown if(aux_ins_indices[i]) 22760c7d97c5SJed Brown ins_local_primal_size++; 22770c7d97c5SJed Brown /* evaluate indices I will insert in coarse mat */ 22780c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 22790c7d97c5SJed Brown j=0; 22800c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++) 22810c7d97c5SJed Brown if(aux_ins_indices[i]) 22820c7d97c5SJed Brown ins_local_primal_indices[j++]=i; 22830c7d97c5SJed Brown /* use aux_ins_indices to realize a global to local mapping */ 22840c7d97c5SJed Brown j=0; 22850c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++){ 22860c7d97c5SJed Brown if(aux_ins_indices[i]==0){ 22870c7d97c5SJed Brown aux_ins_indices[i]=-1; 22880c7d97c5SJed Brown } else { 22890c7d97c5SJed Brown aux_ins_indices[i]=j; 22900c7d97c5SJed Brown j++; 22910c7d97c5SJed Brown } 22920c7d97c5SJed Brown } 22930c7d97c5SJed Brown 2294*da1bb401SStefano Zampini /*printf("New details localsizes2 localdispl2\n"); 2295*da1bb401SStefano Zampini for(i=0;i<count_recv;i++) 2296*da1bb401SStefano Zampini printf("(%d %d) ",localsizes2[i],localdispl2[i]); 2297*da1bb401SStefano Zampini printf("\n"); 2298*da1bb401SStefano Zampini printf("aux_ins_indices 2\n"); 2299*da1bb401SStefano Zampini for(i=0;i<pcbddc->coarse_size;i++) 2300*da1bb401SStefano Zampini printf("%d ",aux_ins_indices[i]); 2301*da1bb401SStefano Zampini printf("\n"); 2302*da1bb401SStefano Zampini printf("ins_local_primal_indices\n"); 2303*da1bb401SStefano Zampini for(i=0;i<ins_local_primal_size;i++) 2304*da1bb401SStefano Zampini printf("%d ",ins_local_primal_indices[i]); 2305*da1bb401SStefano Zampini printf("\n"); 2306*da1bb401SStefano Zampini printf("coarse_submat_vals\n"); 2307*da1bb401SStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) 2308*da1bb401SStefano Zampini for(j=0;j<pcbddc->local_primal_size;j++) 2309*da1bb401SStefano Zampini printf("(%lf %d %d)\n",coarse_submat_vals[j*pcbddc->local_primal_size+i],pcbddc->local_primal_indices[i],pcbddc->local_primal_indices[j]); 2310*da1bb401SStefano Zampini printf("\n");*/ 23110c7d97c5SJed Brown 23120c7d97c5SJed Brown /* processes partecipating in coarse problem receive matrix data from their friends */ 231353cdbc3dSStefano 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); 23140c7d97c5SJed Brown if(rank_coarse_proc_send_to != MPI_PROC_NULL ) { 23150c7d97c5SJed Brown send_size=pcbddc->local_primal_size*pcbddc->local_primal_size; 231653cdbc3dSStefano 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); 23170c7d97c5SJed Brown } 231853cdbc3dSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 23190c7d97c5SJed Brown 2320*da1bb401SStefano Zampini /*if(coarse_color == 0) { 2321*da1bb401SStefano Zampini printf("temp_coarse_mat_vals\n"); 2322*da1bb401SStefano Zampini for(k=0;k<count_recv;k++){ 2323*da1bb401SStefano Zampini printf("---- %d ----\n",ranks_recv[k]); 2324*da1bb401SStefano Zampini for(i=0;i<pcbddc->local_primal_sizes[ranks_recv[k]];i++) 2325*da1bb401SStefano Zampini for(j=0;j<pcbddc->local_primal_sizes[ranks_recv[k]];j++) 2326*da1bb401SStefano Zampini 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]); 2327*da1bb401SStefano Zampini printf("\n"); 2328*da1bb401SStefano Zampini } 2329*da1bb401SStefano Zampini }*/ 23300c7d97c5SJed Brown /* calculate data to insert in coarse mat */ 23310c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 23320c7d97c5SJed Brown PetscMemzero(ins_coarse_mat_vals,ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar)); 23330c7d97c5SJed Brown 23340c7d97c5SJed Brown PetscMPIInt rr,kk,lps,lpd; 23350c7d97c5SJed Brown PetscInt row_ind,col_ind; 23360c7d97c5SJed Brown for(k=0;k<count_recv;k++){ 23370c7d97c5SJed Brown rr = ranks_recv[k]; 23380c7d97c5SJed Brown kk = localdispl2[k]; 23390c7d97c5SJed Brown lps = pcbddc->local_primal_sizes[rr]; 23400c7d97c5SJed Brown lpd = pcbddc->local_primal_displacements[rr]; 2341*da1bb401SStefano Zampini /*printf("Inserting the following indices (received from %d)\n",rr);*/ 23420c7d97c5SJed Brown for(j=0;j<lps;j++){ 23430c7d97c5SJed Brown col_ind=aux_ins_indices[pcbddc->replicated_local_primal_indices[lpd+j]]; 23440c7d97c5SJed Brown for(i=0;i<lps;i++){ 23450c7d97c5SJed Brown row_ind=aux_ins_indices[pcbddc->replicated_local_primal_indices[lpd+i]]; 2346*da1bb401SStefano Zampini /*printf("%d %d\n",row_ind,col_ind);*/ 23470c7d97c5SJed Brown ins_coarse_mat_vals[col_ind*ins_local_primal_size+row_ind]+=temp_coarse_mat_vals[kk+j*lps+i]; 23480c7d97c5SJed Brown } 23490c7d97c5SJed Brown } 23500c7d97c5SJed Brown } 23510c7d97c5SJed Brown ierr = PetscFree(requests);CHKERRQ(ierr); 23520c7d97c5SJed Brown ierr = PetscFree(aux_ins_indices);CHKERRQ(ierr); 23530c7d97c5SJed Brown ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr); 23540c7d97c5SJed Brown if(coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 23550c7d97c5SJed Brown 23560c7d97c5SJed Brown /* create local to global mapping needed by coarse MATIS */ 23570c7d97c5SJed Brown { 23580c7d97c5SJed Brown IS coarse_IS; 235953cdbc3dSStefano Zampini if(coarse_comm != MPI_COMM_NULL ) ierr = MPI_Comm_free(&coarse_comm);CHKERRQ(ierr); 23600c7d97c5SJed Brown coarse_comm = prec_comm; 23610c7d97c5SJed Brown active_rank=rank_prec_comm; 23620c7d97c5SJed Brown ierr = ISCreateGeneral(coarse_comm,ins_local_primal_size,ins_local_primal_indices,PETSC_COPY_VALUES,&coarse_IS);CHKERRQ(ierr); 23630c7d97c5SJed Brown ierr = ISLocalToGlobalMappingCreateIS(coarse_IS,&coarse_ISLG);CHKERRQ(ierr); 23640c7d97c5SJed Brown ierr = ISDestroy(&coarse_IS);CHKERRQ(ierr); 23650c7d97c5SJed Brown } 23660c7d97c5SJed Brown } 23670c7d97c5SJed Brown if(pcbddc->coarse_problem_type==PARALLEL_BDDC) { 23680c7d97c5SJed Brown /* arrays for values insertion */ 23690c7d97c5SJed Brown ins_local_primal_size = pcbddc->local_primal_size; 23700c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscMPIInt),&ins_local_primal_indices);CHKERRQ(ierr); 23710c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 23720c7d97c5SJed Brown for(j=0;j<ins_local_primal_size;j++){ 23730c7d97c5SJed Brown ins_local_primal_indices[j]=pcbddc->local_primal_indices[j]; 23740c7d97c5SJed 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]; 23750c7d97c5SJed Brown } 23760c7d97c5SJed Brown } 23770c7d97c5SJed Brown break; 23780c7d97c5SJed Brown 23790c7d97c5SJed Brown } 23800c7d97c5SJed Brown 23810c7d97c5SJed Brown case(GATHERS_BDDC): 23820c7d97c5SJed Brown { 23830c7d97c5SJed Brown 23840c7d97c5SJed Brown PetscMPIInt mysize,mysize2; 23850c7d97c5SJed Brown 23860c7d97c5SJed Brown if(rank_prec_comm==active_rank) { 23870c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 23880c7d97c5SJed Brown pcbddc->replicated_local_primal_values = (PetscScalar*)calloc(pcbddc->replicated_primal_size,sizeof(PetscScalar)); 23890c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 23900c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 23910c7d97c5SJed Brown /* arrays for values insertion */ 23920c7d97c5SJed Brown ins_local_primal_size = pcbddc->coarse_size; 23930c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscMPIInt),&ins_local_primal_indices);CHKERRQ(ierr); 23940c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 23950c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) localsizes2[i]=pcbddc->local_primal_sizes[i]*pcbddc->local_primal_sizes[i]; 23960c7d97c5SJed Brown localdispl2[0]=0; 23970c7d97c5SJed Brown for(i=1;i<size_prec_comm;i++) localdispl2[i]=localsizes2[i-1]+localdispl2[i-1]; 23980c7d97c5SJed Brown j=0; 23990c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) j+=localsizes2[i]; 24000c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 24010c7d97c5SJed Brown } 24020c7d97c5SJed Brown 24030c7d97c5SJed Brown mysize=pcbddc->local_primal_size; 24040c7d97c5SJed Brown mysize2=pcbddc->local_primal_size*pcbddc->local_primal_size; 24050c7d97c5SJed Brown if(pcbddc->coarse_problem_type == SEQUENTIAL_BDDC){ 240653cdbc3dSStefano 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); 240753cdbc3dSStefano 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); 24080c7d97c5SJed Brown } else { 240953cdbc3dSStefano 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); 241053cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,prec_comm);CHKERRQ(ierr); 24110c7d97c5SJed Brown } 24120c7d97c5SJed Brown 24130c7d97c5SJed Brown /* free data structures no longer needed and allocate some space which will be needed in BDDC application */ 24140c7d97c5SJed Brown if(rank_prec_comm==active_rank) { 24150c7d97c5SJed Brown PetscInt offset,offset2,row_ind,col_ind; 24160c7d97c5SJed Brown for(j=0;j<ins_local_primal_size;j++){ 24170c7d97c5SJed Brown ins_local_primal_indices[j]=j; 24180c7d97c5SJed Brown for(i=0;i<ins_local_primal_size;i++) ins_coarse_mat_vals[j*ins_local_primal_size+i]=0.0; 24190c7d97c5SJed Brown } 24200c7d97c5SJed Brown for(k=0;k<size_prec_comm;k++){ 24210c7d97c5SJed Brown offset=pcbddc->local_primal_displacements[k]; 24220c7d97c5SJed Brown offset2=localdispl2[k]; 24230c7d97c5SJed Brown for(j=0;j<pcbddc->local_primal_sizes[k];j++){ 24240c7d97c5SJed Brown col_ind=pcbddc->replicated_local_primal_indices[offset+j]; 24250c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_sizes[k];i++){ 24260c7d97c5SJed Brown row_ind=pcbddc->replicated_local_primal_indices[offset+i]; 24270c7d97c5SJed Brown ins_coarse_mat_vals[col_ind*pcbddc->coarse_size+row_ind]+=temp_coarse_mat_vals[offset2+j*pcbddc->local_primal_sizes[k]+i]; 24280c7d97c5SJed Brown } 24290c7d97c5SJed Brown } 24300c7d97c5SJed Brown } 24310c7d97c5SJed Brown } 24320c7d97c5SJed Brown break; 2433*da1bb401SStefano Zampini }/* switch on coarse problem and communications associated with finished */ 24340c7d97c5SJed Brown } 24350c7d97c5SJed Brown 24360c7d97c5SJed Brown /* Now create and fill up coarse matrix */ 24370c7d97c5SJed Brown if( rank_prec_comm == active_rank ) { 24380c7d97c5SJed Brown if(pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 24390c7d97c5SJed Brown ierr = MatCreate(coarse_comm,&pcbddc->coarse_mat);CHKERRQ(ierr); 24400c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_mat,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size);CHKERRQ(ierr); 24410c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_mat,coarse_mat_type);CHKERRQ(ierr); 24423b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 2443*da1bb401SStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 24443b03a366Sstefano_zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 24450c7d97c5SJed Brown } else { 24460c7d97c5SJed Brown Mat matis_coarse_local_mat; 2447d3ee2243SStefano Zampini /* remind bs */ 2448d3ee2243SStefano Zampini ierr = MatCreateIS(coarse_comm,bs,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_ISLG,&pcbddc->coarse_mat);CHKERRQ(ierr); 24493b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 24500c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 24513b03a366Sstefano_zampini ierr = MatSetUp(matis_coarse_local_mat);CHKERRQ(ierr); 2452*da1bb401SStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 2453a0ba757dSStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 24540c7d97c5SJed Brown } 2455a0ba757dSStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 24560c7d97c5SJed 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); 24570c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24580c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24590c7d97c5SJed Brown 2460*da1bb401SStefano Zampini /* PetscViewer view_out; 2461*da1bb401SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,"coarsematfull.m",&view_out);CHKERRQ(ierr); 2462*da1bb401SStefano Zampini ierr = PetscViewerSetFormat(view_out,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2463*da1bb401SStefano Zampini ierr = MatView(pcbddc->coarse_mat,view_out);CHKERRQ(ierr); 2464*da1bb401SStefano Zampini ierr = PetscViewerDestroy(&view_out);CHKERRQ(ierr);*/ 2465*da1bb401SStefano Zampini 24660c7d97c5SJed Brown ierr = MatGetVecs(pcbddc->coarse_mat,&pcbddc->coarse_vec,&pcbddc->coarse_rhs);CHKERRQ(ierr); 24670c7d97c5SJed Brown /* Preconditioner for coarse problem */ 246853cdbc3dSStefano Zampini ierr = KSPCreate(coarse_comm,&pcbddc->coarse_ksp);CHKERRQ(ierr); 246953cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 247053cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 24713b03a366Sstefano_zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,max_it_coarse_ksp);CHKERRQ(ierr); 247253cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 247353cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 247453cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 24750c7d97c5SJed Brown /* Allow user's customization */ 2476*da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,"coarse_");CHKERRQ(ierr); 247753cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 24780c7d97c5SJed Brown /* Set Up PC for coarse problem BDDC */ 247953cdbc3dSStefano Zampini if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2480e269702eSStefano Zampini if(dbg_flag) { 2481e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------Setting up a new level---------------\n");CHKERRQ(ierr); 2482e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2483e269702eSStefano Zampini } 248453cdbc3dSStefano Zampini ierr = PCBDDCSetCoarseProblemType(pc_temp,MULTILEVEL_BDDC);CHKERRQ(ierr); 248553cdbc3dSStefano Zampini } 248653cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 24875619798eSStefano Zampini if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 24885619798eSStefano Zampini if(dbg_flag) { 24895619798eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------New level set------------------------\n");CHKERRQ(ierr); 24905619798eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 24915619798eSStefano Zampini } 24925619798eSStefano Zampini } 24930c7d97c5SJed Brown } 24940c7d97c5SJed Brown if(pcbddc->coarse_communications_type == SCATTERS_BDDC) { 24950c7d97c5SJed Brown IS local_IS,global_IS; 24960c7d97c5SJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&local_IS);CHKERRQ(ierr); 24970c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_indices,PETSC_COPY_VALUES,&global_IS);CHKERRQ(ierr); 24980c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_P,local_IS,pcbddc->coarse_vec,global_IS,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 24990c7d97c5SJed Brown ierr = ISDestroy(&local_IS);CHKERRQ(ierr); 25000c7d97c5SJed Brown ierr = ISDestroy(&global_IS);CHKERRQ(ierr); 25010c7d97c5SJed Brown } 25020c7d97c5SJed Brown 25030c7d97c5SJed Brown 25043b03a366Sstefano_zampini /* Evaluate condition number of coarse problem for cheby (and verbose output if requested) */ 25053b03a366Sstefano_zampini if( pcbddc->coarse_problem_type == MULTILEVEL_BDDC && rank_prec_comm == active_rank ) { 25060c7d97c5SJed Brown PetscScalar m_one=-1.0; 25075619798eSStefano Zampini PetscReal infty_error,lambda_min,lambda_max,kappa_2; 25083b03a366Sstefano_zampini const KSPType check_ksp_type=KSPGMRES; 25090c7d97c5SJed Brown 25105619798eSStefano Zampini /* change coarse ksp object to an iterative method suitable for extreme eigenvalues' estimation */ 25113b03a366Sstefano_zampini ierr = KSPSetType(pcbddc->coarse_ksp,check_ksp_type);CHKERRQ(ierr); 2512d49ef151SStefano Zampini ierr = KSPSetComputeSingularValues(pcbddc->coarse_ksp,PETSC_TRUE);CHKERRQ(ierr); 25135619798eSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,1.e-8,1.e-8,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 25145619798eSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 2515d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->coarse_rhs,PETSC_NULL);CHKERRQ(ierr); 2516d49ef151SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 2517d49ef151SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,pcbddc->coarse_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 2518d49ef151SStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,pcbddc->coarse_rhs,pcbddc->coarse_rhs);CHKERRQ(ierr); 2519d49ef151SStefano Zampini ierr = KSPComputeExtremeSingularValues(pcbddc->coarse_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); 25203b03a366Sstefano_zampini if(dbg_flag) { 25215619798eSStefano Zampini kappa_2=lambda_max/lambda_min; 25225619798eSStefano Zampini ierr = KSPGetIterationNumber(pcbddc->coarse_ksp,&k);CHKERRQ(ierr); 2523d49ef151SStefano Zampini ierr = VecAXPY(pcbddc->coarse_rhs,m_one,pcbddc->coarse_vec);CHKERRQ(ierr); 2524d49ef151SStefano Zampini ierr = VecNorm(pcbddc->coarse_rhs,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 25253b03a366Sstefano_zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem condition number estimated with %d iterations of %s is: % 1.14e\n",k,check_ksp_type,kappa_2);CHKERRQ(ierr); 2526e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues: % 1.14e %1.14e\n",lambda_min,lambda_max);CHKERRQ(ierr); 2527e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem infty_error: %1.14e\n",infty_error);CHKERRQ(ierr); 25283b03a366Sstefano_zampini } 25295619798eSStefano Zampini /* restore coarse ksp to default values */ 2530d49ef151SStefano Zampini ierr = KSPSetComputeSingularValues(pcbddc->coarse_ksp,PETSC_FALSE);CHKERRQ(ierr); 25315619798eSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 25326c9de887SHong Zhang ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 25333b03a366Sstefano_zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,max_it_coarse_ksp);CHKERRQ(ierr); 25345619798eSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 25355619798eSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 253653cdbc3dSStefano Zampini } 25370c7d97c5SJed Brown 25380c7d97c5SJed Brown /* free data structures no longer needed */ 25390c7d97c5SJed Brown if(coarse_ISLG) { ierr = ISLocalToGlobalMappingDestroy(&coarse_ISLG);CHKERRQ(ierr); } 25400c7d97c5SJed Brown if(ins_local_primal_indices) { ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); } 25410c7d97c5SJed Brown if(ins_coarse_mat_vals) { ierr = PetscFree(ins_coarse_mat_vals);CHKERRQ(ierr);} 25420c7d97c5SJed Brown if(localsizes2) { ierr = PetscFree(localsizes2);CHKERRQ(ierr);} 25430c7d97c5SJed Brown if(localdispl2) { ierr = PetscFree(localdispl2);CHKERRQ(ierr);} 25440c7d97c5SJed Brown if(temp_coarse_mat_vals) { ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr);} 25450c7d97c5SJed Brown 25460c7d97c5SJed Brown PetscFunctionReturn(0); 25470c7d97c5SJed Brown } 25480c7d97c5SJed Brown 25490c7d97c5SJed Brown #undef __FUNCT__ 25500c7d97c5SJed Brown #define __FUNCT__ "PCBDDCManageLocalBoundaries" 255153cdbc3dSStefano Zampini static PetscErrorCode PCBDDCManageLocalBoundaries(PC pc) 25520c7d97c5SJed Brown { 25530c7d97c5SJed Brown 25540c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 25550c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 25560c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2557*da1bb401SStefano Zampini PCBDDCGraph mat_graph=pcbddc->mat_graph; 2558a0ba757dSStefano Zampini PetscInt *queue_in_global_numbering; 25593b03a366Sstefano_zampini PetscInt bs,ierr,i,j,s,k,iindex,neumann_bsize,dirichlet_bsize; 2560*da1bb401SStefano Zampini PetscInt total_counts,nodes_touched,where_values=1,vertex_size; 25613b03a366Sstefano_zampini PetscMPIInt adapt_interface=0,adapt_interface_reduced=0; 2562*da1bb401SStefano Zampini PetscBool same_set; 2563a0ba757dSStefano Zampini MPI_Comm interface_comm=((PetscObject)pc)->comm; 25643b03a366Sstefano_zampini PetscBool use_faces=PETSC_FALSE,use_edges=PETSC_FALSE; 25653b03a366Sstefano_zampini const PetscInt *neumann_nodes; 25663b03a366Sstefano_zampini const PetscInt *dirichlet_nodes; 256736e030ebSStefano Zampini IS used_IS; 2568*da1bb401SStefano Zampini PetscScalar *array; 2569*da1bb401SStefano Zampini PetscScalar *array2; 2570*da1bb401SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 25710c7d97c5SJed Brown 25720c7d97c5SJed Brown PetscFunctionBegin; 2573*da1bb401SStefano Zampini /* Setup local adjacency graph */ 2574*da1bb401SStefano Zampini mat_graph->nvtxs=pcis->n; 2575*da1bb401SStefano Zampini ierr = PCBDDCSetupLocalAdjacencyGraph(pc);CHKERRQ(ierr); 2576a0ba757dSStefano Zampini i = mat_graph->nvtxs; 2577a0ba757dSStefano 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); 2578a0ba757dSStefano Zampini ierr = PetscMalloc3(i,PetscInt,&mat_graph->which_dof,i,PetscBool,&mat_graph->touched,i,PetscInt,&queue_in_global_numbering);CHKERRQ(ierr); 2579a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->where,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2580a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->count,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2581a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->which_dof,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2582a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->queue,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 25833828260eSStefano Zampini ierr = PetscMemzero(mat_graph->cptr,(mat_graph->nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 2584a0ba757dSStefano Zampini 25859c0446d6SStefano Zampini /* Setting dofs splitting in mat_graph->which_dof */ 25869c0446d6SStefano Zampini if(pcbddc->n_ISForDofs) { /* get information about dofs' splitting if provided by the user */ 25879c0446d6SStefano Zampini PetscInt *is_indices; 25889c0446d6SStefano Zampini PetscInt is_size; 25899c0446d6SStefano Zampini for(i=0;i<pcbddc->n_ISForDofs;i++) { 25909c0446d6SStefano Zampini ierr = ISGetSize(pcbddc->ISForDofs[i],&is_size);CHKERRQ(ierr); 25919c0446d6SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofs[i],(const PetscInt**)&is_indices);CHKERRQ(ierr); 25929c0446d6SStefano Zampini for(j=0;j<is_size;j++) { 25939c0446d6SStefano Zampini mat_graph->which_dof[is_indices[j]]=i; 25949c0446d6SStefano Zampini } 25959c0446d6SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofs[i],(const PetscInt**)&is_indices);CHKERRQ(ierr); 25969c0446d6SStefano Zampini } 25973b03a366Sstefano_zampini /* use mat block size as vertex size */ 25983b03a366Sstefano_zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 25993b03a366Sstefano_zampini } else { /* otherwise it assumes a constant block size */ 2600a0ba757dSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 26010c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs/bs;i++) { 26020c7d97c5SJed Brown for(s=0;s<bs;s++) { 26030c7d97c5SJed Brown mat_graph->which_dof[i*bs+s]=s; 26040c7d97c5SJed Brown } 26050c7d97c5SJed Brown } 26063b03a366Sstefano_zampini vertex_size=1; 26079c0446d6SStefano Zampini } 26083b03a366Sstefano_zampini /* count number of neigh per node */ 26090c7d97c5SJed Brown total_counts=0; 26103b03a366Sstefano_zampini for(i=1;i<pcis->n_neigh;i++){ 26110c7d97c5SJed Brown s=pcis->n_shared[i]; 26120c7d97c5SJed Brown total_counts+=s; 261353cdbc3dSStefano Zampini for(j=0;j<s;j++){ 26140c7d97c5SJed Brown mat_graph->count[pcis->shared[i][j]] += 1; 26150c7d97c5SJed Brown } 26160c7d97c5SJed Brown } 26173b03a366Sstefano_zampini /* Take into account Neumann data -> it increments number of sharing subdomains for all but faces nodes lying on the interface */ 261836e030ebSStefano Zampini ierr = PCBDDCGetNeumannBoundaries(pc,&used_IS);CHKERRQ(ierr); 2619*da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 2620*da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 262136e030ebSStefano Zampini if(used_IS) { 262236e030ebSStefano Zampini ierr = ISGetSize(used_IS,&neumann_bsize);CHKERRQ(ierr); 262336e030ebSStefano Zampini ierr = ISGetIndices(used_IS,&neumann_nodes);CHKERRQ(ierr); 262453cdbc3dSStefano Zampini for(i=0;i<neumann_bsize;i++){ 262553cdbc3dSStefano Zampini iindex = neumann_nodes[i]; 2626*da1bb401SStefano Zampini if(mat_graph->count[iindex] > 1 && array[iindex]==0.0){ 262753cdbc3dSStefano Zampini mat_graph->count[iindex]+=1; 26280c7d97c5SJed Brown total_counts++; 2629*da1bb401SStefano Zampini array[iindex]=array[iindex]+1.0; 2630*da1bb401SStefano Zampini } else if(array[iindex]>0.0) { 2631*da1bb401SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Error for neumann nodes provided to BDDC! They must be uniquely listed! Found duplicate node %d\n",iindex); 26320c7d97c5SJed Brown } 26330c7d97c5SJed Brown } 26340c7d97c5SJed Brown } 2635*da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 2636*da1bb401SStefano Zampini /* allocate space for storing the set of neighbours for each node */ 2637*da1bb401SStefano Zampini ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt*),&mat_graph->neighbours_set);CHKERRQ(ierr); 2638*da1bb401SStefano Zampini if(mat_graph->nvtxs) { ierr = PetscMalloc(total_counts*sizeof(PetscInt),&mat_graph->neighbours_set[0]);CHKERRQ(ierr); } 2639*da1bb401SStefano Zampini for(i=1;i<mat_graph->nvtxs;i++) mat_graph->neighbours_set[i]=mat_graph->neighbours_set[i-1]+mat_graph->count[i-1]; 2640a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->count,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 26413b03a366Sstefano_zampini for(i=1;i<pcis->n_neigh;i++){ 26420c7d97c5SJed Brown s=pcis->n_shared[i]; 26430c7d97c5SJed Brown for(j=0;j<s;j++) { 26440c7d97c5SJed Brown k=pcis->shared[i][j]; 2645*da1bb401SStefano Zampini mat_graph->neighbours_set[k][mat_graph->count[k]] = pcis->neigh[i]; 26460c7d97c5SJed Brown mat_graph->count[k]+=1; 26470c7d97c5SJed Brown } 26480c7d97c5SJed Brown } 2649*da1bb401SStefano Zampini /* Check consistency of Neumann nodes */ 2650*da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 2651*da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2652*da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2653*da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2654*da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2655*da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 26563b03a366Sstefano_zampini /* set -1 fake neighbour to mimic Neumann boundary */ 265736e030ebSStefano Zampini if(used_IS) { 265853cdbc3dSStefano Zampini for(i=0;i<neumann_bsize;i++){ 265953cdbc3dSStefano Zampini iindex = neumann_nodes[i]; 26603b03a366Sstefano_zampini if(mat_graph->count[iindex] > 1){ 2661*da1bb401SStefano Zampini if(mat_graph->count[iindex]+1 != (PetscInt)array[iindex]) { 2662*da1bb401SStefano Zampini SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Neumann nodes provided to BDDC must be consistent among neighbours!\nNode %d: number of sharing subdomains %d != number of subdomains for which it is a neumann node %d\n",iindex,mat_graph->count[iindex]+1,(PetscInt)array[iindex]); 2663*da1bb401SStefano Zampini } 2664*da1bb401SStefano Zampini mat_graph->neighbours_set[iindex][mat_graph->count[iindex]] = -1; 266553cdbc3dSStefano Zampini mat_graph->count[iindex]+=1; 26660c7d97c5SJed Brown } 26670c7d97c5SJed Brown } 266836e030ebSStefano Zampini ierr = ISRestoreIndices(used_IS,&neumann_nodes);CHKERRQ(ierr); 26690c7d97c5SJed Brown } 2670*da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 2671*da1bb401SStefano Zampini /* sort set of sharing subdomains */ 2672*da1bb401SStefano Zampini for(i=0;i<mat_graph->nvtxs;i++) { ierr = PetscSortInt(mat_graph->count[i],mat_graph->neighbours_set[i]);CHKERRQ(ierr); } 26733b03a366Sstefano_zampini /* remove interior nodes and dirichlet boundary nodes from the next search into the graph */ 2674*da1bb401SStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){mat_graph->touched[i]=PETSC_FALSE;} 2675*da1bb401SStefano Zampini nodes_touched=0; 267636e030ebSStefano Zampini ierr = PCBDDCGetDirichletBoundaries(pc,&used_IS);CHKERRQ(ierr); 2677*da1bb401SStefano Zampini ierr = VecSet(pcis->vec2_N,0.0);CHKERRQ(ierr); 2678*da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 2679*da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 2680*da1bb401SStefano Zampini if(used_IS) { 2681*da1bb401SStefano Zampini ierr = ISGetSize(used_IS,&dirichlet_bsize);CHKERRQ(ierr); 2682*da1bb401SStefano Zampini if(dirichlet_bsize && matis->pure_neumann) { 2683*da1bb401SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Dirichlet boundaries are intended to be used with matrices with zeroed rows!\n"); 2684*da1bb401SStefano Zampini } 2685*da1bb401SStefano Zampini ierr = ISGetIndices(used_IS,&dirichlet_nodes);CHKERRQ(ierr); 2686*da1bb401SStefano Zampini for(i=0;i<dirichlet_bsize;i++){ 2687*da1bb401SStefano Zampini iindex=dirichlet_nodes[i]; 2688*da1bb401SStefano Zampini if(mat_graph->count[iindex] && !mat_graph->touched[iindex]) { 2689*da1bb401SStefano Zampini if(array[iindex]>0.0) { 2690*da1bb401SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"BDDC cannot have nodes which are marked as Neumann and Dirichlet at the same time! Wrong node %d\n",iindex); 2691*da1bb401SStefano Zampini } 2692*da1bb401SStefano Zampini mat_graph->touched[iindex]=PETSC_TRUE; 2693*da1bb401SStefano Zampini mat_graph->where[iindex]=0; 2694*da1bb401SStefano Zampini nodes_touched++; 2695*da1bb401SStefano Zampini array2[iindex]=array2[iindex]+1.0; 2696*da1bb401SStefano Zampini } 2697*da1bb401SStefano Zampini } 2698*da1bb401SStefano Zampini ierr = ISRestoreIndices(used_IS,&dirichlet_nodes);CHKERRQ(ierr); 2699*da1bb401SStefano Zampini } 2700*da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 2701*da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 2702*da1bb401SStefano Zampini /* Check consistency of Dirichlet nodes */ 2703*da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 2704*da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 2705*da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2706*da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2707*da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2708*da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2709*da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 2710*da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec2_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2711*da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec2_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2712*da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2713*da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2714*da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 2715*da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 271636e030ebSStefano Zampini if(used_IS) { 271736e030ebSStefano Zampini ierr = ISGetSize(used_IS,&dirichlet_bsize);CHKERRQ(ierr); 271836e030ebSStefano Zampini ierr = ISGetIndices(used_IS,&dirichlet_nodes);CHKERRQ(ierr); 27193b03a366Sstefano_zampini for(i=0;i<dirichlet_bsize;i++){ 2720*da1bb401SStefano Zampini iindex=dirichlet_nodes[i]; 2721*da1bb401SStefano Zampini if(array[iindex]>1.0 && array[iindex]!=array2[iindex] ) { 2722*da1bb401SStefano Zampini SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Dirichlet nodes provided to BDDC must be consistent among neighbours!\nNode %d: number of sharing subdomains %d != number of subdomains for which it is a neumann node %d\n",iindex,(PetscInt)array[iindex],(PetscInt)array2[iindex]); 2723*da1bb401SStefano Zampini } 27243b03a366Sstefano_zampini } 272536e030ebSStefano Zampini ierr = ISRestoreIndices(used_IS,&dirichlet_nodes);CHKERRQ(ierr); 27263b03a366Sstefano_zampini } 2727*da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 2728*da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 2729*da1bb401SStefano Zampini 27300c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs;i++){ 27313b03a366Sstefano_zampini if(!mat_graph->count[i]){ /* interior nodes */ 27320c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 27330c7d97c5SJed Brown mat_graph->where[i]=0; 27340c7d97c5SJed Brown nodes_touched++; 27350c7d97c5SJed Brown } 27360c7d97c5SJed Brown } 27370c7d97c5SJed Brown mat_graph->ncmps = 0; 2738*da1bb401SStefano Zampini i=0; 27390c7d97c5SJed Brown while(nodes_touched<mat_graph->nvtxs) { 2740a0ba757dSStefano Zampini /* find first untouched node in local ordering */ 27410c7d97c5SJed Brown while(mat_graph->touched[i]) i++; 27420c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 2743a0ba757dSStefano Zampini mat_graph->where[i]=where_values; 27440c7d97c5SJed Brown nodes_touched++; 2745a0ba757dSStefano Zampini /* now find all other nodes having the same set of sharing subdomains */ 27460c7d97c5SJed Brown for(j=i+1;j<mat_graph->nvtxs;j++){ 2747a0ba757dSStefano Zampini /* check for same number of sharing subdomains and dof number */ 2748*da1bb401SStefano Zampini if(!mat_graph->touched[j] && mat_graph->count[i]==mat_graph->count[j] && mat_graph->which_dof[i] == mat_graph->which_dof[j] ){ 2749a0ba757dSStefano Zampini /* check for same set of sharing subdomains */ 27500c7d97c5SJed Brown same_set=PETSC_TRUE; 27510c7d97c5SJed Brown for(k=0;k<mat_graph->count[j];k++){ 2752*da1bb401SStefano Zampini if(mat_graph->neighbours_set[i][k]!=mat_graph->neighbours_set[j][k]) { 27530c7d97c5SJed Brown same_set=PETSC_FALSE; 27540c7d97c5SJed Brown } 27550c7d97c5SJed Brown } 2756a0ba757dSStefano Zampini /* I found a friend of mine */ 27570c7d97c5SJed Brown if(same_set) { 2758a0ba757dSStefano Zampini mat_graph->where[j]=where_values; 27590c7d97c5SJed Brown mat_graph->touched[j]=PETSC_TRUE; 27600c7d97c5SJed Brown nodes_touched++; 27610c7d97c5SJed Brown } 27620c7d97c5SJed Brown } 27630c7d97c5SJed Brown } 2764a0ba757dSStefano Zampini where_values++; 27650c7d97c5SJed Brown } 2766a0ba757dSStefano Zampini where_values--; if(where_values<0) where_values=0; 2767a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscMPIInt),&mat_graph->where_ncmps);CHKERRQ(ierr); 2768a0ba757dSStefano Zampini /* Find connected components defined on the shared interface */ 2769a0ba757dSStefano Zampini if(where_values) { 2770a0ba757dSStefano Zampini ierr = PCBDDCFindConnectedComponents(mat_graph, where_values); 27713b03a366Sstefano_zampini /* For consistency among neughbouring procs, I need to sort (by global ordering) each connected component */ 2772a0ba757dSStefano Zampini for(i=0;i<mat_graph->ncmps;i++) { 2773a0ba757dSStefano 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); 2774a0ba757dSStefano 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); 2775a0ba757dSStefano Zampini } 2776a0ba757dSStefano Zampini } 2777a0ba757dSStefano Zampini /* check consistency of connected components among neighbouring subdomains -> it adapt them in case it is needed */ 2778a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 27793b03a366Sstefano_zampini /* We are not sure that two connected components will be the same among subdomains sharing a subset of local interface */ 27803b03a366Sstefano_zampini if(mat_graph->where_ncmps[i]>1) { 2781a0ba757dSStefano Zampini adapt_interface=1; 2782a0ba757dSStefano Zampini break; 2783a0ba757dSStefano Zampini } 2784a0ba757dSStefano Zampini } 2785a0ba757dSStefano Zampini ierr = MPI_Allreduce(&adapt_interface,&adapt_interface_reduced,1,MPIU_INT,MPI_LOR,interface_comm);CHKERRQ(ierr); 2786*da1bb401SStefano Zampini if(pcbddc->dbg_flag && adapt_interface_reduced) { 2787*da1bb401SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Interface adapted\n");CHKERRQ(ierr); 2788*da1bb401SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2789*da1bb401SStefano Zampini } 2790a0ba757dSStefano Zampini if(where_values && adapt_interface_reduced) { 27910c7d97c5SJed Brown 27923b03a366Sstefano_zampini 2793a0ba757dSStefano Zampini PetscInt sum_requests=0,my_rank; 2794a0ba757dSStefano Zampini PetscInt buffer_size,start_of_recv,size_of_recv,start_of_send; 2795a0ba757dSStefano Zampini PetscInt temp_buffer_size,ins_val,global_where_counter; 2796a0ba757dSStefano Zampini PetscInt *cum_recv_counts; 2797a0ba757dSStefano Zampini PetscInt *where_to_nodes_indices; 2798a0ba757dSStefano Zampini PetscInt *petsc_buffer; 2799a0ba757dSStefano Zampini PetscMPIInt *recv_buffer; 2800a0ba757dSStefano Zampini PetscMPIInt *recv_buffer_where; 2801a0ba757dSStefano Zampini PetscMPIInt *send_buffer; 2802a0ba757dSStefano Zampini PetscMPIInt size_of_send; 2803a0ba757dSStefano Zampini PetscInt *sizes_of_sends; 2804a0ba757dSStefano Zampini MPI_Request *send_requests; 2805a0ba757dSStefano Zampini MPI_Request *recv_requests; 2806a0ba757dSStefano Zampini PetscInt *where_cc_adapt; 2807a0ba757dSStefano Zampini PetscInt **temp_buffer; 2808a0ba757dSStefano Zampini PetscInt *nodes_to_temp_buffer_indices; 2809a0ba757dSStefano Zampini PetscInt *add_to_where; 2810a0ba757dSStefano Zampini 2811a0ba757dSStefano Zampini ierr = MPI_Comm_rank(interface_comm,&my_rank);CHKERRQ(ierr); 2812a0ba757dSStefano Zampini ierr = PetscMalloc((where_values+1)*sizeof(PetscInt),&cum_recv_counts);CHKERRQ(ierr); 2813a0ba757dSStefano Zampini ierr = PetscMemzero(cum_recv_counts,(where_values+1)*sizeof(PetscInt));CHKERRQ(ierr); 2814a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&where_to_nodes_indices);CHKERRQ(ierr); 2815a0ba757dSStefano Zampini /* first count how many neighbours per connected component I will receive from */ 2816a0ba757dSStefano Zampini cum_recv_counts[0]=0; 2817a0ba757dSStefano Zampini for(i=1;i<where_values+1;i++){ 2818a0ba757dSStefano Zampini j=0; 2819a0ba757dSStefano Zampini while(mat_graph->where[j] != i) j++; 2820a0ba757dSStefano Zampini where_to_nodes_indices[i-1]=j; 2821*da1bb401SStefano Zampini if(mat_graph->neighbours_set[j][0]!=-1) { cum_recv_counts[i]=cum_recv_counts[i-1]+mat_graph->count[j]; } /* We don't want sends/recvs_to/from_self -> here I don't count myself */ 28223b03a366Sstefano_zampini else { cum_recv_counts[i]=cum_recv_counts[i-1]+mat_graph->count[j]-1; } 2823a0ba757dSStefano Zampini } 2824a0ba757dSStefano Zampini buffer_size=2*cum_recv_counts[where_values]+mat_graph->nvtxs; 2825a0ba757dSStefano Zampini ierr = PetscMalloc(2*cum_recv_counts[where_values]*sizeof(PetscMPIInt),&recv_buffer_where);CHKERRQ(ierr); 2826a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 2827a0ba757dSStefano Zampini ierr = PetscMalloc(cum_recv_counts[where_values]*sizeof(MPI_Request),&send_requests);CHKERRQ(ierr); 2828a0ba757dSStefano Zampini ierr = PetscMalloc(cum_recv_counts[where_values]*sizeof(MPI_Request),&recv_requests);CHKERRQ(ierr); 2829a0ba757dSStefano Zampini for(i=0;i<cum_recv_counts[where_values];i++) { 2830a0ba757dSStefano Zampini send_requests[i]=MPI_REQUEST_NULL; 2831a0ba757dSStefano Zampini recv_requests[i]=MPI_REQUEST_NULL; 2832a0ba757dSStefano Zampini } 2833a0ba757dSStefano Zampini /* exchange with my neighbours the number of my connected components on the shared interface */ 2834a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2835a0ba757dSStefano Zampini j=where_to_nodes_indices[i]; 2836*da1bb401SStefano Zampini k = (mat_graph->neighbours_set[j][0] == -1 ? 1 : 0); 2837a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2838*da1bb401SStefano Zampini ierr = MPI_Isend(&mat_graph->where_ncmps[i],1,MPIU_INT,mat_graph->neighbours_set[j][k],(my_rank+1)*mat_graph->count[j],interface_comm,&send_requests[sum_requests]);CHKERRQ(ierr); 2839*da1bb401SStefano Zampini ierr = MPI_Irecv(&recv_buffer_where[sum_requests],1,MPIU_INT,mat_graph->neighbours_set[j][k],(mat_graph->neighbours_set[j][k]+1)*mat_graph->count[j],interface_comm,&recv_requests[sum_requests]);CHKERRQ(ierr); 2840a0ba757dSStefano Zampini sum_requests++; 2841a0ba757dSStefano Zampini } 2842a0ba757dSStefano Zampini } 2843a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2844a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2845a0ba757dSStefano Zampini /* determine the connected component I need to adapt */ 2846a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&where_cc_adapt);CHKERRQ(ierr); 2847a0ba757dSStefano Zampini ierr = PetscMemzero(where_cc_adapt,where_values*sizeof(PetscInt));CHKERRQ(ierr); 2848a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2849a0ba757dSStefano Zampini for(j=cum_recv_counts[i];j<cum_recv_counts[i+1];j++){ 28503b03a366Sstefano_zampini /* The first condition is natural (i.e someone has a different number of cc than me), the second one is just to be safe */ 28513b03a366Sstefano_zampini if( mat_graph->where_ncmps[i]!=recv_buffer_where[j] || mat_graph->where_ncmps[i] > 1 ) { 2852a0ba757dSStefano Zampini where_cc_adapt[i]=PETSC_TRUE; 2853a0ba757dSStefano Zampini break; 2854a0ba757dSStefano Zampini } 2855a0ba757dSStefano Zampini } 2856a0ba757dSStefano Zampini } 2857a0ba757dSStefano Zampini /* now get from neighbours their ccs (in global numbering) and adapt them (in case it is needed) */ 2858a0ba757dSStefano Zampini /* first determine how much data to send (size of each queue plus the global indices) and communicate it to neighbours */ 2859a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&sizes_of_sends);CHKERRQ(ierr); 2860a0ba757dSStefano Zampini ierr = PetscMemzero(sizes_of_sends,where_values*sizeof(PetscInt));CHKERRQ(ierr); 2861a0ba757dSStefano Zampini sum_requests=0; 2862a0ba757dSStefano Zampini start_of_send=0; 2863a0ba757dSStefano Zampini start_of_recv=cum_recv_counts[where_values]; 2864a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 2865a0ba757dSStefano Zampini if(where_cc_adapt[i]) { 2866a0ba757dSStefano Zampini size_of_send=0; 2867a0ba757dSStefano Zampini for(j=i;j<mat_graph->ncmps;j++) { 2868a0ba757dSStefano Zampini if(mat_graph->where[mat_graph->queue[mat_graph->cptr[j]]] == i+1) { /* WARNING -> where values goes from 1 to where_values included */ 2869a0ba757dSStefano Zampini send_buffer[start_of_send+size_of_send]=mat_graph->cptr[j+1]-mat_graph->cptr[j]; 2870a0ba757dSStefano Zampini size_of_send+=1; 2871a0ba757dSStefano Zampini for(k=0;k<mat_graph->cptr[j+1]-mat_graph->cptr[j];k++) { 2872a0ba757dSStefano Zampini send_buffer[start_of_send+size_of_send+k]=queue_in_global_numbering[mat_graph->cptr[j]+k]; 2873a0ba757dSStefano Zampini } 2874a0ba757dSStefano Zampini size_of_send=size_of_send+mat_graph->cptr[j+1]-mat_graph->cptr[j]; 2875a0ba757dSStefano Zampini } 2876a0ba757dSStefano Zampini } 2877a0ba757dSStefano Zampini j = where_to_nodes_indices[i]; 2878*da1bb401SStefano Zampini k = (mat_graph->neighbours_set[j][0] == -1 ? 1 : 0); 2879a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2880*da1bb401SStefano Zampini ierr = MPI_Isend(&size_of_send,1,MPIU_INT,mat_graph->neighbours_set[j][k],(my_rank+1)*mat_graph->count[j],interface_comm,&send_requests[sum_requests]);CHKERRQ(ierr); 2881*da1bb401SStefano Zampini ierr = MPI_Irecv(&recv_buffer_where[sum_requests+start_of_recv],1,MPIU_INT,mat_graph->neighbours_set[j][k],(mat_graph->neighbours_set[j][k]+1)*mat_graph->count[j],interface_comm,&recv_requests[sum_requests]);CHKERRQ(ierr); 2882a0ba757dSStefano Zampini sum_requests++; 2883a0ba757dSStefano Zampini } 2884a0ba757dSStefano Zampini sizes_of_sends[i]=size_of_send; 2885a0ba757dSStefano Zampini start_of_send+=size_of_send; 2886a0ba757dSStefano Zampini } 2887a0ba757dSStefano Zampini } 2888a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2889a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2890a0ba757dSStefano Zampini buffer_size=0; 2891a0ba757dSStefano Zampini for(k=0;k<sum_requests;k++) { buffer_size+=recv_buffer_where[start_of_recv+k]; } 2892a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscMPIInt),&recv_buffer);CHKERRQ(ierr); 2893a0ba757dSStefano Zampini /* now exchange the data */ 2894a0ba757dSStefano Zampini start_of_recv=0; 2895a0ba757dSStefano Zampini start_of_send=0; 2896a0ba757dSStefano Zampini sum_requests=0; 2897a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 2898a0ba757dSStefano Zampini if(where_cc_adapt[i]) { 2899a0ba757dSStefano Zampini size_of_send = sizes_of_sends[i]; 2900a0ba757dSStefano Zampini j = where_to_nodes_indices[i]; 2901*da1bb401SStefano Zampini k = (mat_graph->neighbours_set[j][0] == -1 ? 1 : 0); 2902a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2903*da1bb401SStefano Zampini ierr = MPI_Isend(&send_buffer[start_of_send],size_of_send,MPIU_INT,mat_graph->neighbours_set[j][k],(my_rank+1)*mat_graph->count[j],interface_comm,&send_requests[sum_requests]);CHKERRQ(ierr); 2904a0ba757dSStefano Zampini size_of_recv=recv_buffer_where[cum_recv_counts[where_values]+sum_requests]; 2905*da1bb401SStefano Zampini ierr = MPI_Irecv(&recv_buffer[start_of_recv],size_of_recv,MPIU_INT,mat_graph->neighbours_set[j][k],(mat_graph->neighbours_set[j][k]+1)*mat_graph->count[j],interface_comm,&recv_requests[sum_requests]);CHKERRQ(ierr); 2906a0ba757dSStefano Zampini start_of_recv+=size_of_recv; 2907a0ba757dSStefano Zampini sum_requests++; 2908a0ba757dSStefano Zampini } 2909a0ba757dSStefano Zampini start_of_send+=size_of_send; 2910a0ba757dSStefano Zampini } 2911a0ba757dSStefano Zampini } 2912a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2913a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2914a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscInt),&petsc_buffer);CHKERRQ(ierr); 2915a0ba757dSStefano Zampini for(k=0;k<start_of_recv;k++) { petsc_buffer[k]=(PetscInt)recv_buffer[k]; } 2916a0ba757dSStefano Zampini for(j=0;j<buffer_size;) { 2917a0ba757dSStefano Zampini ierr = ISGlobalToLocalMappingApply(matis->mapping,IS_GTOLM_MASK,petsc_buffer[j],&petsc_buffer[j+1],&petsc_buffer[j],&petsc_buffer[j+1]);CHKERRQ(ierr); 2918a0ba757dSStefano Zampini k=petsc_buffer[j]+1; 2919a0ba757dSStefano Zampini j+=k; 2920a0ba757dSStefano Zampini } 2921a0ba757dSStefano Zampini sum_requests=cum_recv_counts[where_values]; 2922a0ba757dSStefano Zampini start_of_recv=0; 2923a0ba757dSStefano Zampini ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt),&nodes_to_temp_buffer_indices);CHKERRQ(ierr); 2924a0ba757dSStefano Zampini global_where_counter=0; 2925a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2926a0ba757dSStefano Zampini if(where_cc_adapt[i]){ 2927a0ba757dSStefano Zampini temp_buffer_size=0; 2928a0ba757dSStefano Zampini /* find nodes on the shared interface we need to adapt */ 2929a0ba757dSStefano Zampini for(j=0;j<mat_graph->nvtxs;j++){ 2930a0ba757dSStefano Zampini if(mat_graph->where[j]==i+1) { 2931a0ba757dSStefano Zampini nodes_to_temp_buffer_indices[j]=temp_buffer_size; 2932a0ba757dSStefano Zampini temp_buffer_size++; 2933a0ba757dSStefano Zampini } else { 2934a0ba757dSStefano Zampini nodes_to_temp_buffer_indices[j]=-1; 2935a0ba757dSStefano Zampini } 2936a0ba757dSStefano Zampini } 2937a0ba757dSStefano Zampini /* allocate some temporary space */ 2938a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*sizeof(PetscInt*),&temp_buffer);CHKERRQ(ierr); 2939a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*(cum_recv_counts[i+1]-cum_recv_counts[i])*sizeof(PetscInt),&temp_buffer[0]);CHKERRQ(ierr); 2940a0ba757dSStefano Zampini ierr = PetscMemzero(temp_buffer[0],temp_buffer_size*(cum_recv_counts[i+1]-cum_recv_counts[i])*sizeof(PetscInt));CHKERRQ(ierr); 2941a0ba757dSStefano Zampini for(j=1;j<temp_buffer_size;j++){ 2942a0ba757dSStefano Zampini temp_buffer[j]=temp_buffer[j-1]+cum_recv_counts[i+1]-cum_recv_counts[i]; 2943a0ba757dSStefano Zampini } 2944a0ba757dSStefano Zampini /* analyze contributions from neighbouring subdomains for i-th conn comp 2945a0ba757dSStefano Zampini temp buffer structure: 2946a0ba757dSStefano Zampini supposing part of the interface has dimension 5 (global nodes 0,1,2,3,4) 2947a0ba757dSStefano Zampini 3 neighs procs with structured connected components: 2948a0ba757dSStefano Zampini neigh 0: [0 1 4], [2 3]; (2 connected components) 2949a0ba757dSStefano Zampini neigh 1: [0 1], [2 3 4]; (2 connected components) 2950a0ba757dSStefano Zampini neigh 2: [0 4], [1], [2 3]; (3 connected components) 2951a0ba757dSStefano Zampini tempbuffer (row-oriented) should be filled as: 2952a0ba757dSStefano Zampini [ 0, 0, 0; 2953a0ba757dSStefano Zampini 0, 0, 1; 2954a0ba757dSStefano Zampini 1, 1, 2; 2955a0ba757dSStefano Zampini 1, 1, 2; 2956a0ba757dSStefano Zampini 0, 1, 0; ]; 2957a0ba757dSStefano Zampini This way we can simply recover the resulting structure account for possible intersections of ccs among neighs. 2958a0ba757dSStefano Zampini The mat_graph->where array will be modified to reproduce the following 4 connected components [0], [1], [2 3], [4]; 2959a0ba757dSStefano Zampini */ 2960a0ba757dSStefano Zampini for(j=0;j<cum_recv_counts[i+1]-cum_recv_counts[i];j++) { 2961a0ba757dSStefano Zampini ins_val=0; 2962a0ba757dSStefano Zampini size_of_recv=recv_buffer_where[sum_requests]; /* total size of recv from neighs */ 2963a0ba757dSStefano Zampini for(buffer_size=0;buffer_size<size_of_recv;) { /* loop until all data from neighs has been taken into account */ 2964a0ba757dSStefano Zampini for(k=1;k<petsc_buffer[buffer_size+start_of_recv]+1;k++) { /* filling properly temp_buffer using data from a single recv */ 2965a0ba757dSStefano Zampini temp_buffer[ nodes_to_temp_buffer_indices[ petsc_buffer[ start_of_recv+buffer_size+k ] ] ][j]=ins_val; 2966a0ba757dSStefano Zampini } 2967a0ba757dSStefano Zampini buffer_size+=k; 2968a0ba757dSStefano Zampini ins_val++; 2969a0ba757dSStefano Zampini } 2970a0ba757dSStefano Zampini start_of_recv+=size_of_recv; 2971a0ba757dSStefano Zampini sum_requests++; 2972a0ba757dSStefano Zampini } 2973a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*sizeof(PetscInt),&add_to_where);CHKERRQ(ierr); 2974a0ba757dSStefano Zampini ierr = PetscMemzero(add_to_where,temp_buffer_size*sizeof(PetscInt));CHKERRQ(ierr); 2975a0ba757dSStefano Zampini for(j=0;j<temp_buffer_size;j++){ 2976a0ba757dSStefano Zampini if(!add_to_where[j]){ /* found a new cc */ 2977a0ba757dSStefano Zampini global_where_counter++; 2978a0ba757dSStefano Zampini add_to_where[j]=global_where_counter; 2979a0ba757dSStefano Zampini for(k=j+1;k<temp_buffer_size;k++){ /* check for other nodes in new cc */ 2980a0ba757dSStefano Zampini same_set=PETSC_TRUE; 2981a0ba757dSStefano Zampini for(s=0;s<cum_recv_counts[i+1]-cum_recv_counts[i];s++){ 2982a0ba757dSStefano Zampini if(temp_buffer[j][s]!=temp_buffer[k][s]) { 2983a0ba757dSStefano Zampini same_set=PETSC_FALSE; 2984a0ba757dSStefano Zampini break; 2985a0ba757dSStefano Zampini } 2986a0ba757dSStefano Zampini } 2987a0ba757dSStefano Zampini if(same_set) add_to_where[k]=global_where_counter; 2988a0ba757dSStefano Zampini } 2989a0ba757dSStefano Zampini } 2990a0ba757dSStefano Zampini } 2991a0ba757dSStefano Zampini /* insert new data in where array */ 2992a0ba757dSStefano Zampini temp_buffer_size=0; 2993a0ba757dSStefano Zampini for(j=0;j<mat_graph->nvtxs;j++){ 2994a0ba757dSStefano Zampini if(mat_graph->where[j]==i+1) { 2995a0ba757dSStefano Zampini mat_graph->where[j]=where_values+add_to_where[temp_buffer_size]; 2996a0ba757dSStefano Zampini temp_buffer_size++; 2997a0ba757dSStefano Zampini } 2998a0ba757dSStefano Zampini } 2999a0ba757dSStefano Zampini ierr = PetscFree(temp_buffer[0]);CHKERRQ(ierr); 3000a0ba757dSStefano Zampini ierr = PetscFree(temp_buffer);CHKERRQ(ierr); 3001a0ba757dSStefano Zampini ierr = PetscFree(add_to_where);CHKERRQ(ierr); 3002a0ba757dSStefano Zampini } 3003a0ba757dSStefano Zampini } 3004a0ba757dSStefano Zampini ierr = PetscFree(nodes_to_temp_buffer_indices);CHKERRQ(ierr); 3005a0ba757dSStefano Zampini ierr = PetscFree(sizes_of_sends);CHKERRQ(ierr); 3006a0ba757dSStefano Zampini ierr = PetscFree(send_requests);CHKERRQ(ierr); 3007a0ba757dSStefano Zampini ierr = PetscFree(recv_requests);CHKERRQ(ierr); 3008a0ba757dSStefano Zampini ierr = PetscFree(petsc_buffer);CHKERRQ(ierr); 3009a0ba757dSStefano Zampini ierr = PetscFree(recv_buffer);CHKERRQ(ierr); 3010a0ba757dSStefano Zampini ierr = PetscFree(recv_buffer_where);CHKERRQ(ierr); 3011a0ba757dSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 3012a0ba757dSStefano Zampini ierr = PetscFree(cum_recv_counts);CHKERRQ(ierr); 3013a0ba757dSStefano Zampini ierr = PetscFree(where_to_nodes_indices);CHKERRQ(ierr); 3014a0ba757dSStefano Zampini /* We are ready to evaluate consistent connected components on each part of the shared interface */ 3015a0ba757dSStefano Zampini if(global_where_counter) { 3016a0ba757dSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){ mat_graph->touched[i]=PETSC_FALSE; } 3017a0ba757dSStefano Zampini global_where_counter=0; 3018a0ba757dSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){ 3019a0ba757dSStefano Zampini if(mat_graph->where[i] && !mat_graph->touched[i]) { 3020a0ba757dSStefano Zampini global_where_counter++; 3021a0ba757dSStefano Zampini for(j=i+1;j<mat_graph->nvtxs;j++){ 3022a0ba757dSStefano Zampini if(!mat_graph->touched[j] && mat_graph->where[j]==mat_graph->where[i]) { 3023a0ba757dSStefano Zampini mat_graph->where[j]=global_where_counter; 3024a0ba757dSStefano Zampini mat_graph->touched[j]=PETSC_TRUE; 3025a0ba757dSStefano Zampini } 3026a0ba757dSStefano Zampini } 3027a0ba757dSStefano Zampini mat_graph->where[i]=global_where_counter; 3028a0ba757dSStefano Zampini mat_graph->touched[i]=PETSC_TRUE; 3029a0ba757dSStefano Zampini } 3030a0ba757dSStefano Zampini } 3031a0ba757dSStefano Zampini where_values=global_where_counter; 3032a0ba757dSStefano Zampini } 3033a0ba757dSStefano Zampini if(global_where_counter) { 3034a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->cptr,(mat_graph->nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 3035a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->queue,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 3036a0ba757dSStefano Zampini ierr = PetscFree(mat_graph->where_ncmps);CHKERRQ(ierr); 3037a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscMPIInt),&mat_graph->where_ncmps);CHKERRQ(ierr); 3038a0ba757dSStefano Zampini ierr = PCBDDCFindConnectedComponents(mat_graph, where_values); 3039a0ba757dSStefano Zampini for(i=0;i<mat_graph->ncmps;i++) { 3040a0ba757dSStefano 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); 3041a0ba757dSStefano 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); 3042a0ba757dSStefano Zampini } 3043a0ba757dSStefano Zampini } 30443b03a366Sstefano_zampini } /* Finished adapting interface */ 30450c7d97c5SJed Brown PetscInt nfc=0; 30460c7d97c5SJed Brown PetscInt nec=0; 30470c7d97c5SJed Brown PetscInt nvc=0; 30483b03a366Sstefano_zampini PetscBool twodim_flag=PETSC_FALSE; 30490c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 30503b03a366Sstefano_zampini if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > vertex_size ){ 30513b03a366Sstefano_zampini if(mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]==1){ /* 1 neigh */ 30520c7d97c5SJed Brown nfc++; 30533b03a366Sstefano_zampini } else { /* note that nec will be zero in 2d */ 30543b03a366Sstefano_zampini nec++; 30553b03a366Sstefano_zampini } 30560c7d97c5SJed Brown } else { 30573b03a366Sstefano_zampini nvc+=mat_graph->cptr[i+1]-mat_graph->cptr[i]; 30583b03a366Sstefano_zampini } 30593b03a366Sstefano_zampini } 30603b03a366Sstefano_zampini 30613b03a366Sstefano_zampini if(!nec) { /* we are in a 2d case -> no faces, only edges */ 30623b03a366Sstefano_zampini nec = nfc; 30633b03a366Sstefano_zampini nfc = 0; 30643b03a366Sstefano_zampini twodim_flag = PETSC_TRUE; 30653b03a366Sstefano_zampini } 30663b03a366Sstefano_zampini /* allocate IS arrays for faces, edges. Vertices need a single index set. 30673b03a366Sstefano_zampini Reusing space allocated in mat_graph->where for creating IS objects */ 30683b03a366Sstefano_zampini if(!pcbddc->vertices_flag && !pcbddc->edges_flag) { 30693b03a366Sstefano_zampini ierr = PetscMalloc(nfc*sizeof(IS),&pcbddc->ISForFaces);CHKERRQ(ierr); 30703b03a366Sstefano_zampini use_faces=PETSC_TRUE; 30713b03a366Sstefano_zampini } 30723b03a366Sstefano_zampini if(!pcbddc->vertices_flag && !pcbddc->faces_flag) { 30733b03a366Sstefano_zampini ierr = PetscMalloc(nec*sizeof(IS),&pcbddc->ISForEdges);CHKERRQ(ierr); 30743b03a366Sstefano_zampini use_edges=PETSC_TRUE; 30753b03a366Sstefano_zampini } 30763b03a366Sstefano_zampini nfc=0; 30773b03a366Sstefano_zampini nec=0; 30783b03a366Sstefano_zampini for (i=0; i<mat_graph->ncmps; i++) { 30793b03a366Sstefano_zampini if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > vertex_size ){ 30803b03a366Sstefano_zampini for(j=0;j<mat_graph->cptr[i+1]-mat_graph->cptr[i];j++) { 30813b03a366Sstefano_zampini mat_graph->where[j]=mat_graph->queue[mat_graph->cptr[i]+j]; 30823b03a366Sstefano_zampini } 30833b03a366Sstefano_zampini if(mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]==1){ 30843b03a366Sstefano_zampini if(twodim_flag) { 30853b03a366Sstefano_zampini if(use_edges) { 30863b03a366Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,mat_graph->where,PETSC_COPY_VALUES,&pcbddc->ISForEdges[nec]);CHKERRQ(ierr); 30873b03a366Sstefano_zampini nec++; 30883b03a366Sstefano_zampini } 30893b03a366Sstefano_zampini } else { 30903b03a366Sstefano_zampini if(use_faces) { 30913b03a366Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,mat_graph->where,PETSC_COPY_VALUES,&pcbddc->ISForFaces[nfc]);CHKERRQ(ierr); 30923b03a366Sstefano_zampini nfc++; 30933b03a366Sstefano_zampini } 30943b03a366Sstefano_zampini } 30953b03a366Sstefano_zampini } else { 30963b03a366Sstefano_zampini if(use_edges) { 30973b03a366Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,mat_graph->where,PETSC_COPY_VALUES,&pcbddc->ISForEdges[nec]);CHKERRQ(ierr); 30980c7d97c5SJed Brown nec++; 30990c7d97c5SJed Brown } 31000c7d97c5SJed Brown } 31010c7d97c5SJed Brown } 31023b03a366Sstefano_zampini } 31033b03a366Sstefano_zampini pcbddc->n_ISForFaces=nfc; 31043b03a366Sstefano_zampini pcbddc->n_ISForEdges=nec; 31053b03a366Sstefano_zampini nvc=0; 31060c7d97c5SJed Brown if( !pcbddc->constraints_flag ) { 31073b03a366Sstefano_zampini for (i=0; i<mat_graph->ncmps; i++) { 31083b03a366Sstefano_zampini if( mat_graph->cptr[i+1]-mat_graph->cptr[i] <= vertex_size ){ 31093b03a366Sstefano_zampini for( j=mat_graph->cptr[i];j<mat_graph->cptr[i+1];j++) { 31103b03a366Sstefano_zampini mat_graph->where[nvc]=mat_graph->queue[j]; 31110c7d97c5SJed Brown nvc++; 31120c7d97c5SJed Brown } 31130c7d97c5SJed Brown } 31140c7d97c5SJed Brown } 31150c7d97c5SJed Brown } 3116a0ba757dSStefano Zampini /* sort vertex set (by local ordering) */ 31173b03a366Sstefano_zampini ierr = PetscSortInt(nvc,mat_graph->where);CHKERRQ(ierr); 31183b03a366Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nvc,mat_graph->where,PETSC_COPY_VALUES,&pcbddc->ISForVertices);CHKERRQ(ierr); 31190c7d97c5SJed Brown 3120e269702eSStefano Zampini if(pcbddc->dbg_flag) { 3121e269702eSStefano Zampini 3122d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3123d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Details from PCBDDCManageLocalBoundaries for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 3124d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3125a0ba757dSStefano Zampini /* ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Graph (adjacency structure) of local Neumann mat\n");CHKERRQ(ierr); 3126a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3127e269702eSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++) { 3128a0ba757dSStefano 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); 3129e269702eSStefano Zampini for(j=mat_graph->xadj[i];j<mat_graph->xadj[i+1];j++){ 3130a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d ",mat_graph->adjncy[j]);CHKERRQ(ierr); 3131e269702eSStefano Zampini } 3132a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n--------------------------------------------------------------\n");CHKERRQ(ierr); 3133*da1bb401SStefano Zampini }*/ 3134d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Matrix graph has %d connected components", mat_graph->ncmps);CHKERRQ(ierr); 31350c7d97c5SJed Brown for(i=0;i<mat_graph->ncmps;i++) { 31363b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\nDetails for connected component number %02d: size %04d, count %01d. Nodes follow.\n", 31373b03a366Sstefano_zampini i,mat_graph->cptr[i+1]-mat_graph->cptr[i],mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]);CHKERRQ(ierr); 3138*da1bb401SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"subdomains: "); 3139*da1bb401SStefano Zampini for (j=0;j<mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]; j++) { 3140*da1bb401SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d ",mat_graph->neighbours_set[mat_graph->queue[mat_graph->cptr[i]]][j]); 3141*da1bb401SStefano Zampini } 3142*da1bb401SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n"); 31430c7d97c5SJed Brown for (j=mat_graph->cptr[i]; j<mat_graph->cptr[i+1]; j++){ 3144*da1bb401SStefano Zampini /* ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d (%d), ",queue_in_global_numbering[j],mat_graph->queue[j]);CHKERRQ(ierr); */ 3145*da1bb401SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d, ",mat_graph->queue[j]);CHKERRQ(ierr); 31460c7d97c5SJed Brown } 31470c7d97c5SJed Brown } 3148*da1bb401SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n--------------------------------------------------------------\n");CHKERRQ(ierr); 31493b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local vertices\n",PetscGlobalRank,nvc);CHKERRQ(ierr); 31503b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local faces\n",PetscGlobalRank,nfc);CHKERRQ(ierr); 31513b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local edges\n",PetscGlobalRank,nec);CHKERRQ(ierr); 3152d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 31530c7d97c5SJed Brown } 31540c7d97c5SJed Brown 3155a0ba757dSStefano Zampini /* Free graph structure */ 31560c7d97c5SJed Brown if(mat_graph->nvtxs){ 3157a0ba757dSStefano Zampini ierr = PetscFree4(mat_graph->where,mat_graph->count,mat_graph->cptr,mat_graph->queue);CHKERRQ(ierr); 3158a0ba757dSStefano Zampini ierr = PetscFree3(mat_graph->which_dof,mat_graph->touched,queue_in_global_numbering);CHKERRQ(ierr); 3159a0ba757dSStefano Zampini ierr = PetscFree(mat_graph->where_ncmps);CHKERRQ(ierr); 31600c7d97c5SJed Brown } 31610c7d97c5SJed Brown 31620c7d97c5SJed Brown PetscFunctionReturn(0); 31630c7d97c5SJed Brown 31640c7d97c5SJed Brown } 31650c7d97c5SJed Brown 31660c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 31670c7d97c5SJed Brown 31680c7d97c5SJed Brown /* The following code has been adapted from function IsConnectedSubdomain contained 3169*da1bb401SStefano Zampini in source file contig.c of METIS library (version 5.0.1) 3170*da1bb401SStefano Zampini It finds connected components of each partition labeled from 1 to n_dist */ 31710c7d97c5SJed Brown 31720c7d97c5SJed Brown #undef __FUNCT__ 31730c7d97c5SJed Brown #define __FUNCT__ "PCBDDCFindConnectedComponents" 31749c0446d6SStefano Zampini static PetscErrorCode PCBDDCFindConnectedComponents(PCBDDCGraph graph, PetscInt n_dist ) 31750c7d97c5SJed Brown { 31760c7d97c5SJed Brown PetscInt i, j, k, nvtxs, first, last, nleft, ncmps,pid,cum_queue,n,ncmps_pid; 31770c7d97c5SJed Brown PetscInt *xadj, *adjncy, *where, *queue; 31780c7d97c5SJed Brown PetscInt *cptr; 31790c7d97c5SJed Brown PetscBool *touched; 31800c7d97c5SJed Brown 31810c7d97c5SJed Brown PetscFunctionBegin; 31820c7d97c5SJed Brown 31830c7d97c5SJed Brown nvtxs = graph->nvtxs; 31840c7d97c5SJed Brown xadj = graph->xadj; 31850c7d97c5SJed Brown adjncy = graph->adjncy; 31860c7d97c5SJed Brown where = graph->where; 31870c7d97c5SJed Brown touched = graph->touched; 31880c7d97c5SJed Brown queue = graph->queue; 31890c7d97c5SJed Brown cptr = graph->cptr; 31900c7d97c5SJed Brown 31910c7d97c5SJed Brown for (i=0; i<nvtxs; i++) 31920c7d97c5SJed Brown touched[i] = PETSC_FALSE; 31930c7d97c5SJed Brown 31940c7d97c5SJed Brown cum_queue=0; 31950c7d97c5SJed Brown ncmps=0; 31960c7d97c5SJed Brown 31970c7d97c5SJed Brown for(n=0; n<n_dist; n++) { 3198*da1bb401SStefano Zampini pid = n+1; /* partition labeled by 0 is discarded */ 31990c7d97c5SJed Brown nleft = 0; 32000c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 32010c7d97c5SJed Brown if (where[i] == pid) 32020c7d97c5SJed Brown nleft++; 32030c7d97c5SJed Brown } 32040c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 32050c7d97c5SJed Brown if (where[i] == pid) 32060c7d97c5SJed Brown break; 32070c7d97c5SJed Brown } 32080c7d97c5SJed Brown touched[i] = PETSC_TRUE; 32090c7d97c5SJed Brown queue[cum_queue] = i; 32100c7d97c5SJed Brown first = 0; last = 1; 32110c7d97c5SJed Brown cptr[ncmps] = cum_queue; /* This actually points to queue */ 32120c7d97c5SJed Brown ncmps_pid = 0; 32130c7d97c5SJed Brown while (first != nleft) { 32140c7d97c5SJed Brown if (first == last) { /* Find another starting vertex */ 32150c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 32160c7d97c5SJed Brown ncmps_pid++; 32170c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 32180c7d97c5SJed Brown if (where[i] == pid && !touched[i]) 32190c7d97c5SJed Brown break; 32200c7d97c5SJed Brown } 32210c7d97c5SJed Brown queue[cum_queue+last] = i; 32220c7d97c5SJed Brown last++; 32230c7d97c5SJed Brown touched[i] = PETSC_TRUE; 32240c7d97c5SJed Brown } 32250c7d97c5SJed Brown i = queue[cum_queue+first]; 32260c7d97c5SJed Brown first++; 32270c7d97c5SJed Brown for (j=xadj[i]; j<xadj[i+1]; j++) { 32280c7d97c5SJed Brown k = adjncy[j]; 32290c7d97c5SJed Brown if (where[k] == pid && !touched[k]) { 32300c7d97c5SJed Brown queue[cum_queue+last] = k; 32310c7d97c5SJed Brown last++; 32320c7d97c5SJed Brown touched[k] = PETSC_TRUE; 32330c7d97c5SJed Brown } 32340c7d97c5SJed Brown } 32350c7d97c5SJed Brown } 32360c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 32370c7d97c5SJed Brown ncmps_pid++; 32380c7d97c5SJed Brown cum_queue=cptr[ncmps]; 3239a0ba757dSStefano Zampini graph->where_ncmps[n] = ncmps_pid; 32400c7d97c5SJed Brown } 32410c7d97c5SJed Brown graph->ncmps = ncmps; 32420c7d97c5SJed Brown 32430c7d97c5SJed Brown PetscFunctionReturn(0); 32440c7d97c5SJed Brown } 32450c7d97c5SJed Brown 3246