153cdbc3dSStefano Zampini /* TODOLIST 2da1bb401SStefano Zampini DofSplitting and DM attached to pc? 3da1bb401SStefano Zampini Change SetNeumannBoundaries to SetNeumannBoundariesLocal and provide new SetNeumannBoundaries (same Dirichlet) 4da1bb401SStefano 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 */ 44da1bb401SStefano 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); 45da1bb401SStefano 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); 46da1bb401SStefano 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); 47da1bb401SStefano 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 */ 49da1bb401SStefano 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: 84da1bb401SStefano 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 /*@ 116da1bb401SStefano Zampini PCBDDCSetDirichletBoundaries - Set index set defining subdomain part (in local ordering) 117da1bb401SStefano 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 /*@ 159da1bb401SStefano Zampini PCBDDCSetNeumannBoundaries - Set index set defining subdomain part (in local ordering) 160da1bb401SStefano 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__ 186da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC" 187da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 188da1bb401SStefano Zampini { 189da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 190da1bb401SStefano Zampini 191da1bb401SStefano Zampini PetscFunctionBegin; 192da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 193da1bb401SStefano Zampini PetscFunctionReturn(0); 194da1bb401SStefano Zampini } 195da1bb401SStefano Zampini EXTERN_C_END 196da1bb401SStefano Zampini #undef __FUNCT__ 197da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries" 198da1bb401SStefano Zampini /*@ 199da1bb401SStefano Zampini PCBDDCGetDirichletBoundaries - Get index set defining subdomain part (in local ordering) 200da1bb401SStefano Zampini of Dirichlet boundaries for the global problem. 201da1bb401SStefano Zampini 202da1bb401SStefano Zampini Not collective 203da1bb401SStefano Zampini 204da1bb401SStefano Zampini Input Parameters: 205da1bb401SStefano Zampini + pc - the preconditioning context 206da1bb401SStefano Zampini 207da1bb401SStefano Zampini Output Parameters: 208da1bb401SStefano Zampini + DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 209da1bb401SStefano Zampini 210da1bb401SStefano Zampini Level: intermediate 211da1bb401SStefano Zampini 212da1bb401SStefano Zampini Notes: 213da1bb401SStefano Zampini 214da1bb401SStefano Zampini .seealso: PCBDDC 215da1bb401SStefano Zampini @*/ 216da1bb401SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 217da1bb401SStefano Zampini { 218da1bb401SStefano Zampini PetscErrorCode ierr; 219da1bb401SStefano Zampini 220da1bb401SStefano Zampini PetscFunctionBegin; 221da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 222da1bb401SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 223da1bb401SStefano Zampini PetscFunctionReturn(0); 224da1bb401SStefano Zampini } 225da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 226da1bb401SStefano Zampini EXTERN_C_BEGIN 227da1bb401SStefano 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 /*@ 241da1bb401SStefano Zampini PCBDDCGetNeumannBoundaries - Get index set defining subdomain part (in local ordering) 242da1bb401SStefano 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__ 270da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC" 271da1bb401SStefano 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; 274da1bb401SStefano Zampini PCBDDCGraph mat_graph=pcbddc->mat_graph; 275da1bb401SStefano Zampini PetscErrorCode ierr; 27636e030ebSStefano Zampini 27736e030ebSStefano Zampini PetscFunctionBegin; 278da1bb401SStefano Zampini mat_graph->nvtxs=nvtxs; 279da1bb401SStefano Zampini ierr = PetscFree(mat_graph->xadj);CHKERRQ(ierr); 280da1bb401SStefano Zampini ierr = PetscFree(mat_graph->adjncy);CHKERRQ(ierr); 281da1bb401SStefano Zampini if(copymode == PETSC_COPY_VALUES) { 282da1bb401SStefano Zampini ierr = PetscMalloc((mat_graph->nvtxs+1)*sizeof(PetscInt),&mat_graph->xadj);CHKERRQ(ierr); 283da1bb401SStefano Zampini ierr = PetscMalloc(xadj[mat_graph->nvtxs]*sizeof(PetscInt),&mat_graph->adjncy);CHKERRQ(ierr); 284da1bb401SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(mat_graph->nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 285da1bb401SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[mat_graph->nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 286da1bb401SStefano Zampini } else if(copymode == PETSC_OWN_POINTER) { 287da1bb401SStefano Zampini mat_graph->xadj=xadj; 288da1bb401SStefano Zampini mat_graph->adjncy=adjncy; 289da1bb401SStefano Zampini } else { 290da1bb401SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d in %s\n",copymode,__FUNCT__); 291da1bb401SStefano Zampini } 29236e030ebSStefano Zampini PetscFunctionReturn(0); 29336e030ebSStefano Zampini } 29436e030ebSStefano Zampini EXTERN_C_END 29536e030ebSStefano Zampini #undef __FUNCT__ 296da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph" 29736e030ebSStefano Zampini /*@ 298da1bb401SStefano 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 304da1bb401SStefano Zampini - nvtxs - number of local vertices of the graph 305da1bb401SStefano Zampini - xadj, adjncy - the CSR graph 306da1bb401SStefano Zampini - copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER. In the former case the user must free the array passed in; 307da1bb401SStefano 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 @*/ 315da1bb401SStefano Zampini PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,PetscInt xadj[],PetscInt adjncy[], PetscCopyMode copymode) 31636e030ebSStefano Zampini { 317da1bb401SStefano Zampini PetscInt nrows,ncols; 318da1bb401SStefano 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); 323da1bb401SStefano Zampini ierr = MatGetSize(matis->A,&nrows,&ncols);CHKERRQ(ierr); 324da1bb401SStefano Zampini if(nvtxs != nrows) { 325da1bb401SStefano 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); 326da1bb401SStefano Zampini } else { 327da1bb401SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,PetscInt[],PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 328da1bb401SStefano 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; 342da1bb401SStefano 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); 347da1bb401SStefano 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++) { 350da1bb401SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 351da1bb401SStefano 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 /*@ 360da1bb401SStefano 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 366da1bb401SStefano Zampini - n - number of index sets defining the fields 367da1bb401SStefano 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 } 384da1bb401SStefano 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; 4602617d88aSStefano Zampini const PetscScalar zero = 0.0; 4610c7d97c5SJed Brown 4620c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 4630c7d97c5SJed Brown NN interface preconditioner changed to BDDC 4640c7d97c5SJed Brown Added support for M_3 preconditioenr in the reference article (code is active if pcbddc->prec_type = PETSC_TRUE) */ 4650c7d97c5SJed Brown 4660c7d97c5SJed Brown PetscFunctionBegin; 4670c7d97c5SJed Brown /* First Dirichlet solve */ 4680c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4690c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 47053cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 4710c7d97c5SJed Brown /* 4720c7d97c5SJed Brown Assembling right hand side for BDDC operator 4730c7d97c5SJed Brown - vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE) 4740c7d97c5SJed Brown - the interface part of the global vector z 4750c7d97c5SJed Brown */ 4760c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 4770c7d97c5SJed Brown ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 4780c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 4790c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 4800c7d97c5SJed Brown ierr = VecCopy(r,z);CHKERRQ(ierr); 4810c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4820c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4830c7d97c5SJed Brown 4842617d88aSStefano Zampini /* Get Local boundary and apply partition of unity */ 4852617d88aSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4862617d88aSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4872617d88aSStefano Zampini ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 4882617d88aSStefano Zampini 4892617d88aSStefano Zampini /* Apply interface preconditioner 4902617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 4912617d88aSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc);CHKERRQ(ierr); 4922617d88aSStefano Zampini 4932617d88aSStefano Zampini /* Apply partition of unity and sum boundary values */ 4942617d88aSStefano Zampini ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 4952617d88aSStefano Zampini ierr = VecSet(z,zero);CHKERRQ(ierr); 4962617d88aSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4972617d88aSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4980c7d97c5SJed Brown 4993b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 5000c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5010c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5020c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 5030c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 50453cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr); 5050c7d97c5SJed Brown ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr); 5060c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); } 5070c7d97c5SJed Brown ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr); 5080c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5090c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5100c7d97c5SJed Brown 5110c7d97c5SJed Brown PetscFunctionReturn(0); 5120c7d97c5SJed Brown 5130c7d97c5SJed Brown } 514da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 515da1bb401SStefano Zampini #undef __FUNCT__ 516da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC" 517da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 518da1bb401SStefano Zampini { 519da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 520da1bb401SStefano Zampini PetscErrorCode ierr; 521da1bb401SStefano Zampini 522da1bb401SStefano Zampini PetscFunctionBegin; 523da1bb401SStefano Zampini /* free data created by PCIS */ 524da1bb401SStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 525da1bb401SStefano Zampini /* free BDDC data */ 526da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 527da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_rhs);CHKERRQ(ierr); 528da1bb401SStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 529da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_mat);CHKERRQ(ierr); 530da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 531da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 532da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 533da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 534da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 535da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 536da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 537da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 538da1bb401SStefano Zampini ierr = VecDestroy(&pcbddc->vec4_D);CHKERRQ(ierr); 539da1bb401SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 540da1bb401SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 541da1bb401SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 542da1bb401SStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 543da1bb401SStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 544da1bb401SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 545da1bb401SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 546da1bb401SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 547da1bb401SStefano Zampini ierr = PetscFree(pcbddc->local_primal_indices);CHKERRQ(ierr); 548da1bb401SStefano Zampini ierr = PetscFree(pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 549da1bb401SStefano Zampini if (pcbddc->replicated_local_primal_values) { free(pcbddc->replicated_local_primal_values); } 550da1bb401SStefano Zampini ierr = PetscFree(pcbddc->local_primal_displacements);CHKERRQ(ierr); 551da1bb401SStefano Zampini ierr = PetscFree(pcbddc->local_primal_sizes);CHKERRQ(ierr); 552da1bb401SStefano Zampini PetscInt i; 553da1bb401SStefano Zampini for(i=0;i<pcbddc->n_ISForDofs;i++) { ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); } 554da1bb401SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 555da1bb401SStefano Zampini for(i=0;i<pcbddc->n_ISForFaces;i++) { ierr = ISDestroy(&pcbddc->ISForFaces[i]);CHKERRQ(ierr); } 556da1bb401SStefano Zampini ierr = PetscFree(pcbddc->ISForFaces);CHKERRQ(ierr); 557da1bb401SStefano Zampini for(i=0;i<pcbddc->n_ISForEdges;i++) { ierr = ISDestroy(&pcbddc->ISForEdges[i]);CHKERRQ(ierr); } 558da1bb401SStefano Zampini ierr = PetscFree(pcbddc->ISForEdges);CHKERRQ(ierr); 559da1bb401SStefano Zampini ierr = ISDestroy(&pcbddc->ISForVertices);CHKERRQ(ierr); 560da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->xadj);CHKERRQ(ierr); 561da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->adjncy);CHKERRQ(ierr); 562da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->neighbours_set[0]);CHKERRQ(ierr); 563da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->neighbours_set);CHKERRQ(ierr); 564da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr); 565da1bb401SStefano Zampini /* Free the private data structure that was hanging off the PC */ 566da1bb401SStefano Zampini ierr = PetscFree(pcbddc);CHKERRQ(ierr); 567da1bb401SStefano Zampini PetscFunctionReturn(0); 568da1bb401SStefano Zampini } 5690c7d97c5SJed Brown 5700c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 571da1bb401SStefano Zampini /*MC 572da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 5730c7d97c5SJed Brown 574da1bb401SStefano Zampini Options Database Keys: 575da1bb401SStefano Zampini . -pcbddc ??? - 576da1bb401SStefano Zampini 577da1bb401SStefano Zampini Level: intermediate 578da1bb401SStefano Zampini 579da1bb401SStefano Zampini Notes: The matrix used with this preconditioner must be of type MATIS 580da1bb401SStefano Zampini 581da1bb401SStefano Zampini Unlike more 'conventional' interface preconditioners, this iterates over ALL the 582da1bb401SStefano Zampini degrees of freedom, NOT just those on the interface (this allows the use of approximate solvers 583da1bb401SStefano Zampini on the subdomains). 584da1bb401SStefano Zampini 585da1bb401SStefano Zampini Options for the coarse grid preconditioner can be set with - 586da1bb401SStefano Zampini Options for the Dirichlet subproblem can be set with - 587da1bb401SStefano Zampini Options for the Neumann subproblem can be set with - 588da1bb401SStefano Zampini 589da1bb401SStefano Zampini Contributed by Stefano Zampini 590da1bb401SStefano Zampini 591da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 592da1bb401SStefano Zampini M*/ 593da1bb401SStefano Zampini EXTERN_C_BEGIN 594da1bb401SStefano Zampini #undef __FUNCT__ 595da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC" 596da1bb401SStefano Zampini PetscErrorCode PCCreate_BDDC(PC pc) 597da1bb401SStefano Zampini { 598da1bb401SStefano Zampini PetscErrorCode ierr; 599da1bb401SStefano Zampini PC_BDDC *pcbddc; 600da1bb401SStefano Zampini PCBDDCGraph mat_graph; 601da1bb401SStefano Zampini 602da1bb401SStefano Zampini PetscFunctionBegin; 603da1bb401SStefano Zampini /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 604da1bb401SStefano Zampini ierr = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr); 605da1bb401SStefano Zampini pc->data = (void*)pcbddc; 606da1bb401SStefano Zampini 607da1bb401SStefano Zampini /* create PCIS data structure */ 608da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 609da1bb401SStefano Zampini 610da1bb401SStefano Zampini /* BDDC specific */ 611da1bb401SStefano Zampini pcbddc->coarse_vec = 0; 612da1bb401SStefano Zampini pcbddc->coarse_rhs = 0; 613da1bb401SStefano Zampini pcbddc->coarse_ksp = 0; 614da1bb401SStefano Zampini pcbddc->coarse_phi_B = 0; 615da1bb401SStefano Zampini pcbddc->coarse_phi_D = 0; 616da1bb401SStefano Zampini pcbddc->vec1_P = 0; 617da1bb401SStefano Zampini pcbddc->vec1_R = 0; 618da1bb401SStefano Zampini pcbddc->vec2_R = 0; 619da1bb401SStefano Zampini pcbddc->local_auxmat1 = 0; 620da1bb401SStefano Zampini pcbddc->local_auxmat2 = 0; 621da1bb401SStefano Zampini pcbddc->R_to_B = 0; 622da1bb401SStefano Zampini pcbddc->R_to_D = 0; 623da1bb401SStefano Zampini pcbddc->ksp_D = 0; 624da1bb401SStefano Zampini pcbddc->ksp_R = 0; 625da1bb401SStefano Zampini pcbddc->local_primal_indices = 0; 626da1bb401SStefano Zampini pcbddc->prec_type = PETSC_FALSE; 627da1bb401SStefano Zampini pcbddc->NeumannBoundaries = 0; 628da1bb401SStefano Zampini pcbddc->ISForDofs = 0; 629da1bb401SStefano Zampini pcbddc->ISForVertices = 0; 630da1bb401SStefano Zampini pcbddc->n_ISForFaces = 0; 631da1bb401SStefano Zampini pcbddc->n_ISForEdges = 0; 632da1bb401SStefano Zampini pcbddc->ConstraintMatrix = 0; 633da1bb401SStefano Zampini pcbddc->use_nnsp_true = PETSC_FALSE; 634da1bb401SStefano Zampini pcbddc->local_primal_sizes = 0; 635da1bb401SStefano Zampini pcbddc->local_primal_displacements = 0; 636da1bb401SStefano Zampini pcbddc->replicated_local_primal_indices = 0; 637da1bb401SStefano Zampini pcbddc->replicated_local_primal_values = 0; 638da1bb401SStefano Zampini pcbddc->coarse_loc_to_glob = 0; 639da1bb401SStefano Zampini pcbddc->dbg_flag = PETSC_FALSE; 640da1bb401SStefano Zampini pcbddc->coarsening_ratio = 8; 641da1bb401SStefano Zampini 642da1bb401SStefano Zampini /* allocate and initialize needed graph structure */ 643da1bb401SStefano Zampini ierr = PetscMalloc(sizeof(*mat_graph),&pcbddc->mat_graph);CHKERRQ(ierr); 644da1bb401SStefano Zampini pcbddc->mat_graph->xadj = 0; 645da1bb401SStefano Zampini pcbddc->mat_graph->adjncy = 0; 646da1bb401SStefano Zampini 647da1bb401SStefano Zampini /* function pointers */ 648da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 649da1bb401SStefano Zampini pc->ops->applytranspose = 0; 650da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 651da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 652da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 653da1bb401SStefano Zampini pc->ops->view = 0; 654da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 655da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 656da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 657da1bb401SStefano Zampini 658da1bb401SStefano Zampini /* composing function */ 659da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C","PCBDDCSetDirichletBoundaries_BDDC", 660da1bb401SStefano Zampini PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 661da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C","PCBDDCSetNeumannBoundaries_BDDC", 662da1bb401SStefano Zampini PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 663da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C","PCBDDCGetDirichletBoundaries_BDDC", 664da1bb401SStefano Zampini PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 665da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C","PCBDDCGetNeumannBoundaries_BDDC", 666da1bb401SStefano Zampini PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 667da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetCoarseProblemType_C","PCBDDCSetCoarseProblemType_BDDC", 668da1bb401SStefano Zampini PCBDDCSetCoarseProblemType_BDDC);CHKERRQ(ierr); 669da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetDofsSplitting_C","PCBDDCSetDofsSplitting_BDDC", 670da1bb401SStefano Zampini PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 671da1bb401SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C","PCBDDCSetLocalAdjacencyGraph_BDDC", 672da1bb401SStefano Zampini PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 673da1bb401SStefano Zampini PetscFunctionReturn(0); 674da1bb401SStefano Zampini } 675da1bb401SStefano Zampini EXTERN_C_END 676da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 677da1bb401SStefano Zampini /* All static functions from now on */ 678da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 679da1bb401SStefano Zampini #undef __FUNCT__ 680da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetupLocalAdjacencyGraph" 681da1bb401SStefano Zampini static PetscErrorCode PCBDDCSetupLocalAdjacencyGraph(PC pc) 682da1bb401SStefano Zampini { 683da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 684da1bb401SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 685da1bb401SStefano Zampini PetscInt nvtxs,*xadj,*adjncy; 686da1bb401SStefano Zampini Mat mat_adj; 687da1bb401SStefano Zampini PetscBool symmetrize_rowij=PETSC_TRUE,compressed_rowij=PETSC_FALSE,flg_row=PETSC_TRUE; 688da1bb401SStefano Zampini PCBDDCGraph mat_graph=pcbddc->mat_graph; 689da1bb401SStefano Zampini PetscErrorCode ierr; 690da1bb401SStefano Zampini 691da1bb401SStefano Zampini PetscFunctionBegin; 692da1bb401SStefano Zampini /* get CSR adjacency from local matrix if user has not yet provided local graph using PCBDDCSetLocalAdjacencyGraph function */ 693da1bb401SStefano Zampini if(!mat_graph->xadj) { 694da1bb401SStefano Zampini ierr = MatConvert(matis->A,MATMPIADJ,MAT_INITIAL_MATRIX,&mat_adj);CHKERRQ(ierr); 695da1bb401SStefano Zampini ierr = MatGetRowIJ(mat_adj,0,symmetrize_rowij,compressed_rowij,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 696da1bb401SStefano Zampini if(!flg_row) { 697da1bb401SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatGetRowIJ called in %s\n",__FUNCT__); 698da1bb401SStefano Zampini } 699da1bb401SStefano Zampini /* Get adjacency into BDDC workspace */ 700da1bb401SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 701da1bb401SStefano Zampini ierr = MatRestoreRowIJ(mat_adj,0,symmetrize_rowij,compressed_rowij,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 702da1bb401SStefano Zampini if(!flg_row) { 703da1bb401SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called in %s\n",__FUNCT__); 704da1bb401SStefano Zampini } 705da1bb401SStefano Zampini ierr = MatDestroy(&mat_adj);CHKERRQ(ierr); 706da1bb401SStefano Zampini } 707da1bb401SStefano Zampini PetscFunctionReturn(0); 708da1bb401SStefano Zampini } 709da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 7100c7d97c5SJed Brown #undef __FUNCT__ 7110c7d97c5SJed Brown #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 7122617d88aSStefano Zampini static PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc) 7130c7d97c5SJed Brown { 7140c7d97c5SJed Brown PetscErrorCode ierr; 7150c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 7160c7d97c5SJed Brown PC_IS* pcis = (PC_IS*) (pc->data); 7173b03a366Sstefano_zampini const PetscScalar zero = 0.0; 7180c7d97c5SJed Brown 7190c7d97c5SJed Brown PetscFunctionBegin; 7200c7d97c5SJed Brown /* Application of PHI^T */ 7210c7d97c5SJed Brown ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 7220c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 7230c7d97c5SJed Brown 7240c7d97c5SJed Brown /* Scatter data of coarse_rhs */ 7250c7d97c5SJed Brown if(pcbddc->coarse_rhs) ierr = VecSet(pcbddc->coarse_rhs,zero);CHKERRQ(ierr); 7260c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7270c7d97c5SJed Brown 7280c7d97c5SJed Brown /* Local solution on R nodes */ 7290c7d97c5SJed Brown ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 7300c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7310c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7320c7d97c5SJed Brown if(pcbddc->prec_type) { 7330c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7340c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7350c7d97c5SJed Brown } 7360c7d97c5SJed Brown ierr = PCBDDCSolveSaddlePoint(pc);CHKERRQ(ierr); 7370c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 7380c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7390c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7400c7d97c5SJed Brown if(pcbddc->prec_type) { 7410c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7420c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7430c7d97c5SJed Brown } 7440c7d97c5SJed Brown 7450c7d97c5SJed Brown /* Coarse solution */ 7460c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 74753cdbc3dSStefano Zampini if(pcbddc->coarse_rhs) ierr = KSPSolve(pcbddc->coarse_ksp,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 7480c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7490c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd (pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7500c7d97c5SJed Brown 7510c7d97c5SJed Brown /* Sum contributions from two levels */ 7520c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 7530c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 7540c7d97c5SJed Brown PetscFunctionReturn(0); 7550c7d97c5SJed Brown } 7560c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 7570c7d97c5SJed Brown #undef __FUNCT__ 7580c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSolveSaddlePoint" 75953cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSolveSaddlePoint(PC pc) 7600c7d97c5SJed Brown { 7610c7d97c5SJed Brown PetscErrorCode ierr; 7620c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 7630c7d97c5SJed Brown 7640c7d97c5SJed Brown PetscFunctionBegin; 76553cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 7660c7d97c5SJed Brown if(pcbddc->n_constraints) { 7670c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec2_R,pcbddc->vec1_C);CHKERRQ(ierr); 7680c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 7690c7d97c5SJed Brown } 7700c7d97c5SJed Brown PetscFunctionReturn(0); 7710c7d97c5SJed Brown } 7720c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 7730c7d97c5SJed Brown #undef __FUNCT__ 7740c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 77553cdbc3dSStefano Zampini static PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,Vec vec_from, Vec vec_to, InsertMode imode, ScatterMode smode) 7760c7d97c5SJed Brown { 7770c7d97c5SJed Brown PetscErrorCode ierr; 7780c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 7790c7d97c5SJed Brown 7800c7d97c5SJed Brown PetscFunctionBegin; 7810c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 7820c7d97c5SJed Brown case SCATTERS_BDDC: 7830c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 7840c7d97c5SJed Brown break; 7850c7d97c5SJed Brown case GATHERS_BDDC: 7860c7d97c5SJed Brown break; 7870c7d97c5SJed Brown } 7880c7d97c5SJed Brown PetscFunctionReturn(0); 7890c7d97c5SJed Brown } 7900c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 7910c7d97c5SJed Brown #undef __FUNCT__ 7920c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 79353cdbc3dSStefano Zampini static PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc,Vec vec_from, Vec vec_to, InsertMode imode, ScatterMode smode) 7940c7d97c5SJed Brown { 7950c7d97c5SJed Brown PetscErrorCode ierr; 7960c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 7970c7d97c5SJed Brown PetscScalar* array_to; 7980c7d97c5SJed Brown PetscScalar* array_from; 7990c7d97c5SJed Brown MPI_Comm comm=((PetscObject)pc)->comm; 8000c7d97c5SJed Brown PetscInt i; 8010c7d97c5SJed Brown 8020c7d97c5SJed Brown PetscFunctionBegin; 8030c7d97c5SJed Brown 8040c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 8050c7d97c5SJed Brown case SCATTERS_BDDC: 8060c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 8070c7d97c5SJed Brown break; 8080c7d97c5SJed Brown case GATHERS_BDDC: 8090c7d97c5SJed Brown if(vec_from) VecGetArray(vec_from,&array_from); 8100c7d97c5SJed Brown if(vec_to) VecGetArray(vec_to,&array_to); 8110c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 8120c7d97c5SJed Brown case SEQUENTIAL_BDDC: 8130c7d97c5SJed Brown if(smode == SCATTER_FORWARD) { 81453cdbc3dSStefano 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); 8150c7d97c5SJed Brown if(vec_to) { 8160c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 8170c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 8180c7d97c5SJed Brown } 8190c7d97c5SJed Brown } else { 8200c7d97c5SJed Brown if(vec_from) 8210c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 8220c7d97c5SJed Brown pcbddc->replicated_local_primal_values[i]=array_from[pcbddc->replicated_local_primal_indices[i]]; 82353cdbc3dSStefano 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); 8240c7d97c5SJed Brown } 8250c7d97c5SJed Brown break; 8260c7d97c5SJed Brown case REPLICATED_BDDC: 8270c7d97c5SJed Brown if(smode == SCATTER_FORWARD) { 82853cdbc3dSStefano 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); 8290c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 8300c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 8310c7d97c5SJed Brown } else { /* no communications needed for SCATTER_REVERSE since needed data is already present */ 8320c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_size;i++) 8330c7d97c5SJed Brown array_to[i]=array_from[pcbddc->local_primal_indices[i]]; 8340c7d97c5SJed Brown } 8350c7d97c5SJed Brown break; 83653cdbc3dSStefano Zampini case MULTILEVEL_BDDC: 83753cdbc3dSStefano Zampini break; 83853cdbc3dSStefano Zampini case PARALLEL_BDDC: 83953cdbc3dSStefano Zampini break; 8400c7d97c5SJed Brown } 8410c7d97c5SJed Brown if(vec_from) VecRestoreArray(vec_from,&array_from); 8420c7d97c5SJed Brown if(vec_to) VecRestoreArray(vec_to,&array_to); 8430c7d97c5SJed Brown break; 8440c7d97c5SJed Brown } 8450c7d97c5SJed Brown PetscFunctionReturn(0); 8460c7d97c5SJed Brown } 8470c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 848de534f79Sstefano_zampini #ifdef BDDC_USE_POD 849de534f79Sstefano_zampini #if !defined(PETSC_MISSING_LAPACK_GESVD) 8503b03a366Sstefano_zampini #define PETSC_MISSING_LAPACK_GESVD 1 851de534f79Sstefano_zampini #define UNDEF_PETSC_MISSING_LAPACK_GESVD 1 852de534f79Sstefano_zampini #endif 8533b03a366Sstefano_zampini #endif 8543b03a366Sstefano_zampini 8553b03a366Sstefano_zampini #undef __FUNCT__ 8563b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCCreateConstraintMatrix" 8573b03a366Sstefano_zampini static PetscErrorCode PCBDDCCreateConstraintMatrix(PC pc) 8583b03a366Sstefano_zampini { 8593b03a366Sstefano_zampini PetscErrorCode ierr; 8603b03a366Sstefano_zampini PC_IS* pcis = (PC_IS*)(pc->data); 8613b03a366Sstefano_zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 8623b03a366Sstefano_zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 8633b03a366Sstefano_zampini PetscInt *nnz,*vertices,*is_indices; 8643b03a366Sstefano_zampini PetscScalar *temp_quadrature_constraint; 8653b03a366Sstefano_zampini PetscInt *temp_indices,*temp_indices_to_constraint; 8663b03a366Sstefano_zampini PetscInt local_primal_size,i,j,k,total_counts,max_size_of_constraint; 8673b03a366Sstefano_zampini PetscInt n_constraints,n_vertices,size_of_constraint; 8683b03a366Sstefano_zampini PetscReal quad_value; 8693b03a366Sstefano_zampini PetscBool nnsp_has_cnst=PETSC_FALSE,use_nnsp_true=pcbddc->use_nnsp_true; 8703b03a366Sstefano_zampini PetscInt nnsp_size=0,nnsp_addone=0,temp_constraints,temp_start_ptr; 8713b03a366Sstefano_zampini IS *used_IS; 8723b03a366Sstefano_zampini const MatType impMatType=MATSEQAIJ; 8733b03a366Sstefano_zampini PetscBLASInt Bs,Bt,lwork,lierr; 8743b03a366Sstefano_zampini PetscReal tol=1.0e-8; 875fcda91b4SJed Brown MatNullSpace nearnullsp; 876fcda91b4SJed Brown const Vec *nearnullvecs; 8773b03a366Sstefano_zampini Vec *localnearnullsp; 8783b03a366Sstefano_zampini PetscScalar *work,*temp_basis,*array_vector,*correlation_mat; 8793b03a366Sstefano_zampini PetscReal *rwork,*singular_vals; 880de534f79Sstefano_zampini PetscBLASInt Bone=1; 881de534f79Sstefano_zampini /* some ugly conditional declarations */ 8823b03a366Sstefano_zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 8833b03a366Sstefano_zampini PetscScalar dot_result; 8843b03a366Sstefano_zampini PetscScalar one=1.0,zero=0.0; 8853b03a366Sstefano_zampini PetscInt ii; 8863b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 8873b03a366Sstefano_zampini PetscScalar val1,val2; 8883b03a366Sstefano_zampini #endif 8893b03a366Sstefano_zampini #else 8903b03a366Sstefano_zampini PetscBLASInt dummy_int; 8913b03a366Sstefano_zampini PetscScalar dummy_scalar; 8923b03a366Sstefano_zampini #endif 8933b03a366Sstefano_zampini 8943b03a366Sstefano_zampini PetscFunctionBegin; 8953b03a366Sstefano_zampini /* check if near null space is attached to global mat */ 896fcda91b4SJed Brown ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 897fcda91b4SJed Brown if (nearnullsp) { 898fcda91b4SJed Brown ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 8993b03a366Sstefano_zampini } else { /* if near null space is not provided it uses constants */ 9003b03a366Sstefano_zampini nnsp_has_cnst = PETSC_TRUE; 9013b03a366Sstefano_zampini use_nnsp_true = PETSC_TRUE; 9023b03a366Sstefano_zampini } 9033b03a366Sstefano_zampini if(nnsp_has_cnst) { 9043b03a366Sstefano_zampini nnsp_addone = 1; 9053b03a366Sstefano_zampini } 9063b03a366Sstefano_zampini /* 9073b03a366Sstefano_zampini Evaluate maximum storage size needed by the procedure 9083b03a366Sstefano_zampini - temp_indices will contain start index of each constraint stored as follows 9093b03a366Sstefano_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 9103b03a366Sstefano_zampini - temp_quadrature_constraint[temp_indices[i],...,temp[indices[i+1]-1] will contain the scalars representing the constraint itself 9113b03a366Sstefano_zampini */ 912da1bb401SStefano Zampini 9133b03a366Sstefano_zampini total_counts = pcbddc->n_ISForFaces+pcbddc->n_ISForEdges; 9143b03a366Sstefano_zampini total_counts *= (nnsp_addone+nnsp_size); 915da1bb401SStefano Zampini ierr = ISGetSize(pcbddc->ISForVertices,&n_vertices);CHKERRQ(ierr); 916da1bb401SStefano Zampini total_counts += n_vertices; 9173b03a366Sstefano_zampini ierr = PetscMalloc((total_counts+1)*sizeof(PetscInt),&temp_indices);CHKERRQ(ierr); 9183b03a366Sstefano_zampini total_counts = 0; 9193b03a366Sstefano_zampini max_size_of_constraint = 0; 9203b03a366Sstefano_zampini for(i=0;i<pcbddc->n_ISForEdges+pcbddc->n_ISForFaces;i++){ 9213b03a366Sstefano_zampini if(i<pcbddc->n_ISForEdges){ 9223b03a366Sstefano_zampini used_IS = &pcbddc->ISForEdges[i]; 9233b03a366Sstefano_zampini } else { 9243b03a366Sstefano_zampini used_IS = &pcbddc->ISForFaces[i-pcbddc->n_ISForEdges]; 9253b03a366Sstefano_zampini } 9263b03a366Sstefano_zampini ierr = ISGetSize(*used_IS,&j);CHKERRQ(ierr); 9273b03a366Sstefano_zampini total_counts += j; 9283b03a366Sstefano_zampini if(j>max_size_of_constraint) max_size_of_constraint=j; 9293b03a366Sstefano_zampini } 9303b03a366Sstefano_zampini total_counts *= (nnsp_addone+nnsp_size); 931da1bb401SStefano Zampini total_counts += n_vertices; 9323b03a366Sstefano_zampini ierr = PetscMalloc(total_counts*sizeof(PetscScalar),&temp_quadrature_constraint);CHKERRQ(ierr); 9333b03a366Sstefano_zampini ierr = PetscMalloc(total_counts*sizeof(PetscInt),&temp_indices_to_constraint);CHKERRQ(ierr); 9343b03a366Sstefano_zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd or LAPACKsyev/LAPACKheev */ 9353b03a366Sstefano_zampini rwork = 0; 9363b03a366Sstefano_zampini work = 0; 9373b03a366Sstefano_zampini singular_vals = 0; 9383b03a366Sstefano_zampini temp_basis = 0; 9393b03a366Sstefano_zampini correlation_mat = 0; 9403b03a366Sstefano_zampini if(!pcbddc->use_nnsp_true) { 9413b03a366Sstefano_zampini PetscScalar temp_work; 9423b03a366Sstefano_zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 9433b03a366Sstefano_zampini /* POD */ 9443b03a366Sstefano_zampini PetscInt max_n; 9453b03a366Sstefano_zampini max_n = nnsp_addone+nnsp_size; 9463b03a366Sstefano_zampini /* using some techniques borrowed from Proper Orthogonal Decomposition */ 9473b03a366Sstefano_zampini ierr = PetscMalloc(max_n*max_n*sizeof(PetscScalar),&correlation_mat);CHKERRQ(ierr); 9483b03a366Sstefano_zampini ierr = PetscMalloc(max_n*sizeof(PetscReal),&singular_vals);CHKERRQ(ierr); 9493b03a366Sstefano_zampini ierr = PetscMalloc(max_size_of_constraint*(nnsp_addone+nnsp_size)*sizeof(PetscScalar),&temp_basis);CHKERRQ(ierr); 9503b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 9513b03a366Sstefano_zampini ierr = PetscMalloc(3*max_n*sizeof(PetscReal),&rwork);CHKERRQ(ierr); 9523b03a366Sstefano_zampini #endif 9533b03a366Sstefano_zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 9543b03a366Sstefano_zampini Bt = PetscBLASIntCast(max_n); 9553b03a366Sstefano_zampini lwork=-1; 9563b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 9573b03a366Sstefano_zampini LAPACKsyev_("V","U",&Bt,correlation_mat,&Bt,singular_vals,&temp_work,&lwork,&lierr); 9583b03a366Sstefano_zampini #else 9593b03a366Sstefano_zampini LAPACKsyev_("V","U",&Bt,correlation_mat,&Bt,singular_vals,&temp_work,&lwork,rwork,&lierr); 9603b03a366Sstefano_zampini #endif 9613b03a366Sstefano_zampini #else /* on missing GESVD */ 9623b03a366Sstefano_zampini /* SVD */ 9633b03a366Sstefano_zampini PetscInt max_n,min_n; 9643b03a366Sstefano_zampini max_n = max_size_of_constraint; 9653b03a366Sstefano_zampini min_n = nnsp_addone+nnsp_size; 9663b03a366Sstefano_zampini if(max_size_of_constraint < ( nnsp_addone+nnsp_size ) ) { 9673b03a366Sstefano_zampini min_n = max_size_of_constraint; 9683b03a366Sstefano_zampini max_n = nnsp_addone+nnsp_size; 9693b03a366Sstefano_zampini } 9703b03a366Sstefano_zampini ierr = PetscMalloc(min_n*sizeof(PetscReal),&singular_vals);CHKERRQ(ierr); 9713b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 9723b03a366Sstefano_zampini ierr = PetscMalloc(5*min_n*sizeof(PetscReal),&rwork);CHKERRQ(ierr); 9733b03a366Sstefano_zampini #endif 9743b03a366Sstefano_zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 9753b03a366Sstefano_zampini lwork=-1; 9763b03a366Sstefano_zampini Bs = PetscBLASIntCast(max_n); 9773b03a366Sstefano_zampini Bt = PetscBLASIntCast(min_n); 9783b03a366Sstefano_zampini dummy_int = Bs; 979670f3ff9SJed Brown ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 9803b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 9813b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[0],&Bs,singular_vals, 9823b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,&temp_work,&lwork,&lierr); 9833b03a366Sstefano_zampini #else 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,rwork,&lierr); 9863b03a366Sstefano_zampini #endif 9873b03a366Sstefano_zampini if ( lierr ) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SVD Lapack routine %d",(int)lierr); 988670f3ff9SJed Brown ierr = PetscFPTrapPop();CHKERRQ(ierr); 9893b03a366Sstefano_zampini #endif 9903b03a366Sstefano_zampini /* Allocate optimal workspace */ 9913b03a366Sstefano_zampini lwork = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work)); 9923b03a366Sstefano_zampini total_counts = (PetscInt)lwork; 9933b03a366Sstefano_zampini ierr = PetscMalloc(total_counts*sizeof(PetscScalar),&work);CHKERRQ(ierr); 9943b03a366Sstefano_zampini } 9953b03a366Sstefano_zampini /* get local part of global near null space vectors */ 9963b03a366Sstefano_zampini ierr = PetscMalloc(nnsp_size*sizeof(Vec),&localnearnullsp);CHKERRQ(ierr); 9973b03a366Sstefano_zampini for(k=0;k<nnsp_size;k++) { 9983b03a366Sstefano_zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 999fcda91b4SJed Brown ierr = VecScatterBegin(matis->ctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1000fcda91b4SJed Brown ierr = VecScatterEnd (matis->ctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 10013b03a366Sstefano_zampini } 10023b03a366Sstefano_zampini /* Now we can loop on constraining sets */ 10033b03a366Sstefano_zampini total_counts=0; 10043b03a366Sstefano_zampini temp_indices[0]=0; 1005da1bb401SStefano Zampini /* vertices */ 1006da1bb401SStefano Zampini PetscBool used_vertex; 1007da1bb401SStefano Zampini ierr = PetscMalloc(n_vertices*sizeof(PetscInt),&vertices);CHKERRQ(ierr); 1008da1bb401SStefano Zampini ierr = ISGetIndices(pcbddc->ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1009da1bb401SStefano Zampini if(nnsp_has_cnst) { /* consider all vertices */ 1010da1bb401SStefano Zampini for(i=0;i<n_vertices;i++) { 1011da1bb401SStefano Zampini temp_indices_to_constraint[temp_indices[total_counts]]=is_indices[i]; 1012da1bb401SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]]=1.0; 1013da1bb401SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+1; 1014da1bb401SStefano Zampini vertices[total_counts]=is_indices[i]; 1015da1bb401SStefano Zampini total_counts++; 1016da1bb401SStefano Zampini } 1017da1bb401SStefano Zampini } else { /* consider vertices for which exist at least a localnearnullsp which is not null there */ 1018da1bb401SStefano Zampini for(i=0;i<n_vertices;i++) { 1019da1bb401SStefano Zampini used_vertex=PETSC_FALSE; 1020da1bb401SStefano Zampini k=0; 1021da1bb401SStefano Zampini while(!used_vertex && k<nnsp_size) { 1022da1bb401SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array_vector);CHKERRQ(ierr); 1023da1bb401SStefano Zampini if(PetscAbsScalar(array_vector[is_indices[i]])>0.0) { 1024da1bb401SStefano Zampini temp_indices_to_constraint[temp_indices[total_counts]]=is_indices[i]; 1025da1bb401SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]]=1.0; 1026da1bb401SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+1; 1027da1bb401SStefano Zampini vertices[total_counts]=is_indices[i]; 1028da1bb401SStefano Zampini total_counts++; 1029da1bb401SStefano Zampini used_vertex=PETSC_TRUE; 1030da1bb401SStefano Zampini } 1031da1bb401SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array_vector);CHKERRQ(ierr); 1032da1bb401SStefano Zampini k++; 1033da1bb401SStefano Zampini } 1034da1bb401SStefano Zampini } 1035da1bb401SStefano Zampini } 1036da1bb401SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1037da1bb401SStefano Zampini n_vertices=total_counts; 1038da1bb401SStefano Zampini /* edges and faces */ 10393b03a366Sstefano_zampini for(i=0;i<pcbddc->n_ISForEdges+pcbddc->n_ISForFaces;i++){ 10403b03a366Sstefano_zampini if(i<pcbddc->n_ISForEdges){ 10413b03a366Sstefano_zampini used_IS = &pcbddc->ISForEdges[i]; 10423b03a366Sstefano_zampini } else { 10433b03a366Sstefano_zampini used_IS = &pcbddc->ISForFaces[i-pcbddc->n_ISForEdges]; 10443b03a366Sstefano_zampini } 10453b03a366Sstefano_zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 10463b03a366Sstefano_zampini temp_start_ptr = total_counts; /* need to know the starting index of constraints stored */ 10473b03a366Sstefano_zampini ierr = ISGetSize(*used_IS,&size_of_constraint);CHKERRQ(ierr); 10483b03a366Sstefano_zampini ierr = ISGetIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 10493b03a366Sstefano_zampini if(nnsp_has_cnst) { 10503b03a366Sstefano_zampini temp_constraints++; 10513b03a366Sstefano_zampini quad_value = 1.0/PetscSqrtReal((PetscReal)size_of_constraint); 10523b03a366Sstefano_zampini for(j=0;j<size_of_constraint;j++) { 10533b03a366Sstefano_zampini temp_indices_to_constraint[temp_indices[total_counts]+j]=is_indices[j]; 10543b03a366Sstefano_zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=quad_value; 10553b03a366Sstefano_zampini } 10563b03a366Sstefano_zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 10573b03a366Sstefano_zampini total_counts++; 10583b03a366Sstefano_zampini } 10593b03a366Sstefano_zampini for(k=0;k<nnsp_size;k++) { 10603b03a366Sstefano_zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array_vector);CHKERRQ(ierr); 10613b03a366Sstefano_zampini for(j=0;j<size_of_constraint;j++) { 10623b03a366Sstefano_zampini temp_indices_to_constraint[temp_indices[total_counts]+j]=is_indices[j]; 10633b03a366Sstefano_zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=array_vector[is_indices[j]]; 10643b03a366Sstefano_zampini } 10653b03a366Sstefano_zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array_vector);CHKERRQ(ierr); 1066de534f79Sstefano_zampini quad_value = 1.0; 1067de534f79Sstefano_zampini if( use_nnsp_true ) { /* check if array is null on the connected component in case use_nnsp_true has been requested */ 1068de534f79Sstefano_zampini Bs = PetscBLASIntCast(size_of_constraint); 1069de534f79Sstefano_zampini quad_value = BLASasum_(&Bs,&temp_quadrature_constraint[temp_indices[total_counts]],&Bone); 1070de534f79Sstefano_zampini } 1071de534f79Sstefano_zampini if ( quad_value > 0.0 ) { /* keep indices and values */ 1072de534f79Sstefano_zampini temp_constraints++; 10733b03a366Sstefano_zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 10743b03a366Sstefano_zampini total_counts++; 10753b03a366Sstefano_zampini } 1076de534f79Sstefano_zampini } 10773b03a366Sstefano_zampini ierr = ISRestoreIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1078de534f79Sstefano_zampini /* perform SVD on the constraint if use_nnsp_true has not be requested by the user */ 10793b03a366Sstefano_zampini if(!use_nnsp_true) { 1080de534f79Sstefano_zampini 10813b03a366Sstefano_zampini Bs = PetscBLASIntCast(size_of_constraint); 10823b03a366Sstefano_zampini Bt = PetscBLASIntCast(temp_constraints); 1083de534f79Sstefano_zampini 10843b03a366Sstefano_zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 10853b03a366Sstefano_zampini ierr = PetscMemzero(correlation_mat,Bt*Bt*sizeof(PetscScalar));CHKERRQ(ierr); 10863b03a366Sstefano_zampini /* Store upper triangular part of correlation matrix */ 10873b03a366Sstefano_zampini for(j=0;j<temp_constraints;j++) { 10883b03a366Sstefano_zampini for(k=0;k<j+1;k++) { 10893b03a366Sstefano_zampini #if defined(PETSC_USE_COMPLEX) 10903b03a366Sstefano_zampini /* hand made complex dot product */ 10913b03a366Sstefano_zampini dot_result = 0.0; 10923b03a366Sstefano_zampini for (ii=0; ii<size_of_constraint; ii++) { 10933b03a366Sstefano_zampini val1 = temp_quadrature_constraint[temp_indices[temp_start_ptr+j]+ii]; 10943b03a366Sstefano_zampini val2 = temp_quadrature_constraint[temp_indices[temp_start_ptr+k]+ii]; 10953b03a366Sstefano_zampini dot_result += val1*PetscConj(val2); 10963b03a366Sstefano_zampini } 10973b03a366Sstefano_zampini #else 10983b03a366Sstefano_zampini dot_result = BLASdot_(&Bs,&temp_quadrature_constraint[temp_indices[temp_start_ptr+j]],&Bone, 10993b03a366Sstefano_zampini &temp_quadrature_constraint[temp_indices[temp_start_ptr+k]],&Bone); 11003b03a366Sstefano_zampini #endif 11013b03a366Sstefano_zampini correlation_mat[j*temp_constraints+k]=dot_result; 11023b03a366Sstefano_zampini } 11033b03a366Sstefano_zampini } 11043b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 11053b03a366Sstefano_zampini LAPACKsyev_("V","U",&Bt,correlation_mat,&Bt,singular_vals,work,&lwork,&lierr); 11063b03a366Sstefano_zampini #else 11073b03a366Sstefano_zampini LAPACKsyev_("V","U",&Bt,correlation_mat,&Bt,singular_vals,work,&lwork,rwork,&lierr); 11083b03a366Sstefano_zampini #endif 11093b03a366Sstefano_zampini if ( lierr ) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in EV Lapack routine %d",(int)lierr); 11103b03a366Sstefano_zampini /* retain eigenvalues greater than tol: note that lapack SYEV gives eigs in ascending order */ 11113b03a366Sstefano_zampini j=0; 11123b03a366Sstefano_zampini while( j < Bt && singular_vals[j] < tol) j++; 11133b03a366Sstefano_zampini total_counts=total_counts-j; 11143b03a366Sstefano_zampini if(j<temp_constraints) { 11153b03a366Sstefano_zampini for(k=j;k<Bt;k++) { singular_vals[k]=1.0/PetscSqrtReal(singular_vals[k]); } 11163b03a366Sstefano_zampini BLASgemm_("N","N",&Bs,&Bt,&Bt,&one,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Bs,correlation_mat,&Bt,&zero,temp_basis,&Bs); 11173b03a366Sstefano_zampini /* copy POD basis into used quadrature memory */ 11183b03a366Sstefano_zampini for(k=0;k<Bt-j;k++) { 11193b03a366Sstefano_zampini for(ii=0;ii<size_of_constraint;ii++) { 11203b03a366Sstefano_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]; 11213b03a366Sstefano_zampini } 11223b03a366Sstefano_zampini } 11233b03a366Sstefano_zampini } 1124de534f79Sstefano_zampini 11253b03a366Sstefano_zampini #else /* on missing GESVD */ 1126de534f79Sstefano_zampini 11273b03a366Sstefano_zampini PetscInt min_n = temp_constraints; 11283b03a366Sstefano_zampini if(min_n > size_of_constraint) min_n = size_of_constraint; 11293b03a366Sstefano_zampini dummy_int = Bs; 1130670f3ff9SJed Brown ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 11313b03a366Sstefano_zampini #if !defined(PETSC_USE_COMPLEX) 11323b03a366Sstefano_zampini LAPACKgesvd_("O","N",&Bs,&Bt,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Bs,singular_vals, 11333b03a366Sstefano_zampini &dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,work,&lwork,&lierr); 11343b03a366Sstefano_zampini #else 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,rwork,&lierr); 11373b03a366Sstefano_zampini #endif 11383b03a366Sstefano_zampini if ( lierr ) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SVD Lapack routine %d",(int)lierr); 1139670f3ff9SJed Brown ierr = PetscFPTrapPop();CHKERRQ(ierr); 11403b03a366Sstefano_zampini /* retain eigenvalues greater than tol: note that lapack SVD gives eigs in descending order */ 11413b03a366Sstefano_zampini j=0; 11423b03a366Sstefano_zampini while( j < min_n && singular_vals[min_n-j-1] < tol) j++; 11433b03a366Sstefano_zampini total_counts = total_counts-(PetscInt)Bt+(min_n-j); 1144de534f79Sstefano_zampini 11453b03a366Sstefano_zampini #endif 11463b03a366Sstefano_zampini } 11473b03a366Sstefano_zampini } 1148da1bb401SStefano Zampini n_constraints=total_counts-n_vertices; 1149da1bb401SStefano Zampini local_primal_size = total_counts; 11503b03a366Sstefano_zampini ierr = PetscMalloc(local_primal_size*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 11513b03a366Sstefano_zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 11523b03a366Sstefano_zampini ierr = MatSetType(pcbddc->ConstraintMatrix,impMatType);CHKERRQ(ierr); 11533b03a366Sstefano_zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,local_primal_size,pcis->n,local_primal_size,pcis->n);CHKERRQ(ierr); 1154da1bb401SStefano Zampini for(i=0;i<local_primal_size;i++) { 1155da1bb401SStefano Zampini nnz[i]=temp_indices[i+1]-temp_indices[i]; 1156da1bb401SStefano Zampini } 11573b03a366Sstefano_zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 1158da1bb401SStefano Zampini for(i=0;i<local_primal_size;i++) { 11593b03a366Sstefano_zampini size_of_constraint=temp_indices[i+1]-temp_indices[i]; 1160da1bb401SStefano 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); 11613b03a366Sstefano_zampini } 11623b03a366Sstefano_zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11633b03a366Sstefano_zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11643b03a366Sstefano_zampini /* set quantities in pcbddc data structure */ 11653b03a366Sstefano_zampini pcbddc->n_vertices = n_vertices; 11663b03a366Sstefano_zampini pcbddc->n_constraints = n_constraints; 1167da1bb401SStefano Zampini pcbddc->local_primal_size = local_primal_size; 11683b03a366Sstefano_zampini /* free workspace no longer needed */ 11693b03a366Sstefano_zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 11703b03a366Sstefano_zampini ierr = PetscFree(work);CHKERRQ(ierr); 11713b03a366Sstefano_zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 11723b03a366Sstefano_zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 11733b03a366Sstefano_zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 11743b03a366Sstefano_zampini ierr = PetscFree(temp_indices);CHKERRQ(ierr); 11753b03a366Sstefano_zampini ierr = PetscFree(temp_indices_to_constraint);CHKERRQ(ierr); 11763b03a366Sstefano_zampini ierr = PetscFree(temp_quadrature_constraint);CHKERRQ(ierr); 11773b03a366Sstefano_zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 1178da1bb401SStefano Zampini for(k=0;k<nnsp_size;k++) { 1179da1bb401SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 1180da1bb401SStefano Zampini } 11813b03a366Sstefano_zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 11823b03a366Sstefano_zampini PetscFunctionReturn(0); 11833b03a366Sstefano_zampini } 1184de534f79Sstefano_zampini #ifdef UNDEF_PETSC_MISSING_LAPACK_GESVD 11853b03a366Sstefano_zampini #undef PETSC_MISSING_LAPACK_GESVD 11863b03a366Sstefano_zampini #endif 11873b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 11880c7d97c5SJed Brown #undef __FUNCT__ 11890c7d97c5SJed Brown #define __FUNCT__ "PCBDDCCoarseSetUp" 119053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC pc) 11910c7d97c5SJed Brown { 11920c7d97c5SJed Brown PetscErrorCode ierr; 11930c7d97c5SJed Brown 11940c7d97c5SJed Brown PC_IS* pcis = (PC_IS*)(pc->data); 11950c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 11960c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 11970c7d97c5SJed Brown IS is_R_local; 11980c7d97c5SJed Brown IS is_V_local; 11990c7d97c5SJed Brown IS is_C_local; 12000c7d97c5SJed Brown IS is_aux1; 12010c7d97c5SJed Brown IS is_aux2; 12020c7d97c5SJed Brown const VecType impVecType; 12030c7d97c5SJed Brown const MatType impMatType; 12040c7d97c5SJed Brown PetscInt n_R=0; 12050c7d97c5SJed Brown PetscInt n_D=0; 12060c7d97c5SJed Brown PetscInt n_B=0; 12070c7d97c5SJed Brown PetscScalar zero=0.0; 12080c7d97c5SJed Brown PetscScalar one=1.0; 12090c7d97c5SJed Brown PetscScalar m_one=-1.0; 12100c7d97c5SJed Brown PetscScalar* array; 12110c7d97c5SJed Brown PetscScalar *coarse_submat_vals; 12120c7d97c5SJed Brown PetscInt *idx_R_local; 12130c7d97c5SJed Brown PetscInt *idx_V_B; 12140c7d97c5SJed Brown PetscScalar *coarsefunctions_errors; 12150c7d97c5SJed Brown PetscScalar *constraints_errors; 12160c7d97c5SJed Brown /* auxiliary indices */ 1217da1bb401SStefano Zampini PetscInt i,j; 1218e269702eSStefano Zampini /* for verbose output of bddc */ 1219e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 1220e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 1221a0ba757dSStefano Zampini /* for counting coarse dofs */ 12223b03a366Sstefano_zampini PetscInt n_vertices=pcbddc->n_vertices,n_constraints=pcbddc->n_constraints; 12233b03a366Sstefano_zampini PetscInt size_of_constraint; 12243b03a366Sstefano_zampini PetscInt *row_cmat_indices; 12253b03a366Sstefano_zampini PetscScalar *row_cmat_values; 1226da1bb401SStefano Zampini PetscInt *vertices; 12270c7d97c5SJed Brown 12280c7d97c5SJed Brown PetscFunctionBegin; 12290c7d97c5SJed Brown /* Set Non-overlapping dimensions */ 12300c7d97c5SJed Brown n_B = pcis->n_B; n_D = pcis->n - n_B; 12313b03a366Sstefano_zampini 1232da1bb401SStefano Zampini /* get vertex indices from constraint matrix */ 1233da1bb401SStefano Zampini ierr = PetscMalloc(pcbddc->n_vertices*sizeof(PetscInt),&vertices);CHKERRQ(ierr); 1234da1bb401SStefano Zampini j=0; 1235da1bb401SStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) { 1236da1bb401SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 1237da1bb401SStefano Zampini if(size_of_constraint == 1) { 1238da1bb401SStefano Zampini vertices[j]=row_cmat_indices[0]; 1239da1bb401SStefano Zampini j++; 1240a0ba757dSStefano Zampini } 1241da1bb401SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 1242a0ba757dSStefano Zampini } 1243a0ba757dSStefano Zampini 12440c7d97c5SJed Brown /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 12450c7d97c5SJed Brown ierr = VecSet(pcis->vec1_N,one);CHKERRQ(ierr); 12460c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 12473b03a366Sstefano_zampini for (i=0;i<n_vertices;i++) { array[ vertices[i] ] = zero; } 12483b03a366Sstefano_zampini ierr = PetscMalloc(( pcis->n - n_vertices )*sizeof(PetscInt),&idx_R_local);CHKERRQ(ierr); 12490c7d97c5SJed Brown for (i=0, n_R=0; i<pcis->n; i++) { if (array[i] == one) { idx_R_local[n_R] = i; n_R++; } } 12500c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1251e269702eSStefano Zampini if(dbg_flag) { 12520c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 12530c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 12540c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 12550c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 12563b03a366Sstefano_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); 12570c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 12580c7d97c5SJed Brown } 12590c7d97c5SJed Brown /* Allocate needed vectors */ 12600c7d97c5SJed Brown /* Set Mat type for local matrices needed by BDDC precondtioner */ 12610c7d97c5SJed Brown impMatType = MATSEQDENSE; 12620c7d97c5SJed Brown impVecType = VECSEQ; 12630c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_D,&pcbddc->vec4_D);CHKERRQ(ierr); 12640c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_R);CHKERRQ(ierr); 12650c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_R,n_R,n_R);CHKERRQ(ierr); 12660c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 1267d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 12680c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_P);CHKERRQ(ierr); 12690c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_P,pcbddc->local_primal_size,pcbddc->local_primal_size);CHKERRQ(ierr); 12700c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 12710c7d97c5SJed Brown 12720c7d97c5SJed Brown /* Creating some index sets needed */ 12730c7d97c5SJed Brown /* For submatrices */ 1274da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n_R,idx_R_local,PETSC_OWN_POINTER,&is_R_local);CHKERRQ(ierr); 12753b03a366Sstefano_zampini if(n_vertices) { 1276da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n_vertices,vertices,PETSC_OWN_POINTER,&is_V_local);CHKERRQ(ierr); 12773b03a366Sstefano_zampini } 1278da1bb401SStefano Zampini if(n_constraints) { 1279da1bb401SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_C_local);CHKERRQ(ierr); 1280da1bb401SStefano Zampini } 1281da1bb401SStefano Zampini 12820c7d97c5SJed Brown /* For VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 12830c7d97c5SJed Brown { 12840c7d97c5SJed Brown PetscInt *aux_array1; 12850c7d97c5SJed Brown PetscInt *aux_array2; 12860c7d97c5SJed Brown 12873b03a366Sstefano_zampini ierr = PetscMalloc( (pcis->n_B-n_vertices)*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 12883b03a366Sstefano_zampini ierr = PetscMalloc( (pcis->n_B-n_vertices)*sizeof(PetscInt),&aux_array2);CHKERRQ(ierr); 12890c7d97c5SJed Brown 1290d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 12910c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 12920c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 12930c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12940c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12950c7d97c5SJed Brown ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12960c7d97c5SJed Brown ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12970c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1298da1bb401SStefano Zampini for (i=0, j=0; i<n_R; i++) { if (array[idx_R_local[i]] > one) { aux_array1[j] = i; j++; } } 12990c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1300da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 13010c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1302da1bb401SStefano Zampini for (i=0, j=0; i<n_B; i++) { if (array[i] > one) { aux_array2[j] = i; j++; } } 13033828260eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1304da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_COPY_VALUES,&is_aux2);CHKERRQ(ierr); 13050c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 13060c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 13070c7d97c5SJed Brown ierr = PetscFree(aux_array2);CHKERRQ(ierr); 13080c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 13090c7d97c5SJed Brown ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 13100c7d97c5SJed Brown 1311e269702eSStefano Zampini if(pcbddc->prec_type || dbg_flag ) { 13120c7d97c5SJed Brown ierr = PetscMalloc(n_D*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 13130c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1314da1bb401SStefano Zampini for (i=0, j=0; i<n_R; i++) { if (array[idx_R_local[i]] == one) { aux_array1[j] = i; j++; } } 13150c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1316da1bb401SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 13170c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 13180c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 13190c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 13200c7d97c5SJed Brown } 13210c7d97c5SJed Brown } 13220c7d97c5SJed Brown 13230c7d97c5SJed Brown /* vertices in boundary numbering */ 13243b03a366Sstefano_zampini if(n_vertices) { 1325d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,m_one);CHKERRQ(ierr); 13260c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 13273b03a366Sstefano_zampini for (i=0; i<n_vertices; i++) { array[ vertices[i] ] = i; } 13280c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1329d49ef151SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1330d49ef151SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13313b03a366Sstefano_zampini ierr = PetscMalloc(n_vertices*sizeof(PetscInt),&idx_V_B);CHKERRQ(ierr); 13320c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 13333b03a366Sstefano_zampini for (i=0; i<n_vertices; i++) { 1334da1bb401SStefano Zampini j=0; 1335da1bb401SStefano Zampini while (array[j] != i ) {j++;} 1336da1bb401SStefano Zampini idx_V_B[i]=j; 13370c7d97c5SJed Brown } 13380c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 13390c7d97c5SJed Brown } 13400c7d97c5SJed Brown 13410c7d97c5SJed Brown /* Creating PC contexts for local Dirichlet and Neumann problems */ 13420c7d97c5SJed Brown { 13430c7d97c5SJed Brown Mat A_RR; 134453cdbc3dSStefano Zampini PC pc_temp; 13450c7d97c5SJed Brown /* Matrix for Dirichlet problem is A_II -> we already have it from pcis.c code */ 134653cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 134753cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 134853cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II,SAME_PRECONDITIONER);CHKERRQ(ierr); 134953cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 1350da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,"dirichlet_");CHKERRQ(ierr); 13510c7d97c5SJed Brown /* default */ 135253cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 135353cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 13540c7d97c5SJed Brown /* Allow user's customization */ 135553cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 135653cdbc3dSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 135753cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 1358da1bb401SStefano Zampini if(pcbddc->dbg_flag) ierr = KSPView(pcbddc->ksp_D,PETSC_VIEWER_STDOUT_SELF); 13590c7d97c5SJed Brown /* Matrix for Neumann problem is A_RR -> we need to create it */ 13600c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_R_local,is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 136153cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 136253cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 136353cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR,SAME_PRECONDITIONER);CHKERRQ(ierr); 136453cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 1365da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,"neumann_");CHKERRQ(ierr); 13660c7d97c5SJed Brown /* default */ 136753cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 136853cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 13690c7d97c5SJed Brown /* Allow user's customization */ 137053cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 137153cdbc3dSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 137253cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 1373da1bb401SStefano Zampini if(pcbddc->dbg_flag) ierr = KSPView(pcbddc->ksp_R,PETSC_VIEWER_STDOUT_SELF); 1374a0ba757dSStefano Zampini /* check Dirichlet and Neumann solvers */ 1375e269702eSStefano Zampini if(pcbddc->dbg_flag) { 13760c7d97c5SJed Brown Vec temp_vec; 13770c7d97c5SJed Brown PetscScalar value; 13780c7d97c5SJed Brown 1379a0ba757dSStefano Zampini ierr = VecDuplicate(pcis->vec1_D,&temp_vec);CHKERRQ(ierr); 1380a0ba757dSStefano Zampini ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL);CHKERRQ(ierr); 1381a0ba757dSStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 1382a0ba757dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,temp_vec);CHKERRQ(ierr); 1383a0ba757dSStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcis->vec1_D);CHKERRQ(ierr); 1384a0ba757dSStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 1385a0ba757dSStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1386a0ba757dSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1387a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1388a0ba757dSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Checking solution of Dirichlet and Neumann problems\n");CHKERRQ(ierr); 1389a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Dirichlet solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 1390d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&temp_vec);CHKERRQ(ierr); 1391d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 1392d49ef151SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 1393d49ef151SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,temp_vec);CHKERRQ(ierr); 1394d49ef151SStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 1395d49ef151SStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 1396e269702eSStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 13970c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Neumann solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 1398d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 13990c7d97c5SJed Brown } 14000c7d97c5SJed Brown /* free Neumann problem's matrix */ 14010c7d97c5SJed Brown ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 14020c7d97c5SJed Brown } 14030c7d97c5SJed Brown 14040c7d97c5SJed Brown /* Assemble all remaining stuff needed to apply BDDC */ 14050c7d97c5SJed Brown { 14060c7d97c5SJed Brown Mat A_RV,A_VR,A_VV; 14070c7d97c5SJed Brown Mat M1,M2; 14080c7d97c5SJed Brown Mat C_CR; 14093b03a366Sstefano_zampini Mat AUXMAT; 14100c7d97c5SJed Brown Vec vec1_C; 14110c7d97c5SJed Brown Vec vec2_C; 14120c7d97c5SJed Brown Vec vec1_V; 14130c7d97c5SJed Brown Vec vec2_V; 14140c7d97c5SJed Brown PetscInt *nnz; 14150c7d97c5SJed Brown PetscInt *auxindices; 141653cdbc3dSStefano Zampini PetscInt index; 14170c7d97c5SJed Brown PetscScalar* array2; 14180c7d97c5SJed Brown MatFactorInfo matinfo; 14190c7d97c5SJed Brown 14200c7d97c5SJed Brown /* Allocating some extra storage just to be safe */ 14210c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 14220c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&auxindices);CHKERRQ(ierr); 14230c7d97c5SJed Brown for(i=0;i<pcis->n;i++) {auxindices[i]=i;} 14240c7d97c5SJed Brown 14250c7d97c5SJed Brown /* some work vectors on vertices and/or constraints */ 14263b03a366Sstefano_zampini if(n_vertices) { 14270c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_V);CHKERRQ(ierr); 14283b03a366Sstefano_zampini ierr = VecSetSizes(vec1_V,n_vertices,n_vertices);CHKERRQ(ierr); 14290c7d97c5SJed Brown ierr = VecSetType(vec1_V,impVecType);CHKERRQ(ierr); 14300c7d97c5SJed Brown ierr = VecDuplicate(vec1_V,&vec2_V);CHKERRQ(ierr); 14310c7d97c5SJed Brown } 14320c7d97c5SJed Brown if(pcbddc->n_constraints) { 14330c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_C);CHKERRQ(ierr); 14340c7d97c5SJed Brown ierr = VecSetSizes(vec1_C,pcbddc->n_constraints,pcbddc->n_constraints);CHKERRQ(ierr); 14350c7d97c5SJed Brown ierr = VecSetType(vec1_C,impVecType);CHKERRQ(ierr); 14360c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&vec2_C);CHKERRQ(ierr); 14370c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&pcbddc->vec1_C);CHKERRQ(ierr); 14380c7d97c5SJed Brown } 14390c7d97c5SJed Brown /* Precompute stuffs needed for preprocessing and application of BDDC*/ 14403b03a366Sstefano_zampini if(n_constraints) { 14410c7d97c5SJed Brown /* some work vectors */ 14420c7d97c5SJed Brown ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->local_auxmat2);CHKERRQ(ierr); 14433b03a366Sstefano_zampini ierr = MatSetSizes(pcbddc->local_auxmat2,n_R,n_constraints,n_R,n_constraints);CHKERRQ(ierr); 14440c7d97c5SJed Brown ierr = MatSetType(pcbddc->local_auxmat2,impMatType);CHKERRQ(ierr); 14453b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(pcbddc->local_auxmat2,PETSC_NULL);CHKERRQ(ierr); 14460c7d97c5SJed Brown 14470c7d97c5SJed Brown /* Assemble local_auxmat2 = - A_{RR}^{-1} C^T_{CR} needed by BDDC application */ 14483b03a366Sstefano_zampini for(i=0;i<n_constraints;i++) { 1449d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 14503b03a366Sstefano_zampini ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 14513b03a366Sstefano_zampini /* Get row of constraint matrix in R numbering */ 14520c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14533b03a366Sstefano_zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,n_vertices+i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 14543b03a366Sstefano_zampini for(j=0;j<size_of_constraint;j++) { array[ row_cmat_indices[j] ] = - row_cmat_values[j]; } 14553b03a366Sstefano_zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,n_vertices+i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,(const PetscScalar**)&row_cmat_values);CHKERRQ(ierr); 14560c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 14570c7d97c5SJed Brown for(j=0;j<n_R;j++) { array2[j] = array[ idx_R_local[j] ]; } 14580c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 14590c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 14603b03a366Sstefano_zampini /* Solve for row of constraint matrix in R numbering */ 146153cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 14623b03a366Sstefano_zampini /* Set values */ 14630c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 14643b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->local_auxmat2,n_R,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 14650c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 14660c7d97c5SJed Brown } 14670c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14680c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14690c7d97c5SJed Brown 14700c7d97c5SJed Brown /* Create Constraint matrix on R nodes: C_{CR} */ 14713b03a366Sstefano_zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_C_local,is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 14720c7d97c5SJed Brown ierr = ISDestroy(&is_C_local);CHKERRQ(ierr); 14730c7d97c5SJed Brown 14740c7d97c5SJed Brown /* Assemble AUXMAT = ( LUFactor )( -C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 14750c7d97c5SJed Brown ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AUXMAT);CHKERRQ(ierr); 1476d49ef151SStefano Zampini ierr = MatFactorInfoInitialize(&matinfo);CHKERRQ(ierr); 14773b03a366Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,0,1,&is_aux1);CHKERRQ(ierr); 14780c7d97c5SJed Brown ierr = MatLUFactor(AUXMAT,is_aux1,is_aux1,&matinfo);CHKERRQ(ierr); 14790c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 14800c7d97c5SJed Brown 14813b03a366Sstefano_zampini /* Assemble explicitly M1 = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} needed in preproc */ 1482d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M1);CHKERRQ(ierr); 14833b03a366Sstefano_zampini ierr = MatSetSizes(M1,n_constraints,n_constraints,n_constraints,n_constraints);CHKERRQ(ierr); 14840c7d97c5SJed Brown ierr = MatSetType(M1,impMatType);CHKERRQ(ierr); 14853b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(M1,PETSC_NULL);CHKERRQ(ierr); 14863b03a366Sstefano_zampini for(i=0;i<n_constraints;i++) { 14870c7d97c5SJed Brown ierr = VecSet(vec1_C,zero);CHKERRQ(ierr); 14880c7d97c5SJed Brown ierr = VecSetValue(vec1_C,i,one,INSERT_VALUES);CHKERRQ(ierr); 14890c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_C);CHKERRQ(ierr); 14900c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_C);CHKERRQ(ierr); 14910c7d97c5SJed Brown ierr = MatSolve(AUXMAT,vec1_C,vec2_C);CHKERRQ(ierr); 14920c7d97c5SJed Brown ierr = VecScale(vec2_C,m_one);CHKERRQ(ierr); 14930c7d97c5SJed Brown ierr = VecGetArray(vec2_C,&array);CHKERRQ(ierr); 14943b03a366Sstefano_zampini ierr = MatSetValues(M1,n_constraints,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 14950c7d97c5SJed Brown ierr = VecRestoreArray(vec2_C,&array);CHKERRQ(ierr); 14960c7d97c5SJed Brown } 14970c7d97c5SJed Brown ierr = MatAssemblyBegin(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14980c7d97c5SJed Brown ierr = MatAssemblyEnd(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14990c7d97c5SJed Brown ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 15000c7d97c5SJed Brown /* Assemble local_auxmat1 = M1*C_{CR} needed by BDDC application in KSP and in preproc */ 15010c7d97c5SJed Brown ierr = MatMatMult(M1,C_CR,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 15020c7d97c5SJed Brown 15030c7d97c5SJed Brown } 15040c7d97c5SJed Brown 15050c7d97c5SJed Brown /* Get submatrices from subdomain matrix */ 15063b03a366Sstefano_zampini if(n_vertices){ 15070c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_R_local,is_V_local,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 15080c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_V_local,is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 15090c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_V_local,is_V_local,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 15100c7d97c5SJed Brown /* Assemble M2 = A_RR^{-1}A_RV */ 1511d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M2);CHKERRQ(ierr); 15123b03a366Sstefano_zampini ierr = MatSetSizes(M2,n_R,n_vertices,n_R,n_vertices);CHKERRQ(ierr); 15130c7d97c5SJed Brown ierr = MatSetType(M2,impMatType);CHKERRQ(ierr); 15143b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(M2,PETSC_NULL);CHKERRQ(ierr); 15153b03a366Sstefano_zampini for(i=0;i<n_vertices;i++) { 15160c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 15170c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 15180c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 15190c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 15200c7d97c5SJed Brown ierr = MatMult(A_RV,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 152153cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 15220c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 15233b03a366Sstefano_zampini ierr = MatSetValues(M2,n_R,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 15240c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 15250c7d97c5SJed Brown } 15260c7d97c5SJed Brown ierr = MatAssemblyBegin(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 15270c7d97c5SJed Brown ierr = MatAssemblyEnd(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 15280c7d97c5SJed Brown } 15290c7d97c5SJed Brown 15300c7d97c5SJed Brown /* Matrix of coarse basis functions (local) */ 1531d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 15320c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 15330c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_B,impMatType);CHKERRQ(ierr); 15343b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_phi_B,PETSC_NULL);CHKERRQ(ierr); 1535e269702eSStefano Zampini if(pcbddc->prec_type || dbg_flag ) { 1536d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 15370c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 15380c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_D,impMatType);CHKERRQ(ierr); 15393b03a366Sstefano_zampini ierr = MatSeqDenseSetPreallocation(pcbddc->coarse_phi_D,PETSC_NULL);CHKERRQ(ierr); 15400c7d97c5SJed Brown } 15410c7d97c5SJed Brown 1542e269702eSStefano Zampini if(dbg_flag) { 15430c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&coarsefunctions_errors);CHKERRQ(ierr); 15440c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&constraints_errors);CHKERRQ(ierr); 15450c7d97c5SJed Brown } 15463b03a366Sstefano_zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 15470c7d97c5SJed Brown ierr = PetscMalloc ((pcbddc->local_primal_size)*(pcbddc->local_primal_size)*sizeof(PetscScalar),&coarse_submat_vals);CHKERRQ(ierr); 15480c7d97c5SJed Brown 15490c7d97c5SJed Brown /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 15503b03a366Sstefano_zampini for(i=0;i<n_vertices;i++){ 15510c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 15520c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 15530c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 15540c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 15550c7d97c5SJed Brown /* solution of saddle point problem */ 15560c7d97c5SJed Brown ierr = MatMult(M2,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 15570c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_R,m_one);CHKERRQ(ierr); 15583b03a366Sstefano_zampini if(n_constraints) { 15590c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec1_R,vec1_C);CHKERRQ(ierr); 15600c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 15610c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 15620c7d97c5SJed Brown } 15630c7d97c5SJed Brown ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); 15640c7d97c5SJed Brown ierr = MatMultAdd(A_VV,vec1_V,vec2_V,vec2_V);CHKERRQ(ierr); 15650c7d97c5SJed Brown 15660c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 15670c7d97c5SJed Brown /* coarse basis functions */ 15680c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 15690c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15700c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15710c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 15723b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 15730c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 15740c7d97c5SJed Brown ierr = MatSetValue(pcbddc->coarse_phi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 1575e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 15760c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15770c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15780c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 15793b03a366Sstefano_zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 15800c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 15810c7d97c5SJed Brown } 15820c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 15830c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 1584da1bb401SStefano Zampini for(j=0;j<n_vertices;j++) { coarse_submat_vals[i*pcbddc->local_primal_size+j] = array[j]; } /* WARNING -> column major ordering */ 15850c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 15863b03a366Sstefano_zampini if(n_constraints) { 15870c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 1588da1bb401SStefano 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 */ 15890c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 15900c7d97c5SJed Brown } 15910c7d97c5SJed Brown 1592e269702eSStefano Zampini if( dbg_flag ) { 15930c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 1594d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 15950c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 15960c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 15970c7d97c5SJed Brown for(j=0;j<n_R;j++) { array[idx_R_local[j]] = array2[j]; } 15983b03a366Sstefano_zampini array[ vertices[i] ] = one; 15990c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 16000c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 16010c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers (i.e. primal nodes) */ 1602d49ef151SStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 16030c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 16040c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 16053b03a366Sstefano_zampini for(j=0;j<n_vertices;j++) { array2[j]=array[j]; } 16060c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 16073b03a366Sstefano_zampini if(n_constraints) { 16080c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 16093b03a366Sstefano_zampini for(j=0;j<n_constraints;j++) { array2[j+n_vertices]=array[j]; } 16100c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 16110c7d97c5SJed Brown } 16120c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 16130c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_P,m_one);CHKERRQ(ierr); 16140c7d97c5SJed Brown /* check saddle point solution */ 16150c7d97c5SJed Brown ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 16163b03a366Sstefano_zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 16173b03a366Sstefano_zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[i]);CHKERRQ(ierr); 16183b03a366Sstefano_zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 16190c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 16203b03a366Sstefano_zampini array[i]=array[i]+m_one; /* shift by the identity matrix */ 16210c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 16223b03a366Sstefano_zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[i]);CHKERRQ(ierr); 16230c7d97c5SJed Brown } 16240c7d97c5SJed Brown } 16250c7d97c5SJed Brown 16263b03a366Sstefano_zampini for(i=0;i<n_constraints;i++){ 1627d49ef151SStefano Zampini ierr = VecSet(vec2_C,zero);CHKERRQ(ierr); 16280c7d97c5SJed Brown ierr = VecSetValue(vec2_C,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 16290c7d97c5SJed Brown ierr = VecAssemblyBegin(vec2_C);CHKERRQ(ierr); 16300c7d97c5SJed Brown ierr = VecAssemblyEnd(vec2_C);CHKERRQ(ierr); 16310c7d97c5SJed Brown /* solution of saddle point problem */ 16320c7d97c5SJed Brown ierr = MatMult(M1,vec2_C,vec1_C);CHKERRQ(ierr); 16330c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 16340c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 16353b03a366Sstefano_zampini if(n_vertices) { ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); } 16360c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 16370c7d97c5SJed Brown /* coarse basis functions */ 16383b03a366Sstefano_zampini index=i+n_vertices; 16390c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 16400c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16410c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16420c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 164353cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 16440c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1645e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 16460c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16470c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16480c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 164953cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 16500c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 16510c7d97c5SJed Brown } 16520c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 16533b03a366Sstefano_zampini if(n_vertices) { 16540c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 1655da1bb401SStefano Zampini for(j=0;j<n_vertices;j++) {coarse_submat_vals[index*pcbddc->local_primal_size+j]=array[j];} /* WARNING -> column major ordering */ 16560c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 16570c7d97c5SJed Brown } 16580c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 1659da1bb401SStefano 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 */ 16600c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 16610c7d97c5SJed Brown 1662e269702eSStefano Zampini if( dbg_flag ) { 16630c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 166453cdbc3dSStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 16650c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 16660c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 16670c7d97c5SJed Brown for(j=0;j<n_R;j++){ array[ idx_R_local[j] ] = array2[j]; } 16680c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 16690c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 16700c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers */ 167153cdbc3dSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 16720c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 16733b03a366Sstefano_zampini if( n_vertices) { 16740c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 16753b03a366Sstefano_zampini for(j=0;j<n_vertices;j++) {array2[j]=-array[j];} 16760c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 16770c7d97c5SJed Brown } 16780c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 16793b03a366Sstefano_zampini for(j=0;j<n_constraints;j++) {array2[j+n_vertices]=-array[j];} 16800c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 16810c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 16820c7d97c5SJed Brown /* check saddle point solution */ 16830c7d97c5SJed Brown ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 16843b03a366Sstefano_zampini ierr = MatMultTransposeAdd(pcbddc->ConstraintMatrix,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 168553cdbc3dSStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[index]);CHKERRQ(ierr); 16863b03a366Sstefano_zampini ierr = MatMult(pcbddc->ConstraintMatrix,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 16870c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 168853cdbc3dSStefano Zampini array[index]=array[index]+m_one; /* shift by the identity matrix */ 16890c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 169053cdbc3dSStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[index]);CHKERRQ(ierr); 16910c7d97c5SJed Brown } 16920c7d97c5SJed Brown } 16930c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16940c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1695e269702eSStefano Zampini if( pcbddc->prec_type || dbg_flag ) { 16960c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16970c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16980c7d97c5SJed Brown } 16990c7d97c5SJed Brown /* Checking coarse_sub_mat and coarse basis functios */ 17000c7d97c5SJed Brown /* It shuld be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 17019d2fce94SStefano Zampini if(dbg_flag) { 17020c7d97c5SJed Brown 17030c7d97c5SJed Brown Mat coarse_sub_mat; 17040c7d97c5SJed Brown Mat TM1,TM2,TM3,TM4; 17050c7d97c5SJed Brown Mat coarse_phi_D,coarse_phi_B,A_II,A_BB,A_IB,A_BI; 1706a0ba757dSStefano Zampini const MatType checkmattype=MATSEQAIJ; 17070c7d97c5SJed Brown PetscScalar value; 17080c7d97c5SJed Brown 1709c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 1710c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 1711c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 1712c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 1713c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 1714c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 1715c042a7c3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 1716c042a7c3SStefano Zampini ierr = MatConvert(coarse_sub_mat,checkmattype,MAT_REUSE_MATRIX,&coarse_sub_mat);CHKERRQ(ierr); 17170c7d97c5SJed Brown 1718da1bb401SStefano Zampini /*PetscViewer view_out; 1719da1bb401SStefano Zampini PetscMPIInt myrank; 1720da1bb401SStefano Zampini char filename[256]; 1721da1bb401SStefano Zampini MPI_Comm_rank(((PetscObject)pc)->comm,&myrank); 1722da1bb401SStefano Zampini sprintf(filename,"coarsesubmat_%04d.m",myrank); 1723da1bb401SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&view_out);CHKERRQ(ierr); 1724da1bb401SStefano Zampini ierr = PetscViewerSetFormat(view_out,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1725da1bb401SStefano Zampini ierr = MatView(coarse_sub_mat,view_out);CHKERRQ(ierr); 1726da1bb401SStefano Zampini ierr = PetscViewerDestroy(&view_out);CHKERRQ(ierr);*/ 1727da1bb401SStefano Zampini 17280c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 17290c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Check coarse sub mat and local basis functions\n");CHKERRQ(ierr); 17300c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 173153cdbc3dSStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 173253cdbc3dSStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 173353cdbc3dSStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1734c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 173553cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 173653cdbc3dSStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1737c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 173853cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 173953cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 174053cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 174153cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 174253cdbc3dSStefano Zampini ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 174353cdbc3dSStefano Zampini ierr = MatNorm(TM1,NORM_INFINITY,&value);CHKERRQ(ierr); 17440c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"----------------------------------\n");CHKERRQ(ierr); 17450c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d \n",PetscGlobalRank);CHKERRQ(ierr); 17460c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"matrix error = % 1.14e\n",value);CHKERRQ(ierr); 17470c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"coarse functions errors\n");CHKERRQ(ierr); 174853cdbc3dSStefano 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); } 17490c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"constraints errors\n");CHKERRQ(ierr); 175053cdbc3dSStefano 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); } 17510c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 175253cdbc3dSStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 175353cdbc3dSStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 175453cdbc3dSStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 175553cdbc3dSStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 175653cdbc3dSStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 175753cdbc3dSStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 175853cdbc3dSStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 175953cdbc3dSStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 176053cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 176153cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 176253cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 17630c7d97c5SJed Brown ierr = PetscFree(coarsefunctions_errors);CHKERRQ(ierr); 17640c7d97c5SJed Brown ierr = PetscFree(constraints_errors);CHKERRQ(ierr); 17650c7d97c5SJed Brown } 17660c7d97c5SJed Brown 17670c7d97c5SJed Brown /* create coarse matrix and data structures for message passing associated actual choice of coarse problem type */ 17680c7d97c5SJed Brown ierr = PCBDDCSetupCoarseEnvironment(pc,coarse_submat_vals);CHKERRQ(ierr); 17690c7d97c5SJed Brown /* free memory */ 17700c7d97c5SJed Brown ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 17710c7d97c5SJed Brown ierr = PetscFree(auxindices);CHKERRQ(ierr); 17720c7d97c5SJed Brown ierr = PetscFree(nnz);CHKERRQ(ierr); 17733b03a366Sstefano_zampini if(n_vertices) { 17740c7d97c5SJed Brown ierr = VecDestroy(&vec1_V);CHKERRQ(ierr); 17750c7d97c5SJed Brown ierr = VecDestroy(&vec2_V);CHKERRQ(ierr); 17760c7d97c5SJed Brown ierr = MatDestroy(&M2);CHKERRQ(ierr); 17770c7d97c5SJed Brown ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 17780c7d97c5SJed Brown ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 17790c7d97c5SJed Brown ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 17800c7d97c5SJed Brown } 17810c7d97c5SJed Brown if(pcbddc->n_constraints) { 17820c7d97c5SJed Brown ierr = VecDestroy(&vec1_C);CHKERRQ(ierr); 17830c7d97c5SJed Brown ierr = VecDestroy(&vec2_C);CHKERRQ(ierr); 17840c7d97c5SJed Brown ierr = MatDestroy(&M1);CHKERRQ(ierr); 17850c7d97c5SJed Brown ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 17860c7d97c5SJed Brown } 17870c7d97c5SJed Brown } 17880c7d97c5SJed Brown /* free memory */ 17893b03a366Sstefano_zampini if(n_vertices) { 17900c7d97c5SJed Brown ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 17910c7d97c5SJed Brown ierr = ISDestroy(&is_V_local);CHKERRQ(ierr); 17920c7d97c5SJed Brown } 17930c7d97c5SJed Brown ierr = ISDestroy(&is_R_local);CHKERRQ(ierr); 17940c7d97c5SJed Brown 17950c7d97c5SJed Brown PetscFunctionReturn(0); 17960c7d97c5SJed Brown } 17970c7d97c5SJed Brown 17980c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 17990c7d97c5SJed Brown 18000c7d97c5SJed Brown #undef __FUNCT__ 18010c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetupCoarseEnvironment" 180253cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetupCoarseEnvironment(PC pc,PetscScalar* coarse_submat_vals) 18030c7d97c5SJed Brown { 18040c7d97c5SJed Brown 18050c7d97c5SJed Brown 18060c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 18070c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 18080c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 18090c7d97c5SJed Brown MPI_Comm prec_comm = ((PetscObject)pc)->comm; 18100c7d97c5SJed Brown MPI_Comm coarse_comm; 18110c7d97c5SJed Brown 18120c7d97c5SJed Brown /* common to all choiches */ 18130c7d97c5SJed Brown PetscScalar *temp_coarse_mat_vals; 18140c7d97c5SJed Brown PetscScalar *ins_coarse_mat_vals; 18150c7d97c5SJed Brown PetscInt *ins_local_primal_indices; 18160c7d97c5SJed Brown PetscMPIInt *localsizes2,*localdispl2; 18170c7d97c5SJed Brown PetscMPIInt size_prec_comm; 18180c7d97c5SJed Brown PetscMPIInt rank_prec_comm; 18190c7d97c5SJed Brown PetscMPIInt active_rank=MPI_PROC_NULL; 18200c7d97c5SJed Brown PetscMPIInt master_proc=0; 18210c7d97c5SJed Brown PetscInt ins_local_primal_size; 18220c7d97c5SJed Brown /* specific to MULTILEVEL_BDDC */ 18230c7d97c5SJed Brown PetscMPIInt *ranks_recv; 18240c7d97c5SJed Brown PetscMPIInt count_recv=0; 18250c7d97c5SJed Brown PetscMPIInt rank_coarse_proc_send_to; 18260c7d97c5SJed Brown PetscMPIInt coarse_color = MPI_UNDEFINED; 18270c7d97c5SJed Brown ISLocalToGlobalMapping coarse_ISLG; 18280c7d97c5SJed Brown /* some other variables */ 18290c7d97c5SJed Brown PetscErrorCode ierr; 18300c7d97c5SJed Brown const MatType coarse_mat_type; 18310c7d97c5SJed Brown const PCType coarse_pc_type; 183253cdbc3dSStefano Zampini const KSPType coarse_ksp_type; 183353cdbc3dSStefano Zampini PC pc_temp; 18340c7d97c5SJed Brown PetscInt i,j,k,bs; 18353b03a366Sstefano_zampini PetscInt max_it_coarse_ksp=1; /* don't increase this value */ 1836e269702eSStefano Zampini /* verbose output viewer */ 1837e269702eSStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 1838e269702eSStefano Zampini PetscBool dbg_flag=pcbddc->dbg_flag; 18390c7d97c5SJed Brown 18400c7d97c5SJed Brown PetscFunctionBegin; 18410c7d97c5SJed Brown 18420c7d97c5SJed Brown ins_local_primal_indices = 0; 18430c7d97c5SJed Brown ins_coarse_mat_vals = 0; 18440c7d97c5SJed Brown localsizes2 = 0; 18450c7d97c5SJed Brown localdispl2 = 0; 18460c7d97c5SJed Brown temp_coarse_mat_vals = 0; 18470c7d97c5SJed Brown coarse_ISLG = 0; 18480c7d97c5SJed Brown 184953cdbc3dSStefano Zampini ierr = MPI_Comm_size(prec_comm,&size_prec_comm);CHKERRQ(ierr); 185053cdbc3dSStefano Zampini ierr = MPI_Comm_rank(prec_comm,&rank_prec_comm);CHKERRQ(ierr); 18510c7d97c5SJed Brown ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 18520c7d97c5SJed Brown 1853beed3852SStefano Zampini /* Assign global numbering to coarse dofs */ 1854beed3852SStefano Zampini { 1855a0ba757dSStefano Zampini PetscScalar one=1.,zero=0.; 1856beed3852SStefano Zampini PetscScalar *array; 1857beed3852SStefano Zampini PetscMPIInt *auxlocal_primal; 1858beed3852SStefano Zampini PetscMPIInt *auxglobal_primal; 1859beed3852SStefano Zampini PetscMPIInt *all_auxglobal_primal; 1860beed3852SStefano Zampini PetscMPIInt *all_auxglobal_primal_dummy; 1861beed3852SStefano Zampini PetscMPIInt mpi_local_primal_size = (PetscMPIInt)pcbddc->local_primal_size; 1862da1bb401SStefano Zampini PetscInt *row_cmat_indices; 18633b03a366Sstefano_zampini PetscInt size_of_constraint; 1864da1bb401SStefano Zampini PetscScalar coarsesum; 1865beed3852SStefano Zampini 1866beed3852SStefano Zampini /* Construct needed data structures for message passing */ 1867beed3852SStefano Zampini ierr = PetscMalloc(mpi_local_primal_size*sizeof(PetscMPIInt),&pcbddc->local_primal_indices);CHKERRQ(ierr); 1868beed3852SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&pcbddc->local_primal_sizes);CHKERRQ(ierr); 1869beed3852SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 1870beed3852SStefano Zampini /* Gather local_primal_size information for all processes */ 18715619798eSStefano Zampini ierr = MPI_Allgather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,prec_comm);CHKERRQ(ierr); 1872beed3852SStefano Zampini pcbddc->replicated_primal_size = 0; 1873beed3852SStefano Zampini for (i=0; i<size_prec_comm; i++) { 1874beed3852SStefano Zampini pcbddc->local_primal_displacements[i] = pcbddc->replicated_primal_size ; 1875beed3852SStefano Zampini pcbddc->replicated_primal_size += pcbddc->local_primal_sizes[i]; 1876beed3852SStefano Zampini } 18775619798eSStefano Zampini if(rank_prec_comm == 0) { 1878beed3852SStefano Zampini /* allocate some auxiliary space */ 1879beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->replicated_primal_size*sizeof(*all_auxglobal_primal),&all_auxglobal_primal);CHKERRQ(ierr); 1880beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->replicated_primal_size*sizeof(*all_auxglobal_primal_dummy),&all_auxglobal_primal_dummy);CHKERRQ(ierr); 1881beed3852SStefano Zampini } 1882beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscMPIInt),&auxlocal_primal);CHKERRQ(ierr); 1883beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscMPIInt),&auxglobal_primal);CHKERRQ(ierr); 1884beed3852SStefano Zampini 1885da1bb401SStefano Zampini /* First let's count coarse dofs. 1886beed3852SStefano Zampini This code fragment assumes that the number of local constraints per connected component 1887beed3852SStefano Zampini is not greater than the number of nodes defined for the connected component 1888beed3852SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 18893b03a366Sstefano_zampini /* auxlocal_primal : primal indices in local nodes numbering (internal and interface) with complete queue sorted by global ordering */ 1890beed3852SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 1891beed3852SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1892da1bb401SStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) { 1893da1bb401SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 18943b03a366Sstefano_zampini for (j=0; j<size_of_constraint; j++) { 18953b03a366Sstefano_zampini k = row_cmat_indices[j]; 1896beed3852SStefano Zampini if( array[k] == zero ) { 1897beed3852SStefano Zampini array[k] = one; 1898da1bb401SStefano Zampini auxlocal_primal[i] = k; 1899beed3852SStefano Zampini break; 1900beed3852SStefano Zampini } 1901beed3852SStefano Zampini } 1902da1bb401SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,PETSC_NULL);CHKERRQ(ierr); 1903beed3852SStefano Zampini } 1904beed3852SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1905da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 1906da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1907da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1908da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1909da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1910da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1911da1bb401SStefano Zampini for(i=0;i<pcis->n;i++) { if( array[i] > zero) array[i] = one/array[i]; } 1912da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1913da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 1914da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1915da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1916da1bb401SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 1917da1bb401SStefano Zampini pcbddc->coarse_size = (PetscInt) coarsesum; 1918a0ba757dSStefano Zampini 1919beed3852SStefano Zampini /* Now assign them a global numbering */ 1920beed3852SStefano Zampini /* auxglobal_primal contains indices in global nodes numbering (internal and interface) */ 1921beed3852SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,pcbddc->local_primal_size,auxlocal_primal,auxglobal_primal);CHKERRQ(ierr); 1922beed3852SStefano Zampini /* all_auxglobal_primal contains all primal nodes indices in global nodes numbering (internal and interface) */ 1923beed3852SStefano 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); 1924beed3852SStefano Zampini 1925beed3852SStefano Zampini /* After this block all_auxglobal_primal should contains one copy of each primal node's indices in global nodes numbering */ 1926beed3852SStefano Zampini /* It implements a function similar to PetscSortRemoveDupsInt */ 1927beed3852SStefano Zampini if(rank_prec_comm==0) { 1928beed3852SStefano Zampini /* dummy argument since PetscSortMPIInt doesn't exist! */ 1929beed3852SStefano Zampini ierr = PetscSortMPIIntWithArray(pcbddc->replicated_primal_size,all_auxglobal_primal,all_auxglobal_primal_dummy);CHKERRQ(ierr); 1930beed3852SStefano Zampini k=1; 1931beed3852SStefano Zampini j=all_auxglobal_primal[0]; /* first dof in global numbering */ 1932beed3852SStefano Zampini for(i=1;i< pcbddc->replicated_primal_size ;i++) { 1933beed3852SStefano Zampini if(j != all_auxglobal_primal[i] ) { 1934beed3852SStefano Zampini all_auxglobal_primal[k]=all_auxglobal_primal[i]; 1935beed3852SStefano Zampini k++; 1936beed3852SStefano Zampini j=all_auxglobal_primal[i]; 1937beed3852SStefano Zampini } 1938beed3852SStefano Zampini } 1939beed3852SStefano Zampini } else { 1940beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscMPIInt),&all_auxglobal_primal);CHKERRQ(ierr); 1941beed3852SStefano Zampini } 19425619798eSStefano Zampini /* We only need to broadcast the indices from 0 to pcbddc->coarse_size. Remaning elements of array all_aux_global_primal are garbage. */ 1943beed3852SStefano Zampini ierr = MPI_Bcast(all_auxglobal_primal,pcbddc->coarse_size,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 1944beed3852SStefano Zampini 1945beed3852SStefano Zampini /* Now get global coarse numbering of local primal nodes */ 1946beed3852SStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) { 1947beed3852SStefano Zampini k=0; 1948beed3852SStefano Zampini while( all_auxglobal_primal[k] != auxglobal_primal[i] ) { k++;} 1949beed3852SStefano Zampini pcbddc->local_primal_indices[i]=k; 1950beed3852SStefano Zampini } 1951e269702eSStefano Zampini if(dbg_flag) { 1952e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1953da1bb401SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem %d\n",pcbddc->coarse_size);CHKERRQ(ierr); 1954e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1955e269702eSStefano Zampini } 1956beed3852SStefano Zampini /* free allocated memory */ 1957beed3852SStefano Zampini ierr = PetscFree(auxlocal_primal);CHKERRQ(ierr); 1958beed3852SStefano Zampini ierr = PetscFree(auxglobal_primal);CHKERRQ(ierr); 1959beed3852SStefano Zampini ierr = PetscFree(all_auxglobal_primal);CHKERRQ(ierr); 1960e269702eSStefano Zampini if(rank_prec_comm == 0) { 1961beed3852SStefano Zampini ierr = PetscFree(all_auxglobal_primal_dummy);CHKERRQ(ierr); 1962beed3852SStefano Zampini } 1963e269702eSStefano Zampini } 1964beed3852SStefano Zampini 19650c7d97c5SJed Brown /* adapt coarse problem type */ 19660c7d97c5SJed Brown if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC && pcbddc->active_procs < MIN_PROCS_FOR_BDDC ) 19670c7d97c5SJed Brown pcbddc->coarse_problem_type = PARALLEL_BDDC; 19680c7d97c5SJed Brown 19690c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 19700c7d97c5SJed Brown 1971da1bb401SStefano Zampini case(MULTILEVEL_BDDC): /* we define a coarse mesh where subdomains are elements */ 19720c7d97c5SJed Brown { 19730c7d97c5SJed Brown /* we need additional variables */ 19740c7d97c5SJed Brown MetisInt n_subdomains,n_parts,objval,ncon,faces_nvtxs; 19750c7d97c5SJed Brown MetisInt *metis_coarse_subdivision; 19760c7d97c5SJed Brown MetisInt options[METIS_NOPTIONS]; 19770c7d97c5SJed Brown PetscMPIInt size_coarse_comm,rank_coarse_comm; 19780c7d97c5SJed Brown PetscMPIInt procs_jumps_coarse_comm; 19790c7d97c5SJed Brown PetscMPIInt *coarse_subdivision; 19800c7d97c5SJed Brown PetscMPIInt *total_count_recv; 19810c7d97c5SJed Brown PetscMPIInt *total_ranks_recv; 19820c7d97c5SJed Brown PetscMPIInt *displacements_recv; 19830c7d97c5SJed Brown PetscMPIInt *my_faces_connectivity; 19840c7d97c5SJed Brown PetscMPIInt *petsc_faces_adjncy; 19850c7d97c5SJed Brown MetisInt *faces_adjncy; 19860c7d97c5SJed Brown MetisInt *faces_xadj; 19870c7d97c5SJed Brown PetscMPIInt *number_of_faces; 19880c7d97c5SJed Brown PetscMPIInt *faces_displacements; 19890c7d97c5SJed Brown PetscInt *array_int; 19900c7d97c5SJed Brown PetscMPIInt my_faces=0; 19910c7d97c5SJed Brown PetscMPIInt total_faces=0; 19923828260eSStefano Zampini PetscInt ranks_stretching_ratio; 19930c7d97c5SJed Brown 19940c7d97c5SJed Brown /* define some quantities */ 19950c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 19960c7d97c5SJed Brown coarse_mat_type = MATIS; 19970c7d97c5SJed Brown coarse_pc_type = PCBDDC; 19986c9de887SHong Zhang coarse_ksp_type = KSPCHEBYSHEV; 19990c7d97c5SJed Brown 20000c7d97c5SJed Brown /* details of coarse decomposition */ 20010c7d97c5SJed Brown n_subdomains = pcbddc->active_procs; 20020c7d97c5SJed Brown n_parts = n_subdomains/pcbddc->coarsening_ratio; 20033828260eSStefano Zampini ranks_stretching_ratio = size_prec_comm/pcbddc->active_procs; 20043828260eSStefano Zampini procs_jumps_coarse_comm = pcbddc->coarsening_ratio*ranks_stretching_ratio; 20053828260eSStefano Zampini 2006da1bb401SStefano Zampini /*printf("Coarse algorithm details: \n"); 2007da1bb401SStefano 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));*/ 20080c7d97c5SJed Brown 20090c7d97c5SJed Brown /* build CSR graph of subdomains' connectivity through faces */ 20100c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&array_int);CHKERRQ(ierr); 20113828260eSStefano Zampini ierr = PetscMemzero(array_int,pcis->n*sizeof(PetscInt));CHKERRQ(ierr); 20120c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){/* i=1 so I don't count myself -> faces nodes counts to 1 */ 20130c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 20140c7d97c5SJed Brown array_int[ pcis->shared[i][j] ]+=1; 20150c7d97c5SJed Brown } 20160c7d97c5SJed Brown } 20170c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){ 20180c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 20190c7d97c5SJed Brown if(array_int[ pcis->shared[i][j] ] == 1 ){ 20200c7d97c5SJed Brown my_faces++; 20210c7d97c5SJed Brown break; 20220c7d97c5SJed Brown } 20230c7d97c5SJed Brown } 20240c7d97c5SJed Brown } 20250c7d97c5SJed Brown 202653cdbc3dSStefano Zampini ierr = MPI_Reduce(&my_faces,&total_faces,1,MPIU_INT,MPI_SUM,master_proc,prec_comm);CHKERRQ(ierr); 20270c7d97c5SJed Brown ierr = PetscMalloc (my_faces*sizeof(PetscInt),&my_faces_connectivity);CHKERRQ(ierr); 20280c7d97c5SJed Brown my_faces=0; 20290c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){ 20300c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 20310c7d97c5SJed Brown if(array_int[ pcis->shared[i][j] ] == 1 ){ 20320c7d97c5SJed Brown my_faces_connectivity[my_faces]=pcis->neigh[i]; 20330c7d97c5SJed Brown my_faces++; 20340c7d97c5SJed Brown break; 20350c7d97c5SJed Brown } 20360c7d97c5SJed Brown } 20370c7d97c5SJed Brown } 20380c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 20390c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(PetscMPIInt),&petsc_faces_adjncy);CHKERRQ(ierr); 20400c7d97c5SJed Brown ierr = PetscMalloc (size_prec_comm*sizeof(PetscMPIInt),&number_of_faces);CHKERRQ(ierr); 20410c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(MetisInt),&faces_adjncy);CHKERRQ(ierr); 20420c7d97c5SJed Brown ierr = PetscMalloc ((n_subdomains+1)*sizeof(MetisInt),&faces_xadj);CHKERRQ(ierr); 20430c7d97c5SJed Brown ierr = PetscMalloc ((size_prec_comm+1)*sizeof(PetscMPIInt),&faces_displacements);CHKERRQ(ierr); 20440c7d97c5SJed Brown } 204553cdbc3dSStefano Zampini ierr = MPI_Gather(&my_faces,1,MPIU_INT,&number_of_faces[0],1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 20460c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 20470c7d97c5SJed Brown faces_xadj[0]=0; 20480c7d97c5SJed Brown faces_displacements[0]=0; 20490c7d97c5SJed Brown j=0; 20500c7d97c5SJed Brown for(i=1;i<size_prec_comm+1;i++) { 20510c7d97c5SJed Brown faces_displacements[i]=faces_displacements[i-1]+number_of_faces[i-1]; 20520c7d97c5SJed Brown if(number_of_faces[i-1]) { 20530c7d97c5SJed Brown j++; 20540c7d97c5SJed Brown faces_xadj[j]=faces_xadj[j-1]+number_of_faces[i-1]; 20550c7d97c5SJed Brown } 20560c7d97c5SJed Brown } 2057da1bb401SStefano Zampini /*printf("The J I count is %d and should be %d\n",j,n_subdomains); 2058da1bb401SStefano Zampini printf("Total faces seem %d and should be %d\n",faces_xadj[j],total_faces);*/ 20590c7d97c5SJed Brown } 206053cdbc3dSStefano 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); 20610c7d97c5SJed Brown ierr = PetscFree(my_faces_connectivity);CHKERRQ(ierr); 20620c7d97c5SJed Brown ierr = PetscFree(array_int);CHKERRQ(ierr); 20630c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 20643828260eSStefano Zampini for(i=0;i<total_faces;i++) faces_adjncy[i]=(MetisInt)(petsc_faces_adjncy[i]/ranks_stretching_ratio); /* cast to MetisInt */ 2065da1bb401SStefano Zampini /*printf("This is the face connectivity (actual ranks)\n"); 20660c7d97c5SJed Brown for(i=0;i<n_subdomains;i++){ 20670c7d97c5SJed Brown printf("proc %d is connected with \n",i); 20680c7d97c5SJed Brown for(j=faces_xadj[i];j<faces_xadj[i+1];j++) 20690c7d97c5SJed Brown printf("%d ",faces_adjncy[j]); 20700c7d97c5SJed Brown printf("\n"); 2071da1bb401SStefano Zampini }*/ 20720c7d97c5SJed Brown ierr = PetscFree(faces_displacements);CHKERRQ(ierr); 20730c7d97c5SJed Brown ierr = PetscFree(number_of_faces);CHKERRQ(ierr); 20740c7d97c5SJed Brown ierr = PetscFree(petsc_faces_adjncy);CHKERRQ(ierr); 20750c7d97c5SJed Brown } 20760c7d97c5SJed Brown 20770c7d97c5SJed Brown if( rank_prec_comm == master_proc ) { 20780c7d97c5SJed Brown 20793828260eSStefano Zampini PetscInt heuristic_for_metis=3; 20803828260eSStefano Zampini 20810c7d97c5SJed Brown ncon=1; 20820c7d97c5SJed Brown faces_nvtxs=n_subdomains; 20830c7d97c5SJed Brown /* partition graoh induced by face connectivity */ 20840c7d97c5SJed Brown ierr = PetscMalloc (n_subdomains*sizeof(MetisInt),&metis_coarse_subdivision);CHKERRQ(ierr); 20850c7d97c5SJed Brown ierr = METIS_SetDefaultOptions(options); 20860c7d97c5SJed Brown /* we need a contiguous partition of the coarse mesh */ 20870c7d97c5SJed Brown options[METIS_OPTION_CONTIG]=1; 20880c7d97c5SJed Brown options[METIS_OPTION_DBGLVL]=1; 20890c7d97c5SJed Brown options[METIS_OPTION_NITER]=30; 20903828260eSStefano Zampini if(n_subdomains>n_parts*heuristic_for_metis) { 20913828260eSStefano Zampini options[METIS_OPTION_IPTYPE]=METIS_IPTYPE_EDGE; 20923828260eSStefano Zampini options[METIS_OPTION_OBJTYPE]=METIS_OBJTYPE_CUT; 20930c7d97c5SJed Brown ierr = METIS_PartGraphKway(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 20943828260eSStefano Zampini } else { 20953828260eSStefano Zampini ierr = METIS_PartGraphRecursive(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 20963828260eSStefano Zampini } 20970c7d97c5SJed 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); 20980c7d97c5SJed Brown ierr = PetscFree(faces_xadj);CHKERRQ(ierr); 20990c7d97c5SJed Brown ierr = PetscFree(faces_adjncy);CHKERRQ(ierr); 21000c7d97c5SJed Brown coarse_subdivision = (PetscMPIInt*)calloc(size_prec_comm,sizeof(PetscMPIInt)); /* calloc for contiguous memory since we need to scatter these values later */ 21010c7d97c5SJed Brown /* copy/cast values avoiding possible type conflicts between PETSc, MPI and METIS */ 21023828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) coarse_subdivision[i]=MPI_PROC_NULL; 21033828260eSStefano Zampini for(i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=(PetscInt)(metis_coarse_subdivision[i]); 21040c7d97c5SJed Brown ierr = PetscFree(metis_coarse_subdivision);CHKERRQ(ierr); 21050c7d97c5SJed Brown } 21060c7d97c5SJed Brown 21070c7d97c5SJed Brown /* Create new communicator for coarse problem splitting the old one */ 21080c7d97c5SJed Brown if( !(rank_prec_comm%procs_jumps_coarse_comm) && rank_prec_comm < procs_jumps_coarse_comm*n_parts ){ 2109da1bb401SStefano Zampini coarse_color=0; /* for communicator splitting */ 2110da1bb401SStefano Zampini active_rank=rank_prec_comm; /* for insertion of matrix values */ 21110c7d97c5SJed Brown } 2112da1bb401SStefano Zampini /* procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 2113da1bb401SStefano Zampini key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator */ 211453cdbc3dSStefano Zampini ierr = MPI_Comm_split(prec_comm,coarse_color,rank_prec_comm,&coarse_comm);CHKERRQ(ierr); 21150c7d97c5SJed Brown 21160c7d97c5SJed Brown if( coarse_color == 0 ) { 211753cdbc3dSStefano Zampini ierr = MPI_Comm_size(coarse_comm,&size_coarse_comm);CHKERRQ(ierr); 211853cdbc3dSStefano Zampini ierr = MPI_Comm_rank(coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 2119da1bb401SStefano Zampini /*printf("Details of coarse comm\n"); 21203828260eSStefano Zampini printf("size = %d, myrank = %d\n",size_coarse_comm,rank_coarse_comm); 2121da1bb401SStefano Zampini printf("jumps = %d, coarse_color = %d, n_parts = %d\n",procs_jumps_coarse_comm,coarse_color,n_parts);*/ 21220c7d97c5SJed Brown } else { 21230c7d97c5SJed Brown rank_coarse_comm = MPI_PROC_NULL; 21240c7d97c5SJed Brown } 21250c7d97c5SJed Brown 21260c7d97c5SJed Brown /* master proc take care of arranging and distributing coarse informations */ 21270c7d97c5SJed Brown if(rank_coarse_comm == master_proc) { 21280c7d97c5SJed Brown ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&displacements_recv);CHKERRQ(ierr); 2129da1bb401SStefano Zampini /*ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&total_count_recv);CHKERRQ(ierr); 2130da1bb401SStefano Zampini ierr = PetscMalloc (n_subdomains*sizeof(PetscMPIInt),&total_ranks_recv);CHKERRQ(ierr);*/ 21310c7d97c5SJed Brown total_count_recv = (PetscMPIInt*)calloc(size_prec_comm,sizeof(PetscMPIInt)); 21320c7d97c5SJed Brown total_ranks_recv = (PetscMPIInt*)calloc(n_subdomains,sizeof(PetscMPIInt)); 21330c7d97c5SJed Brown /* some initializations */ 21340c7d97c5SJed Brown displacements_recv[0]=0; 2135da1bb401SStefano Zampini /* PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt)); not needed -> calloc initializes to zero */ 21360c7d97c5SJed Brown /* count from how many processes the j-th process of the coarse decomposition will receive data */ 21370c7d97c5SJed Brown for(j=0;j<size_coarse_comm;j++) 21383828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) 21390c7d97c5SJed Brown if(coarse_subdivision[i]==j) 21400c7d97c5SJed Brown total_count_recv[j]++; 21410c7d97c5SJed Brown /* displacements needed for scatterv of total_ranks_recv */ 21420c7d97c5SJed Brown for(i=1;i<size_coarse_comm;i++) displacements_recv[i]=displacements_recv[i-1]+total_count_recv[i-1]; 21430c7d97c5SJed Brown /* Now fill properly total_ranks_recv -> each coarse process will receive the ranks (in prec_comm communicator) of its friend (sending) processes */ 21440c7d97c5SJed Brown ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 21450c7d97c5SJed Brown for(j=0;j<size_coarse_comm;j++) { 21463828260eSStefano Zampini for(i=0;i<size_prec_comm;i++) { 21470c7d97c5SJed Brown if(coarse_subdivision[i]==j) { 21480c7d97c5SJed Brown total_ranks_recv[displacements_recv[j]+total_count_recv[j]]=i; 21493828260eSStefano Zampini total_count_recv[j]+=1; 21500c7d97c5SJed Brown } 21510c7d97c5SJed Brown } 21520c7d97c5SJed Brown } 2153da1bb401SStefano Zampini /*for(j=0;j<size_coarse_comm;j++) { 21543828260eSStefano Zampini printf("process %d in new rank will receive from %d processes (original ranks follows)\n",j,total_count_recv[j]); 21553828260eSStefano Zampini for(i=0;i<total_count_recv[j];i++) { 21563828260eSStefano Zampini printf("%d ",total_ranks_recv[displacements_recv[j]+i]); 21573828260eSStefano Zampini } 21583828260eSStefano Zampini printf("\n"); 2159da1bb401SStefano Zampini }*/ 21600c7d97c5SJed Brown 21610c7d97c5SJed Brown /* identify new decomposition in terms of ranks in the old communicator */ 21623828260eSStefano Zampini for(i=0;i<n_subdomains;i++) coarse_subdivision[ranks_stretching_ratio*i]=coarse_subdivision[ranks_stretching_ratio*i]*procs_jumps_coarse_comm; 2163da1bb401SStefano Zampini /*printf("coarse_subdivision in old end new ranks\n"); 21640c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) 21653828260eSStefano Zampini if(coarse_subdivision[i]!=MPI_PROC_NULL) { 21663828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]/procs_jumps_coarse_comm); 21673828260eSStefano Zampini } else { 21683828260eSStefano Zampini printf("%d=(%d %d), ",i,coarse_subdivision[i],coarse_subdivision[i]); 21693828260eSStefano Zampini } 2170da1bb401SStefano Zampini printf("\n");*/ 21710c7d97c5SJed Brown } 21720c7d97c5SJed Brown 21730c7d97c5SJed Brown /* Scatter new decomposition for send details */ 217453cdbc3dSStefano Zampini ierr = MPI_Scatter(&coarse_subdivision[0],1,MPIU_INT,&rank_coarse_proc_send_to,1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 21750c7d97c5SJed Brown /* Scatter receiving details to members of coarse decomposition */ 21760c7d97c5SJed Brown if( coarse_color == 0) { 217753cdbc3dSStefano Zampini ierr = MPI_Scatter(&total_count_recv[0],1,MPIU_INT,&count_recv,1,MPIU_INT,master_proc,coarse_comm);CHKERRQ(ierr); 21780c7d97c5SJed Brown ierr = PetscMalloc (count_recv*sizeof(PetscMPIInt),&ranks_recv);CHKERRQ(ierr); 217953cdbc3dSStefano 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); 21800c7d97c5SJed Brown } 21810c7d97c5SJed Brown 2182da1bb401SStefano Zampini /*printf("I will send my matrix data to proc %d\n",rank_coarse_proc_send_to); 2183da1bb401SStefano Zampini if(coarse_color == 0) { 2184da1bb401SStefano Zampini printf("I will receive some matrix data from %d processes (ranks follows)\n",count_recv); 2185da1bb401SStefano Zampini for(i=0;i<count_recv;i++) 2186da1bb401SStefano Zampini printf("%d ",ranks_recv[i]); 2187da1bb401SStefano Zampini printf("\n"); 2188da1bb401SStefano Zampini }*/ 21890c7d97c5SJed Brown 21900c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 2191da1bb401SStefano Zampini /*ierr = PetscFree(coarse_subdivision);CHKERRQ(ierr); 2192da1bb401SStefano Zampini ierr = PetscFree(total_count_recv);CHKERRQ(ierr); 2193da1bb401SStefano Zampini ierr = PetscFree(total_ranks_recv);CHKERRQ(ierr);*/ 21940c7d97c5SJed Brown free(coarse_subdivision); 21950c7d97c5SJed Brown free(total_count_recv); 21960c7d97c5SJed Brown free(total_ranks_recv); 21970c7d97c5SJed Brown ierr = PetscFree(displacements_recv);CHKERRQ(ierr); 21980c7d97c5SJed Brown } 21990c7d97c5SJed Brown break; 22000c7d97c5SJed Brown } 22010c7d97c5SJed Brown 22020c7d97c5SJed Brown case(REPLICATED_BDDC): 22030c7d97c5SJed Brown 22040c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 22050c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 22060c7d97c5SJed Brown coarse_pc_type = PCLU; 220753cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 22080c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 22090c7d97c5SJed Brown active_rank = rank_prec_comm; 22100c7d97c5SJed Brown break; 22110c7d97c5SJed Brown 22120c7d97c5SJed Brown case(PARALLEL_BDDC): 22130c7d97c5SJed Brown 22140c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 22150c7d97c5SJed Brown coarse_mat_type = MATMPIAIJ; 22160c7d97c5SJed Brown coarse_pc_type = PCREDUNDANT; 221753cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 22180c7d97c5SJed Brown coarse_comm = prec_comm; 22190c7d97c5SJed Brown active_rank = rank_prec_comm; 22200c7d97c5SJed Brown break; 22210c7d97c5SJed Brown 22220c7d97c5SJed Brown case(SEQUENTIAL_BDDC): 22230c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 22240c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 22250c7d97c5SJed Brown coarse_pc_type = PCLU; 222653cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 22270c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 22280c7d97c5SJed Brown active_rank = master_proc; 22290c7d97c5SJed Brown break; 22300c7d97c5SJed Brown } 22310c7d97c5SJed Brown 22320c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 22330c7d97c5SJed Brown 22340c7d97c5SJed Brown case(SCATTERS_BDDC): 22350c7d97c5SJed Brown { 22360c7d97c5SJed Brown if(pcbddc->coarse_problem_type==MULTILEVEL_BDDC) { 22370c7d97c5SJed Brown 22380c7d97c5SJed Brown PetscMPIInt send_size; 22390c7d97c5SJed Brown PetscInt *aux_ins_indices; 22400c7d97c5SJed Brown PetscInt ii,jj; 22410c7d97c5SJed Brown MPI_Request *requests; 22420c7d97c5SJed Brown 22430c7d97c5SJed Brown /* allocate auxiliary space */ 22445619798eSStefano Zampini ierr = PetscMalloc (pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 22455619798eSStefano 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); 22460c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->coarse_size*sizeof(PetscInt),&aux_ins_indices);CHKERRQ(ierr); 22470c7d97c5SJed Brown ierr = PetscMemzero(aux_ins_indices,pcbddc->coarse_size*sizeof(PetscInt));CHKERRQ(ierr); 22480c7d97c5SJed Brown /* allocate stuffs for message massing */ 22490c7d97c5SJed Brown ierr = PetscMalloc ( (count_recv+1)*sizeof(MPI_Request),&requests);CHKERRQ(ierr); 22500c7d97c5SJed Brown for(i=0;i<count_recv+1;i++) requests[i]=MPI_REQUEST_NULL; 22510c7d97c5SJed Brown ierr = PetscMalloc ( count_recv*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 22520c7d97c5SJed Brown ierr = PetscMalloc ( count_recv*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 22530c7d97c5SJed Brown /* fill up quantities */ 22540c7d97c5SJed Brown j=0; 22550c7d97c5SJed Brown for(i=0;i<count_recv;i++){ 22560c7d97c5SJed Brown ii = ranks_recv[i]; 22570c7d97c5SJed Brown localsizes2[i]=pcbddc->local_primal_sizes[ii]*pcbddc->local_primal_sizes[ii]; 22580c7d97c5SJed Brown localdispl2[i]=j; 22590c7d97c5SJed Brown j+=localsizes2[i]; 22600c7d97c5SJed Brown jj = pcbddc->local_primal_displacements[ii]; 2261da1bb401SStefano 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 */ 22620c7d97c5SJed Brown } 2263da1bb401SStefano Zampini /*printf("aux_ins_indices 1\n"); 2264da1bb401SStefano Zampini for(i=0;i<pcbddc->coarse_size;i++) 2265da1bb401SStefano Zampini printf("%d ",aux_ins_indices[i]); 2266da1bb401SStefano Zampini printf("\n");*/ 22670c7d97c5SJed Brown /* temp_coarse_mat_vals used to store temporarly received matrix values */ 22680c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 22690c7d97c5SJed Brown /* evaluate how many values I will insert in coarse mat */ 22700c7d97c5SJed Brown ins_local_primal_size=0; 22710c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++) 22720c7d97c5SJed Brown if(aux_ins_indices[i]) 22730c7d97c5SJed Brown ins_local_primal_size++; 22740c7d97c5SJed Brown /* evaluate indices I will insert in coarse mat */ 22750c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 22760c7d97c5SJed Brown j=0; 22770c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++) 22780c7d97c5SJed Brown if(aux_ins_indices[i]) 22790c7d97c5SJed Brown ins_local_primal_indices[j++]=i; 22800c7d97c5SJed Brown /* use aux_ins_indices to realize a global to local mapping */ 22810c7d97c5SJed Brown j=0; 22820c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++){ 22830c7d97c5SJed Brown if(aux_ins_indices[i]==0){ 22840c7d97c5SJed Brown aux_ins_indices[i]=-1; 22850c7d97c5SJed Brown } else { 22860c7d97c5SJed Brown aux_ins_indices[i]=j; 22870c7d97c5SJed Brown j++; 22880c7d97c5SJed Brown } 22890c7d97c5SJed Brown } 22900c7d97c5SJed Brown 2291da1bb401SStefano Zampini /*printf("New details localsizes2 localdispl2\n"); 2292da1bb401SStefano Zampini for(i=0;i<count_recv;i++) 2293da1bb401SStefano Zampini printf("(%d %d) ",localsizes2[i],localdispl2[i]); 2294da1bb401SStefano Zampini printf("\n"); 2295da1bb401SStefano Zampini printf("aux_ins_indices 2\n"); 2296da1bb401SStefano Zampini for(i=0;i<pcbddc->coarse_size;i++) 2297da1bb401SStefano Zampini printf("%d ",aux_ins_indices[i]); 2298da1bb401SStefano Zampini printf("\n"); 2299da1bb401SStefano Zampini printf("ins_local_primal_indices\n"); 2300da1bb401SStefano Zampini for(i=0;i<ins_local_primal_size;i++) 2301da1bb401SStefano Zampini printf("%d ",ins_local_primal_indices[i]); 2302da1bb401SStefano Zampini printf("\n"); 2303da1bb401SStefano Zampini printf("coarse_submat_vals\n"); 2304da1bb401SStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) 2305da1bb401SStefano Zampini for(j=0;j<pcbddc->local_primal_size;j++) 2306da1bb401SStefano 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]); 2307da1bb401SStefano Zampini printf("\n");*/ 23080c7d97c5SJed Brown 23090c7d97c5SJed Brown /* processes partecipating in coarse problem receive matrix data from their friends */ 231053cdbc3dSStefano 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); 23110c7d97c5SJed Brown if(rank_coarse_proc_send_to != MPI_PROC_NULL ) { 23120c7d97c5SJed Brown send_size=pcbddc->local_primal_size*pcbddc->local_primal_size; 231353cdbc3dSStefano 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); 23140c7d97c5SJed Brown } 231553cdbc3dSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 23160c7d97c5SJed Brown 2317da1bb401SStefano Zampini /*if(coarse_color == 0) { 2318da1bb401SStefano Zampini printf("temp_coarse_mat_vals\n"); 2319da1bb401SStefano Zampini for(k=0;k<count_recv;k++){ 2320da1bb401SStefano Zampini printf("---- %d ----\n",ranks_recv[k]); 2321da1bb401SStefano Zampini for(i=0;i<pcbddc->local_primal_sizes[ranks_recv[k]];i++) 2322da1bb401SStefano Zampini for(j=0;j<pcbddc->local_primal_sizes[ranks_recv[k]];j++) 2323da1bb401SStefano 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]); 2324da1bb401SStefano Zampini printf("\n"); 2325da1bb401SStefano Zampini } 2326da1bb401SStefano Zampini }*/ 23270c7d97c5SJed Brown /* calculate data to insert in coarse mat */ 23280c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 23290c7d97c5SJed Brown PetscMemzero(ins_coarse_mat_vals,ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar)); 23300c7d97c5SJed Brown 23310c7d97c5SJed Brown PetscMPIInt rr,kk,lps,lpd; 23320c7d97c5SJed Brown PetscInt row_ind,col_ind; 23330c7d97c5SJed Brown for(k=0;k<count_recv;k++){ 23340c7d97c5SJed Brown rr = ranks_recv[k]; 23350c7d97c5SJed Brown kk = localdispl2[k]; 23360c7d97c5SJed Brown lps = pcbddc->local_primal_sizes[rr]; 23370c7d97c5SJed Brown lpd = pcbddc->local_primal_displacements[rr]; 2338da1bb401SStefano Zampini /*printf("Inserting the following indices (received from %d)\n",rr);*/ 23390c7d97c5SJed Brown for(j=0;j<lps;j++){ 23400c7d97c5SJed Brown col_ind=aux_ins_indices[pcbddc->replicated_local_primal_indices[lpd+j]]; 23410c7d97c5SJed Brown for(i=0;i<lps;i++){ 23420c7d97c5SJed Brown row_ind=aux_ins_indices[pcbddc->replicated_local_primal_indices[lpd+i]]; 2343da1bb401SStefano Zampini /*printf("%d %d\n",row_ind,col_ind);*/ 23440c7d97c5SJed Brown ins_coarse_mat_vals[col_ind*ins_local_primal_size+row_ind]+=temp_coarse_mat_vals[kk+j*lps+i]; 23450c7d97c5SJed Brown } 23460c7d97c5SJed Brown } 23470c7d97c5SJed Brown } 23480c7d97c5SJed Brown ierr = PetscFree(requests);CHKERRQ(ierr); 23490c7d97c5SJed Brown ierr = PetscFree(aux_ins_indices);CHKERRQ(ierr); 23500c7d97c5SJed Brown ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr); 23510c7d97c5SJed Brown if(coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 23520c7d97c5SJed Brown 23530c7d97c5SJed Brown /* create local to global mapping needed by coarse MATIS */ 23540c7d97c5SJed Brown { 23550c7d97c5SJed Brown IS coarse_IS; 235653cdbc3dSStefano Zampini if(coarse_comm != MPI_COMM_NULL ) ierr = MPI_Comm_free(&coarse_comm);CHKERRQ(ierr); 23570c7d97c5SJed Brown coarse_comm = prec_comm; 23580c7d97c5SJed Brown active_rank=rank_prec_comm; 23590c7d97c5SJed Brown ierr = ISCreateGeneral(coarse_comm,ins_local_primal_size,ins_local_primal_indices,PETSC_COPY_VALUES,&coarse_IS);CHKERRQ(ierr); 23600c7d97c5SJed Brown ierr = ISLocalToGlobalMappingCreateIS(coarse_IS,&coarse_ISLG);CHKERRQ(ierr); 23610c7d97c5SJed Brown ierr = ISDestroy(&coarse_IS);CHKERRQ(ierr); 23620c7d97c5SJed Brown } 23630c7d97c5SJed Brown } 23640c7d97c5SJed Brown if(pcbddc->coarse_problem_type==PARALLEL_BDDC) { 23650c7d97c5SJed Brown /* arrays for values insertion */ 23660c7d97c5SJed Brown ins_local_primal_size = pcbddc->local_primal_size; 23670c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscMPIInt),&ins_local_primal_indices);CHKERRQ(ierr); 23680c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 23690c7d97c5SJed Brown for(j=0;j<ins_local_primal_size;j++){ 23700c7d97c5SJed Brown ins_local_primal_indices[j]=pcbddc->local_primal_indices[j]; 23710c7d97c5SJed 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]; 23720c7d97c5SJed Brown } 23730c7d97c5SJed Brown } 23740c7d97c5SJed Brown break; 23750c7d97c5SJed Brown 23760c7d97c5SJed Brown } 23770c7d97c5SJed Brown 23780c7d97c5SJed Brown case(GATHERS_BDDC): 23790c7d97c5SJed Brown { 23800c7d97c5SJed Brown 23810c7d97c5SJed Brown PetscMPIInt mysize,mysize2; 23820c7d97c5SJed Brown 23830c7d97c5SJed Brown if(rank_prec_comm==active_rank) { 23840c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 23850c7d97c5SJed Brown pcbddc->replicated_local_primal_values = (PetscScalar*)calloc(pcbddc->replicated_primal_size,sizeof(PetscScalar)); 23860c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 23870c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 23880c7d97c5SJed Brown /* arrays for values insertion */ 23890c7d97c5SJed Brown ins_local_primal_size = pcbddc->coarse_size; 23900c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscMPIInt),&ins_local_primal_indices);CHKERRQ(ierr); 23910c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 23920c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) localsizes2[i]=pcbddc->local_primal_sizes[i]*pcbddc->local_primal_sizes[i]; 23930c7d97c5SJed Brown localdispl2[0]=0; 23940c7d97c5SJed Brown for(i=1;i<size_prec_comm;i++) localdispl2[i]=localsizes2[i-1]+localdispl2[i-1]; 23950c7d97c5SJed Brown j=0; 23960c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) j+=localsizes2[i]; 23970c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 23980c7d97c5SJed Brown } 23990c7d97c5SJed Brown 24000c7d97c5SJed Brown mysize=pcbddc->local_primal_size; 24010c7d97c5SJed Brown mysize2=pcbddc->local_primal_size*pcbddc->local_primal_size; 24020c7d97c5SJed Brown if(pcbddc->coarse_problem_type == SEQUENTIAL_BDDC){ 240353cdbc3dSStefano 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); 240453cdbc3dSStefano 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); 24050c7d97c5SJed Brown } else { 240653cdbc3dSStefano 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); 240753cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,prec_comm);CHKERRQ(ierr); 24080c7d97c5SJed Brown } 24090c7d97c5SJed Brown 24100c7d97c5SJed Brown /* free data structures no longer needed and allocate some space which will be needed in BDDC application */ 24110c7d97c5SJed Brown if(rank_prec_comm==active_rank) { 24120c7d97c5SJed Brown PetscInt offset,offset2,row_ind,col_ind; 24130c7d97c5SJed Brown for(j=0;j<ins_local_primal_size;j++){ 24140c7d97c5SJed Brown ins_local_primal_indices[j]=j; 24150c7d97c5SJed Brown for(i=0;i<ins_local_primal_size;i++) ins_coarse_mat_vals[j*ins_local_primal_size+i]=0.0; 24160c7d97c5SJed Brown } 24170c7d97c5SJed Brown for(k=0;k<size_prec_comm;k++){ 24180c7d97c5SJed Brown offset=pcbddc->local_primal_displacements[k]; 24190c7d97c5SJed Brown offset2=localdispl2[k]; 24200c7d97c5SJed Brown for(j=0;j<pcbddc->local_primal_sizes[k];j++){ 24210c7d97c5SJed Brown col_ind=pcbddc->replicated_local_primal_indices[offset+j]; 24220c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_sizes[k];i++){ 24230c7d97c5SJed Brown row_ind=pcbddc->replicated_local_primal_indices[offset+i]; 24240c7d97c5SJed Brown ins_coarse_mat_vals[col_ind*pcbddc->coarse_size+row_ind]+=temp_coarse_mat_vals[offset2+j*pcbddc->local_primal_sizes[k]+i]; 24250c7d97c5SJed Brown } 24260c7d97c5SJed Brown } 24270c7d97c5SJed Brown } 24280c7d97c5SJed Brown } 24290c7d97c5SJed Brown break; 2430da1bb401SStefano Zampini }/* switch on coarse problem and communications associated with finished */ 24310c7d97c5SJed Brown } 24320c7d97c5SJed Brown 24330c7d97c5SJed Brown /* Now create and fill up coarse matrix */ 24340c7d97c5SJed Brown if( rank_prec_comm == active_rank ) { 24350c7d97c5SJed Brown if(pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 24360c7d97c5SJed Brown ierr = MatCreate(coarse_comm,&pcbddc->coarse_mat);CHKERRQ(ierr); 24370c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_mat,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size);CHKERRQ(ierr); 24380c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_mat,coarse_mat_type);CHKERRQ(ierr); 24393b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 2440da1bb401SStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 24413b03a366Sstefano_zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 24420c7d97c5SJed Brown } else { 24430c7d97c5SJed Brown Mat matis_coarse_local_mat; 2444d3ee2243SStefano Zampini /* remind bs */ 2445d3ee2243SStefano Zampini ierr = MatCreateIS(coarse_comm,bs,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_ISLG,&pcbddc->coarse_mat);CHKERRQ(ierr); 24463b03a366Sstefano_zampini ierr = MatSetUp(pcbddc->coarse_mat);CHKERRQ(ierr); 24470c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 24483b03a366Sstefano_zampini ierr = MatSetUp(matis_coarse_local_mat);CHKERRQ(ierr); 2449da1bb401SStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); /* local values stored in column major */ 2450a0ba757dSStefano Zampini ierr = MatSetOption(matis_coarse_local_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 24510c7d97c5SJed Brown } 2452a0ba757dSStefano Zampini ierr = MatSetOption(pcbddc->coarse_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 24530c7d97c5SJed 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); 24540c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24550c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24560c7d97c5SJed Brown 2457da1bb401SStefano Zampini /* PetscViewer view_out; 2458da1bb401SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,"coarsematfull.m",&view_out);CHKERRQ(ierr); 2459da1bb401SStefano Zampini ierr = PetscViewerSetFormat(view_out,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2460da1bb401SStefano Zampini ierr = MatView(pcbddc->coarse_mat,view_out);CHKERRQ(ierr); 2461da1bb401SStefano Zampini ierr = PetscViewerDestroy(&view_out);CHKERRQ(ierr);*/ 2462da1bb401SStefano Zampini 24630c7d97c5SJed Brown ierr = MatGetVecs(pcbddc->coarse_mat,&pcbddc->coarse_vec,&pcbddc->coarse_rhs);CHKERRQ(ierr); 24640c7d97c5SJed Brown /* Preconditioner for coarse problem */ 246553cdbc3dSStefano Zampini ierr = KSPCreate(coarse_comm,&pcbddc->coarse_ksp);CHKERRQ(ierr); 246653cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 246753cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 24683b03a366Sstefano_zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,max_it_coarse_ksp);CHKERRQ(ierr); 246953cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 247053cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 247153cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 24720c7d97c5SJed Brown /* Allow user's customization */ 2473da1bb401SStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,"coarse_");CHKERRQ(ierr); 247453cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 24750c7d97c5SJed Brown /* Set Up PC for coarse problem BDDC */ 247653cdbc3dSStefano Zampini if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 2477e269702eSStefano Zampini if(dbg_flag) { 2478e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------Setting up a new level---------------\n");CHKERRQ(ierr); 2479e269702eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2480e269702eSStefano Zampini } 248153cdbc3dSStefano Zampini ierr = PCBDDCSetCoarseProblemType(pc_temp,MULTILEVEL_BDDC);CHKERRQ(ierr); 248253cdbc3dSStefano Zampini } 248353cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 24845619798eSStefano Zampini if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 24855619798eSStefano Zampini if(dbg_flag) { 24865619798eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"----------------New level set------------------------\n");CHKERRQ(ierr); 24875619798eSStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 24885619798eSStefano Zampini } 24895619798eSStefano Zampini } 24900c7d97c5SJed Brown } 24910c7d97c5SJed Brown if(pcbddc->coarse_communications_type == SCATTERS_BDDC) { 24920c7d97c5SJed Brown IS local_IS,global_IS; 24930c7d97c5SJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&local_IS);CHKERRQ(ierr); 24940c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_indices,PETSC_COPY_VALUES,&global_IS);CHKERRQ(ierr); 24950c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_P,local_IS,pcbddc->coarse_vec,global_IS,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 24960c7d97c5SJed Brown ierr = ISDestroy(&local_IS);CHKERRQ(ierr); 24970c7d97c5SJed Brown ierr = ISDestroy(&global_IS);CHKERRQ(ierr); 24980c7d97c5SJed Brown } 24990c7d97c5SJed Brown 25000c7d97c5SJed Brown 25013b03a366Sstefano_zampini /* Evaluate condition number of coarse problem for cheby (and verbose output if requested) */ 25023b03a366Sstefano_zampini if( pcbddc->coarse_problem_type == MULTILEVEL_BDDC && rank_prec_comm == active_rank ) { 25030c7d97c5SJed Brown PetscScalar m_one=-1.0; 25045619798eSStefano Zampini PetscReal infty_error,lambda_min,lambda_max,kappa_2; 25053b03a366Sstefano_zampini const KSPType check_ksp_type=KSPGMRES; 25060c7d97c5SJed Brown 25075619798eSStefano Zampini /* change coarse ksp object to an iterative method suitable for extreme eigenvalues' estimation */ 25083b03a366Sstefano_zampini ierr = KSPSetType(pcbddc->coarse_ksp,check_ksp_type);CHKERRQ(ierr); 2509d49ef151SStefano Zampini ierr = KSPSetComputeSingularValues(pcbddc->coarse_ksp,PETSC_TRUE);CHKERRQ(ierr); 25105619798eSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,1.e-8,1.e-8,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 25115619798eSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 2512d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->coarse_rhs,PETSC_NULL);CHKERRQ(ierr); 2513d49ef151SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 2514d49ef151SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,pcbddc->coarse_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 2515d49ef151SStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,pcbddc->coarse_rhs,pcbddc->coarse_rhs);CHKERRQ(ierr); 2516d49ef151SStefano Zampini ierr = KSPComputeExtremeSingularValues(pcbddc->coarse_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); 25173b03a366Sstefano_zampini if(dbg_flag) { 25185619798eSStefano Zampini kappa_2=lambda_max/lambda_min; 25195619798eSStefano Zampini ierr = KSPGetIterationNumber(pcbddc->coarse_ksp,&k);CHKERRQ(ierr); 2520d49ef151SStefano Zampini ierr = VecAXPY(pcbddc->coarse_rhs,m_one,pcbddc->coarse_vec);CHKERRQ(ierr); 2521d49ef151SStefano Zampini ierr = VecNorm(pcbddc->coarse_rhs,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 25223b03a366Sstefano_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); 2523e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem eigenvalues: % 1.14e %1.14e\n",lambda_min,lambda_max);CHKERRQ(ierr); 2524e269702eSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Coarse problem infty_error: %1.14e\n",infty_error);CHKERRQ(ierr); 25253b03a366Sstefano_zampini } 25265619798eSStefano Zampini /* restore coarse ksp to default values */ 2527d49ef151SStefano Zampini ierr = KSPSetComputeSingularValues(pcbddc->coarse_ksp,PETSC_FALSE);CHKERRQ(ierr); 25285619798eSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 25296c9de887SHong Zhang ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 25303b03a366Sstefano_zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,max_it_coarse_ksp);CHKERRQ(ierr); 25315619798eSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 25325619798eSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 253353cdbc3dSStefano Zampini } 25340c7d97c5SJed Brown 25350c7d97c5SJed Brown /* free data structures no longer needed */ 25360c7d97c5SJed Brown if(coarse_ISLG) { ierr = ISLocalToGlobalMappingDestroy(&coarse_ISLG);CHKERRQ(ierr); } 25370c7d97c5SJed Brown if(ins_local_primal_indices) { ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); } 25380c7d97c5SJed Brown if(ins_coarse_mat_vals) { ierr = PetscFree(ins_coarse_mat_vals);CHKERRQ(ierr);} 25390c7d97c5SJed Brown if(localsizes2) { ierr = PetscFree(localsizes2);CHKERRQ(ierr);} 25400c7d97c5SJed Brown if(localdispl2) { ierr = PetscFree(localdispl2);CHKERRQ(ierr);} 25410c7d97c5SJed Brown if(temp_coarse_mat_vals) { ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr);} 25420c7d97c5SJed Brown 25430c7d97c5SJed Brown PetscFunctionReturn(0); 25440c7d97c5SJed Brown } 25450c7d97c5SJed Brown 25460c7d97c5SJed Brown #undef __FUNCT__ 25470c7d97c5SJed Brown #define __FUNCT__ "PCBDDCManageLocalBoundaries" 254853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCManageLocalBoundaries(PC pc) 25490c7d97c5SJed Brown { 25500c7d97c5SJed Brown 25510c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 25520c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 25530c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2554da1bb401SStefano Zampini PCBDDCGraph mat_graph=pcbddc->mat_graph; 2555a0ba757dSStefano Zampini PetscInt *queue_in_global_numbering; 25563b03a366Sstefano_zampini PetscInt bs,ierr,i,j,s,k,iindex,neumann_bsize,dirichlet_bsize; 2557da1bb401SStefano Zampini PetscInt total_counts,nodes_touched,where_values=1,vertex_size; 25583b03a366Sstefano_zampini PetscMPIInt adapt_interface=0,adapt_interface_reduced=0; 2559da1bb401SStefano Zampini PetscBool same_set; 2560a0ba757dSStefano Zampini MPI_Comm interface_comm=((PetscObject)pc)->comm; 25613b03a366Sstefano_zampini PetscBool use_faces=PETSC_FALSE,use_edges=PETSC_FALSE; 25623b03a366Sstefano_zampini const PetscInt *neumann_nodes; 25633b03a366Sstefano_zampini const PetscInt *dirichlet_nodes; 256436e030ebSStefano Zampini IS used_IS; 2565da1bb401SStefano Zampini PetscScalar *array; 2566da1bb401SStefano Zampini PetscScalar *array2; 2567da1bb401SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 25680c7d97c5SJed Brown 25690c7d97c5SJed Brown PetscFunctionBegin; 2570da1bb401SStefano Zampini /* Setup local adjacency graph */ 2571da1bb401SStefano Zampini mat_graph->nvtxs=pcis->n; 2572da1bb401SStefano Zampini ierr = PCBDDCSetupLocalAdjacencyGraph(pc);CHKERRQ(ierr); 2573a0ba757dSStefano Zampini i = mat_graph->nvtxs; 2574a0ba757dSStefano 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); 2575a0ba757dSStefano Zampini ierr = PetscMalloc3(i,PetscInt,&mat_graph->which_dof,i,PetscBool,&mat_graph->touched,i,PetscInt,&queue_in_global_numbering);CHKERRQ(ierr); 2576a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->where,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2577a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->count,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2578a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->which_dof,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 2579a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->queue,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 25803828260eSStefano Zampini ierr = PetscMemzero(mat_graph->cptr,(mat_graph->nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 2581a0ba757dSStefano Zampini 25829c0446d6SStefano Zampini /* Setting dofs splitting in mat_graph->which_dof */ 25839c0446d6SStefano Zampini if(pcbddc->n_ISForDofs) { /* get information about dofs' splitting if provided by the user */ 25849c0446d6SStefano Zampini PetscInt *is_indices; 25859c0446d6SStefano Zampini PetscInt is_size; 25869c0446d6SStefano Zampini for(i=0;i<pcbddc->n_ISForDofs;i++) { 25879c0446d6SStefano Zampini ierr = ISGetSize(pcbddc->ISForDofs[i],&is_size);CHKERRQ(ierr); 25889c0446d6SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofs[i],(const PetscInt**)&is_indices);CHKERRQ(ierr); 25899c0446d6SStefano Zampini for(j=0;j<is_size;j++) { 25909c0446d6SStefano Zampini mat_graph->which_dof[is_indices[j]]=i; 25919c0446d6SStefano Zampini } 25929c0446d6SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofs[i],(const PetscInt**)&is_indices);CHKERRQ(ierr); 25939c0446d6SStefano Zampini } 25943b03a366Sstefano_zampini /* use mat block size as vertex size */ 25953b03a366Sstefano_zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 25963b03a366Sstefano_zampini } else { /* otherwise it assumes a constant block size */ 2597a0ba757dSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 25980c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs/bs;i++) { 25990c7d97c5SJed Brown for(s=0;s<bs;s++) { 26000c7d97c5SJed Brown mat_graph->which_dof[i*bs+s]=s; 26010c7d97c5SJed Brown } 26020c7d97c5SJed Brown } 26033b03a366Sstefano_zampini vertex_size=1; 26049c0446d6SStefano Zampini } 26053b03a366Sstefano_zampini /* count number of neigh per node */ 26060c7d97c5SJed Brown total_counts=0; 26073b03a366Sstefano_zampini for(i=1;i<pcis->n_neigh;i++){ 26080c7d97c5SJed Brown s=pcis->n_shared[i]; 26090c7d97c5SJed Brown total_counts+=s; 261053cdbc3dSStefano Zampini for(j=0;j<s;j++){ 26110c7d97c5SJed Brown mat_graph->count[pcis->shared[i][j]] += 1; 26120c7d97c5SJed Brown } 26130c7d97c5SJed Brown } 26143b03a366Sstefano_zampini /* Take into account Neumann data -> it increments number of sharing subdomains for all but faces nodes lying on the interface */ 261536e030ebSStefano Zampini ierr = PCBDDCGetNeumannBoundaries(pc,&used_IS);CHKERRQ(ierr); 2616da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 2617da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 261836e030ebSStefano Zampini if(used_IS) { 261936e030ebSStefano Zampini ierr = ISGetSize(used_IS,&neumann_bsize);CHKERRQ(ierr); 262036e030ebSStefano Zampini ierr = ISGetIndices(used_IS,&neumann_nodes);CHKERRQ(ierr); 262153cdbc3dSStefano Zampini for(i=0;i<neumann_bsize;i++){ 262253cdbc3dSStefano Zampini iindex = neumann_nodes[i]; 2623da1bb401SStefano Zampini if(mat_graph->count[iindex] > 1 && array[iindex]==0.0){ 262453cdbc3dSStefano Zampini mat_graph->count[iindex]+=1; 26250c7d97c5SJed Brown total_counts++; 2626da1bb401SStefano Zampini array[iindex]=array[iindex]+1.0; 2627da1bb401SStefano Zampini } else if(array[iindex]>0.0) { 2628da1bb401SStefano 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); 26290c7d97c5SJed Brown } 26300c7d97c5SJed Brown } 26310c7d97c5SJed Brown } 2632da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 2633da1bb401SStefano Zampini /* allocate space for storing the set of neighbours for each node */ 2634da1bb401SStefano Zampini ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt*),&mat_graph->neighbours_set);CHKERRQ(ierr); 2635da1bb401SStefano Zampini if(mat_graph->nvtxs) { ierr = PetscMalloc(total_counts*sizeof(PetscInt),&mat_graph->neighbours_set[0]);CHKERRQ(ierr); } 2636da1bb401SStefano 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]; 2637a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->count,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 26383b03a366Sstefano_zampini for(i=1;i<pcis->n_neigh;i++){ 26390c7d97c5SJed Brown s=pcis->n_shared[i]; 26400c7d97c5SJed Brown for(j=0;j<s;j++) { 26410c7d97c5SJed Brown k=pcis->shared[i][j]; 2642da1bb401SStefano Zampini mat_graph->neighbours_set[k][mat_graph->count[k]] = pcis->neigh[i]; 26430c7d97c5SJed Brown mat_graph->count[k]+=1; 26440c7d97c5SJed Brown } 26450c7d97c5SJed Brown } 2646da1bb401SStefano Zampini /* Check consistency of Neumann nodes */ 2647da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 2648da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2649da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2650da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2651da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2652da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 26533b03a366Sstefano_zampini /* set -1 fake neighbour to mimic Neumann boundary */ 265436e030ebSStefano Zampini if(used_IS) { 265553cdbc3dSStefano Zampini for(i=0;i<neumann_bsize;i++){ 265653cdbc3dSStefano Zampini iindex = neumann_nodes[i]; 26573b03a366Sstefano_zampini if(mat_graph->count[iindex] > 1){ 2658da1bb401SStefano Zampini if(mat_graph->count[iindex]+1 != (PetscInt)array[iindex]) { 2659da1bb401SStefano 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]); 2660da1bb401SStefano Zampini } 2661da1bb401SStefano Zampini mat_graph->neighbours_set[iindex][mat_graph->count[iindex]] = -1; 266253cdbc3dSStefano Zampini mat_graph->count[iindex]+=1; 26630c7d97c5SJed Brown } 26640c7d97c5SJed Brown } 266536e030ebSStefano Zampini ierr = ISRestoreIndices(used_IS,&neumann_nodes);CHKERRQ(ierr); 26660c7d97c5SJed Brown } 2667da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 2668da1bb401SStefano Zampini /* sort set of sharing subdomains */ 2669da1bb401SStefano Zampini for(i=0;i<mat_graph->nvtxs;i++) { ierr = PetscSortInt(mat_graph->count[i],mat_graph->neighbours_set[i]);CHKERRQ(ierr); } 26703b03a366Sstefano_zampini /* remove interior nodes and dirichlet boundary nodes from the next search into the graph */ 2671da1bb401SStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){mat_graph->touched[i]=PETSC_FALSE;} 2672da1bb401SStefano Zampini nodes_touched=0; 267336e030ebSStefano Zampini ierr = PCBDDCGetDirichletBoundaries(pc,&used_IS);CHKERRQ(ierr); 2674da1bb401SStefano Zampini ierr = VecSet(pcis->vec2_N,0.0);CHKERRQ(ierr); 2675da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 2676da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 2677da1bb401SStefano Zampini if(used_IS) { 2678da1bb401SStefano Zampini ierr = ISGetSize(used_IS,&dirichlet_bsize);CHKERRQ(ierr); 2679da1bb401SStefano Zampini if(dirichlet_bsize && matis->pure_neumann) { 2680da1bb401SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Dirichlet boundaries are intended to be used with matrices with zeroed rows!\n"); 2681da1bb401SStefano Zampini } 2682da1bb401SStefano Zampini ierr = ISGetIndices(used_IS,&dirichlet_nodes);CHKERRQ(ierr); 2683da1bb401SStefano Zampini for(i=0;i<dirichlet_bsize;i++){ 2684da1bb401SStefano Zampini iindex=dirichlet_nodes[i]; 2685da1bb401SStefano Zampini if(mat_graph->count[iindex] && !mat_graph->touched[iindex]) { 2686da1bb401SStefano Zampini if(array[iindex]>0.0) { 2687da1bb401SStefano 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); 2688da1bb401SStefano Zampini } 2689da1bb401SStefano Zampini mat_graph->touched[iindex]=PETSC_TRUE; 2690da1bb401SStefano Zampini mat_graph->where[iindex]=0; 2691da1bb401SStefano Zampini nodes_touched++; 2692da1bb401SStefano Zampini array2[iindex]=array2[iindex]+1.0; 2693da1bb401SStefano Zampini } 2694da1bb401SStefano Zampini } 2695da1bb401SStefano Zampini ierr = ISRestoreIndices(used_IS,&dirichlet_nodes);CHKERRQ(ierr); 2696da1bb401SStefano Zampini } 2697da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 2698da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 2699da1bb401SStefano Zampini /* Check consistency of Dirichlet nodes */ 2700da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 2701da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 2702da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2703da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2704da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2705da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2706da1bb401SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 2707da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec2_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2708da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec2_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2709da1bb401SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2710da1bb401SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2711da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 2712da1bb401SStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 271336e030ebSStefano Zampini if(used_IS) { 271436e030ebSStefano Zampini ierr = ISGetSize(used_IS,&dirichlet_bsize);CHKERRQ(ierr); 271536e030ebSStefano Zampini ierr = ISGetIndices(used_IS,&dirichlet_nodes);CHKERRQ(ierr); 27163b03a366Sstefano_zampini for(i=0;i<dirichlet_bsize;i++){ 2717da1bb401SStefano Zampini iindex=dirichlet_nodes[i]; 2718da1bb401SStefano Zampini if(array[iindex]>1.0 && array[iindex]!=array2[iindex] ) { 2719da1bb401SStefano 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]); 2720da1bb401SStefano Zampini } 27213b03a366Sstefano_zampini } 272236e030ebSStefano Zampini ierr = ISRestoreIndices(used_IS,&dirichlet_nodes);CHKERRQ(ierr); 27233b03a366Sstefano_zampini } 2724da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 2725da1bb401SStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 2726da1bb401SStefano Zampini 27270c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs;i++){ 27283b03a366Sstefano_zampini if(!mat_graph->count[i]){ /* interior nodes */ 27290c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 27300c7d97c5SJed Brown mat_graph->where[i]=0; 27310c7d97c5SJed Brown nodes_touched++; 27320c7d97c5SJed Brown } 27330c7d97c5SJed Brown } 27340c7d97c5SJed Brown mat_graph->ncmps = 0; 2735da1bb401SStefano Zampini i=0; 27360c7d97c5SJed Brown while(nodes_touched<mat_graph->nvtxs) { 2737a0ba757dSStefano Zampini /* find first untouched node in local ordering */ 27380c7d97c5SJed Brown while(mat_graph->touched[i]) i++; 27390c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 2740a0ba757dSStefano Zampini mat_graph->where[i]=where_values; 27410c7d97c5SJed Brown nodes_touched++; 2742a0ba757dSStefano Zampini /* now find all other nodes having the same set of sharing subdomains */ 27430c7d97c5SJed Brown for(j=i+1;j<mat_graph->nvtxs;j++){ 2744a0ba757dSStefano Zampini /* check for same number of sharing subdomains and dof number */ 2745da1bb401SStefano Zampini if(!mat_graph->touched[j] && mat_graph->count[i]==mat_graph->count[j] && mat_graph->which_dof[i] == mat_graph->which_dof[j] ){ 2746a0ba757dSStefano Zampini /* check for same set of sharing subdomains */ 27470c7d97c5SJed Brown same_set=PETSC_TRUE; 27480c7d97c5SJed Brown for(k=0;k<mat_graph->count[j];k++){ 2749da1bb401SStefano Zampini if(mat_graph->neighbours_set[i][k]!=mat_graph->neighbours_set[j][k]) { 27500c7d97c5SJed Brown same_set=PETSC_FALSE; 27510c7d97c5SJed Brown } 27520c7d97c5SJed Brown } 2753a0ba757dSStefano Zampini /* I found a friend of mine */ 27540c7d97c5SJed Brown if(same_set) { 2755a0ba757dSStefano Zampini mat_graph->where[j]=where_values; 27560c7d97c5SJed Brown mat_graph->touched[j]=PETSC_TRUE; 27570c7d97c5SJed Brown nodes_touched++; 27580c7d97c5SJed Brown } 27590c7d97c5SJed Brown } 27600c7d97c5SJed Brown } 2761a0ba757dSStefano Zampini where_values++; 27620c7d97c5SJed Brown } 2763a0ba757dSStefano Zampini where_values--; if(where_values<0) where_values=0; 2764a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscMPIInt),&mat_graph->where_ncmps);CHKERRQ(ierr); 2765a0ba757dSStefano Zampini /* Find connected components defined on the shared interface */ 2766a0ba757dSStefano Zampini if(where_values) { 2767a0ba757dSStefano Zampini ierr = PCBDDCFindConnectedComponents(mat_graph, where_values); 27683b03a366Sstefano_zampini /* For consistency among neughbouring procs, I need to sort (by global ordering) each connected component */ 2769a0ba757dSStefano Zampini for(i=0;i<mat_graph->ncmps;i++) { 2770a0ba757dSStefano 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); 2771a0ba757dSStefano 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); 2772a0ba757dSStefano Zampini } 2773a0ba757dSStefano Zampini } 2774a0ba757dSStefano Zampini /* check consistency of connected components among neighbouring subdomains -> it adapt them in case it is needed */ 2775a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 27763b03a366Sstefano_zampini /* We are not sure that two connected components will be the same among subdomains sharing a subset of local interface */ 27773b03a366Sstefano_zampini if(mat_graph->where_ncmps[i]>1) { 2778a0ba757dSStefano Zampini adapt_interface=1; 2779a0ba757dSStefano Zampini break; 2780a0ba757dSStefano Zampini } 2781a0ba757dSStefano Zampini } 2782a0ba757dSStefano Zampini ierr = MPI_Allreduce(&adapt_interface,&adapt_interface_reduced,1,MPIU_INT,MPI_LOR,interface_comm);CHKERRQ(ierr); 2783da1bb401SStefano Zampini if(pcbddc->dbg_flag && adapt_interface_reduced) { 2784da1bb401SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"Interface adapted\n");CHKERRQ(ierr); 2785da1bb401SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2786da1bb401SStefano Zampini } 2787a0ba757dSStefano Zampini if(where_values && adapt_interface_reduced) { 27880c7d97c5SJed Brown 27893b03a366Sstefano_zampini 2790a0ba757dSStefano Zampini PetscInt sum_requests=0,my_rank; 2791a0ba757dSStefano Zampini PetscInt buffer_size,start_of_recv,size_of_recv,start_of_send; 2792a0ba757dSStefano Zampini PetscInt temp_buffer_size,ins_val,global_where_counter; 2793a0ba757dSStefano Zampini PetscInt *cum_recv_counts; 2794a0ba757dSStefano Zampini PetscInt *where_to_nodes_indices; 2795a0ba757dSStefano Zampini PetscInt *petsc_buffer; 2796a0ba757dSStefano Zampini PetscMPIInt *recv_buffer; 2797a0ba757dSStefano Zampini PetscMPIInt *recv_buffer_where; 2798a0ba757dSStefano Zampini PetscMPIInt *send_buffer; 2799a0ba757dSStefano Zampini PetscMPIInt size_of_send; 2800a0ba757dSStefano Zampini PetscInt *sizes_of_sends; 2801a0ba757dSStefano Zampini MPI_Request *send_requests; 2802a0ba757dSStefano Zampini MPI_Request *recv_requests; 2803a0ba757dSStefano Zampini PetscInt *where_cc_adapt; 2804a0ba757dSStefano Zampini PetscInt **temp_buffer; 2805a0ba757dSStefano Zampini PetscInt *nodes_to_temp_buffer_indices; 2806a0ba757dSStefano Zampini PetscInt *add_to_where; 2807a0ba757dSStefano Zampini 2808a0ba757dSStefano Zampini ierr = MPI_Comm_rank(interface_comm,&my_rank);CHKERRQ(ierr); 2809a0ba757dSStefano Zampini ierr = PetscMalloc((where_values+1)*sizeof(PetscInt),&cum_recv_counts);CHKERRQ(ierr); 2810a0ba757dSStefano Zampini ierr = PetscMemzero(cum_recv_counts,(where_values+1)*sizeof(PetscInt));CHKERRQ(ierr); 2811a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&where_to_nodes_indices);CHKERRQ(ierr); 2812a0ba757dSStefano Zampini /* first count how many neighbours per connected component I will receive from */ 2813a0ba757dSStefano Zampini cum_recv_counts[0]=0; 2814a0ba757dSStefano Zampini for(i=1;i<where_values+1;i++){ 2815a0ba757dSStefano Zampini j=0; 2816a0ba757dSStefano Zampini while(mat_graph->where[j] != i) j++; 2817a0ba757dSStefano Zampini where_to_nodes_indices[i-1]=j; 2818da1bb401SStefano 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 */ 28193b03a366Sstefano_zampini else { cum_recv_counts[i]=cum_recv_counts[i-1]+mat_graph->count[j]-1; } 2820a0ba757dSStefano Zampini } 2821a0ba757dSStefano Zampini buffer_size=2*cum_recv_counts[where_values]+mat_graph->nvtxs; 2822a0ba757dSStefano Zampini ierr = PetscMalloc(2*cum_recv_counts[where_values]*sizeof(PetscMPIInt),&recv_buffer_where);CHKERRQ(ierr); 2823a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscMPIInt),&send_buffer);CHKERRQ(ierr); 2824a0ba757dSStefano Zampini ierr = PetscMalloc(cum_recv_counts[where_values]*sizeof(MPI_Request),&send_requests);CHKERRQ(ierr); 2825a0ba757dSStefano Zampini ierr = PetscMalloc(cum_recv_counts[where_values]*sizeof(MPI_Request),&recv_requests);CHKERRQ(ierr); 2826a0ba757dSStefano Zampini for(i=0;i<cum_recv_counts[where_values];i++) { 2827a0ba757dSStefano Zampini send_requests[i]=MPI_REQUEST_NULL; 2828a0ba757dSStefano Zampini recv_requests[i]=MPI_REQUEST_NULL; 2829a0ba757dSStefano Zampini } 2830a0ba757dSStefano Zampini /* exchange with my neighbours the number of my connected components on the shared interface */ 2831a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2832a0ba757dSStefano Zampini j=where_to_nodes_indices[i]; 2833da1bb401SStefano Zampini k = (mat_graph->neighbours_set[j][0] == -1 ? 1 : 0); 2834a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2835da1bb401SStefano 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); 2836da1bb401SStefano 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); 2837a0ba757dSStefano Zampini sum_requests++; 2838a0ba757dSStefano Zampini } 2839a0ba757dSStefano Zampini } 2840a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2841a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2842a0ba757dSStefano Zampini /* determine the connected component I need to adapt */ 2843a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&where_cc_adapt);CHKERRQ(ierr); 2844a0ba757dSStefano Zampini ierr = PetscMemzero(where_cc_adapt,where_values*sizeof(PetscInt));CHKERRQ(ierr); 2845a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2846a0ba757dSStefano Zampini for(j=cum_recv_counts[i];j<cum_recv_counts[i+1];j++){ 28473b03a366Sstefano_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 */ 28483b03a366Sstefano_zampini if( mat_graph->where_ncmps[i]!=recv_buffer_where[j] || mat_graph->where_ncmps[i] > 1 ) { 2849a0ba757dSStefano Zampini where_cc_adapt[i]=PETSC_TRUE; 2850a0ba757dSStefano Zampini break; 2851a0ba757dSStefano Zampini } 2852a0ba757dSStefano Zampini } 2853a0ba757dSStefano Zampini } 2854a0ba757dSStefano Zampini /* now get from neighbours their ccs (in global numbering) and adapt them (in case it is needed) */ 2855a0ba757dSStefano Zampini /* first determine how much data to send (size of each queue plus the global indices) and communicate it to neighbours */ 2856a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscInt),&sizes_of_sends);CHKERRQ(ierr); 2857a0ba757dSStefano Zampini ierr = PetscMemzero(sizes_of_sends,where_values*sizeof(PetscInt));CHKERRQ(ierr); 2858a0ba757dSStefano Zampini sum_requests=0; 2859a0ba757dSStefano Zampini start_of_send=0; 2860a0ba757dSStefano Zampini start_of_recv=cum_recv_counts[where_values]; 2861a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 2862a0ba757dSStefano Zampini if(where_cc_adapt[i]) { 2863a0ba757dSStefano Zampini size_of_send=0; 2864a0ba757dSStefano Zampini for(j=i;j<mat_graph->ncmps;j++) { 2865a0ba757dSStefano Zampini if(mat_graph->where[mat_graph->queue[mat_graph->cptr[j]]] == i+1) { /* WARNING -> where values goes from 1 to where_values included */ 2866a0ba757dSStefano Zampini send_buffer[start_of_send+size_of_send]=mat_graph->cptr[j+1]-mat_graph->cptr[j]; 2867a0ba757dSStefano Zampini size_of_send+=1; 2868a0ba757dSStefano Zampini for(k=0;k<mat_graph->cptr[j+1]-mat_graph->cptr[j];k++) { 2869a0ba757dSStefano Zampini send_buffer[start_of_send+size_of_send+k]=queue_in_global_numbering[mat_graph->cptr[j]+k]; 2870a0ba757dSStefano Zampini } 2871a0ba757dSStefano Zampini size_of_send=size_of_send+mat_graph->cptr[j+1]-mat_graph->cptr[j]; 2872a0ba757dSStefano Zampini } 2873a0ba757dSStefano Zampini } 2874a0ba757dSStefano Zampini j = where_to_nodes_indices[i]; 2875da1bb401SStefano Zampini k = (mat_graph->neighbours_set[j][0] == -1 ? 1 : 0); 2876*11d8f4c2SStefano Zampini sizes_of_sends[i]=size_of_send; 2877a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2878*11d8f4c2SStefano Zampini ierr = MPI_Isend(&sizes_of_sends[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); 2879da1bb401SStefano 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); 2880a0ba757dSStefano Zampini sum_requests++; 2881a0ba757dSStefano Zampini } 2882a0ba757dSStefano Zampini start_of_send+=size_of_send; 2883a0ba757dSStefano Zampini } 2884a0ba757dSStefano Zampini } 2885a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2886a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2887a0ba757dSStefano Zampini buffer_size=0; 2888a0ba757dSStefano Zampini for(k=0;k<sum_requests;k++) { buffer_size+=recv_buffer_where[start_of_recv+k]; } 2889a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscMPIInt),&recv_buffer);CHKERRQ(ierr); 2890a0ba757dSStefano Zampini /* now exchange the data */ 2891a0ba757dSStefano Zampini start_of_recv=0; 2892a0ba757dSStefano Zampini start_of_send=0; 2893a0ba757dSStefano Zampini sum_requests=0; 2894a0ba757dSStefano Zampini for(i=0;i<where_values;i++) { 2895a0ba757dSStefano Zampini if(where_cc_adapt[i]) { 2896a0ba757dSStefano Zampini size_of_send = sizes_of_sends[i]; 2897a0ba757dSStefano Zampini j = where_to_nodes_indices[i]; 2898da1bb401SStefano Zampini k = (mat_graph->neighbours_set[j][0] == -1 ? 1 : 0); 2899a0ba757dSStefano Zampini for(;k<mat_graph->count[j];k++){ 2900da1bb401SStefano 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); 2901a0ba757dSStefano Zampini size_of_recv=recv_buffer_where[cum_recv_counts[where_values]+sum_requests]; 2902da1bb401SStefano 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); 2903a0ba757dSStefano Zampini start_of_recv+=size_of_recv; 2904a0ba757dSStefano Zampini sum_requests++; 2905a0ba757dSStefano Zampini } 2906a0ba757dSStefano Zampini start_of_send+=size_of_send; 2907a0ba757dSStefano Zampini } 2908a0ba757dSStefano Zampini } 2909a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2910a0ba757dSStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 2911a0ba757dSStefano Zampini ierr = PetscMalloc(buffer_size*sizeof(PetscInt),&petsc_buffer);CHKERRQ(ierr); 2912a0ba757dSStefano Zampini for(k=0;k<start_of_recv;k++) { petsc_buffer[k]=(PetscInt)recv_buffer[k]; } 2913a0ba757dSStefano Zampini for(j=0;j<buffer_size;) { 2914a0ba757dSStefano Zampini ierr = ISGlobalToLocalMappingApply(matis->mapping,IS_GTOLM_MASK,petsc_buffer[j],&petsc_buffer[j+1],&petsc_buffer[j],&petsc_buffer[j+1]);CHKERRQ(ierr); 2915a0ba757dSStefano Zampini k=petsc_buffer[j]+1; 2916a0ba757dSStefano Zampini j+=k; 2917a0ba757dSStefano Zampini } 2918a0ba757dSStefano Zampini sum_requests=cum_recv_counts[where_values]; 2919a0ba757dSStefano Zampini start_of_recv=0; 2920a0ba757dSStefano Zampini ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt),&nodes_to_temp_buffer_indices);CHKERRQ(ierr); 2921a0ba757dSStefano Zampini global_where_counter=0; 2922a0ba757dSStefano Zampini for(i=0;i<where_values;i++){ 2923a0ba757dSStefano Zampini if(where_cc_adapt[i]){ 2924a0ba757dSStefano Zampini temp_buffer_size=0; 2925a0ba757dSStefano Zampini /* find nodes on the shared interface we need to adapt */ 2926a0ba757dSStefano Zampini for(j=0;j<mat_graph->nvtxs;j++){ 2927a0ba757dSStefano Zampini if(mat_graph->where[j]==i+1) { 2928a0ba757dSStefano Zampini nodes_to_temp_buffer_indices[j]=temp_buffer_size; 2929a0ba757dSStefano Zampini temp_buffer_size++; 2930a0ba757dSStefano Zampini } else { 2931a0ba757dSStefano Zampini nodes_to_temp_buffer_indices[j]=-1; 2932a0ba757dSStefano Zampini } 2933a0ba757dSStefano Zampini } 2934a0ba757dSStefano Zampini /* allocate some temporary space */ 2935a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*sizeof(PetscInt*),&temp_buffer);CHKERRQ(ierr); 2936a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*(cum_recv_counts[i+1]-cum_recv_counts[i])*sizeof(PetscInt),&temp_buffer[0]);CHKERRQ(ierr); 2937a0ba757dSStefano Zampini ierr = PetscMemzero(temp_buffer[0],temp_buffer_size*(cum_recv_counts[i+1]-cum_recv_counts[i])*sizeof(PetscInt));CHKERRQ(ierr); 2938a0ba757dSStefano Zampini for(j=1;j<temp_buffer_size;j++){ 2939a0ba757dSStefano Zampini temp_buffer[j]=temp_buffer[j-1]+cum_recv_counts[i+1]-cum_recv_counts[i]; 2940a0ba757dSStefano Zampini } 2941a0ba757dSStefano Zampini /* analyze contributions from neighbouring subdomains for i-th conn comp 2942a0ba757dSStefano Zampini temp buffer structure: 2943a0ba757dSStefano Zampini supposing part of the interface has dimension 5 (global nodes 0,1,2,3,4) 2944a0ba757dSStefano Zampini 3 neighs procs with structured connected components: 2945a0ba757dSStefano Zampini neigh 0: [0 1 4], [2 3]; (2 connected components) 2946a0ba757dSStefano Zampini neigh 1: [0 1], [2 3 4]; (2 connected components) 2947a0ba757dSStefano Zampini neigh 2: [0 4], [1], [2 3]; (3 connected components) 2948a0ba757dSStefano Zampini tempbuffer (row-oriented) should be filled as: 2949a0ba757dSStefano Zampini [ 0, 0, 0; 2950a0ba757dSStefano Zampini 0, 0, 1; 2951a0ba757dSStefano Zampini 1, 1, 2; 2952a0ba757dSStefano Zampini 1, 1, 2; 2953a0ba757dSStefano Zampini 0, 1, 0; ]; 2954a0ba757dSStefano Zampini This way we can simply recover the resulting structure account for possible intersections of ccs among neighs. 2955a0ba757dSStefano Zampini The mat_graph->where array will be modified to reproduce the following 4 connected components [0], [1], [2 3], [4]; 2956a0ba757dSStefano Zampini */ 2957a0ba757dSStefano Zampini for(j=0;j<cum_recv_counts[i+1]-cum_recv_counts[i];j++) { 2958a0ba757dSStefano Zampini ins_val=0; 2959a0ba757dSStefano Zampini size_of_recv=recv_buffer_where[sum_requests]; /* total size of recv from neighs */ 2960a0ba757dSStefano Zampini for(buffer_size=0;buffer_size<size_of_recv;) { /* loop until all data from neighs has been taken into account */ 2961a0ba757dSStefano Zampini for(k=1;k<petsc_buffer[buffer_size+start_of_recv]+1;k++) { /* filling properly temp_buffer using data from a single recv */ 2962a0ba757dSStefano Zampini temp_buffer[ nodes_to_temp_buffer_indices[ petsc_buffer[ start_of_recv+buffer_size+k ] ] ][j]=ins_val; 2963a0ba757dSStefano Zampini } 2964a0ba757dSStefano Zampini buffer_size+=k; 2965a0ba757dSStefano Zampini ins_val++; 2966a0ba757dSStefano Zampini } 2967a0ba757dSStefano Zampini start_of_recv+=size_of_recv; 2968a0ba757dSStefano Zampini sum_requests++; 2969a0ba757dSStefano Zampini } 2970a0ba757dSStefano Zampini ierr = PetscMalloc(temp_buffer_size*sizeof(PetscInt),&add_to_where);CHKERRQ(ierr); 2971a0ba757dSStefano Zampini ierr = PetscMemzero(add_to_where,temp_buffer_size*sizeof(PetscInt));CHKERRQ(ierr); 2972a0ba757dSStefano Zampini for(j=0;j<temp_buffer_size;j++){ 2973a0ba757dSStefano Zampini if(!add_to_where[j]){ /* found a new cc */ 2974a0ba757dSStefano Zampini global_where_counter++; 2975a0ba757dSStefano Zampini add_to_where[j]=global_where_counter; 2976a0ba757dSStefano Zampini for(k=j+1;k<temp_buffer_size;k++){ /* check for other nodes in new cc */ 2977a0ba757dSStefano Zampini same_set=PETSC_TRUE; 2978a0ba757dSStefano Zampini for(s=0;s<cum_recv_counts[i+1]-cum_recv_counts[i];s++){ 2979a0ba757dSStefano Zampini if(temp_buffer[j][s]!=temp_buffer[k][s]) { 2980a0ba757dSStefano Zampini same_set=PETSC_FALSE; 2981a0ba757dSStefano Zampini break; 2982a0ba757dSStefano Zampini } 2983a0ba757dSStefano Zampini } 2984a0ba757dSStefano Zampini if(same_set) add_to_where[k]=global_where_counter; 2985a0ba757dSStefano Zampini } 2986a0ba757dSStefano Zampini } 2987a0ba757dSStefano Zampini } 2988a0ba757dSStefano Zampini /* insert new data in where array */ 2989a0ba757dSStefano Zampini temp_buffer_size=0; 2990a0ba757dSStefano Zampini for(j=0;j<mat_graph->nvtxs;j++){ 2991a0ba757dSStefano Zampini if(mat_graph->where[j]==i+1) { 2992a0ba757dSStefano Zampini mat_graph->where[j]=where_values+add_to_where[temp_buffer_size]; 2993a0ba757dSStefano Zampini temp_buffer_size++; 2994a0ba757dSStefano Zampini } 2995a0ba757dSStefano Zampini } 2996a0ba757dSStefano Zampini ierr = PetscFree(temp_buffer[0]);CHKERRQ(ierr); 2997a0ba757dSStefano Zampini ierr = PetscFree(temp_buffer);CHKERRQ(ierr); 2998a0ba757dSStefano Zampini ierr = PetscFree(add_to_where);CHKERRQ(ierr); 2999a0ba757dSStefano Zampini } 3000a0ba757dSStefano Zampini } 3001a0ba757dSStefano Zampini ierr = PetscFree(nodes_to_temp_buffer_indices);CHKERRQ(ierr); 3002a0ba757dSStefano Zampini ierr = PetscFree(sizes_of_sends);CHKERRQ(ierr); 3003a0ba757dSStefano Zampini ierr = PetscFree(send_requests);CHKERRQ(ierr); 3004a0ba757dSStefano Zampini ierr = PetscFree(recv_requests);CHKERRQ(ierr); 3005a0ba757dSStefano Zampini ierr = PetscFree(petsc_buffer);CHKERRQ(ierr); 3006a0ba757dSStefano Zampini ierr = PetscFree(recv_buffer);CHKERRQ(ierr); 3007a0ba757dSStefano Zampini ierr = PetscFree(recv_buffer_where);CHKERRQ(ierr); 3008a0ba757dSStefano Zampini ierr = PetscFree(send_buffer);CHKERRQ(ierr); 3009a0ba757dSStefano Zampini ierr = PetscFree(cum_recv_counts);CHKERRQ(ierr); 3010a0ba757dSStefano Zampini ierr = PetscFree(where_to_nodes_indices);CHKERRQ(ierr); 3011a0ba757dSStefano Zampini /* We are ready to evaluate consistent connected components on each part of the shared interface */ 3012a0ba757dSStefano Zampini if(global_where_counter) { 3013a0ba757dSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){ mat_graph->touched[i]=PETSC_FALSE; } 3014a0ba757dSStefano Zampini global_where_counter=0; 3015a0ba757dSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++){ 3016a0ba757dSStefano Zampini if(mat_graph->where[i] && !mat_graph->touched[i]) { 3017a0ba757dSStefano Zampini global_where_counter++; 3018a0ba757dSStefano Zampini for(j=i+1;j<mat_graph->nvtxs;j++){ 3019a0ba757dSStefano Zampini if(!mat_graph->touched[j] && mat_graph->where[j]==mat_graph->where[i]) { 3020a0ba757dSStefano Zampini mat_graph->where[j]=global_where_counter; 3021a0ba757dSStefano Zampini mat_graph->touched[j]=PETSC_TRUE; 3022a0ba757dSStefano Zampini } 3023a0ba757dSStefano Zampini } 3024a0ba757dSStefano Zampini mat_graph->where[i]=global_where_counter; 3025a0ba757dSStefano Zampini mat_graph->touched[i]=PETSC_TRUE; 3026a0ba757dSStefano Zampini } 3027a0ba757dSStefano Zampini } 3028a0ba757dSStefano Zampini where_values=global_where_counter; 3029a0ba757dSStefano Zampini } 3030a0ba757dSStefano Zampini if(global_where_counter) { 3031a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->cptr,(mat_graph->nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 3032a0ba757dSStefano Zampini ierr = PetscMemzero(mat_graph->queue,mat_graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 3033a0ba757dSStefano Zampini ierr = PetscFree(mat_graph->where_ncmps);CHKERRQ(ierr); 3034a0ba757dSStefano Zampini ierr = PetscMalloc(where_values*sizeof(PetscMPIInt),&mat_graph->where_ncmps);CHKERRQ(ierr); 3035a0ba757dSStefano Zampini ierr = PCBDDCFindConnectedComponents(mat_graph, where_values); 3036a0ba757dSStefano Zampini for(i=0;i<mat_graph->ncmps;i++) { 3037a0ba757dSStefano 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); 3038a0ba757dSStefano 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); 3039a0ba757dSStefano Zampini } 3040a0ba757dSStefano Zampini } 30413b03a366Sstefano_zampini } /* Finished adapting interface */ 30420c7d97c5SJed Brown PetscInt nfc=0; 30430c7d97c5SJed Brown PetscInt nec=0; 30440c7d97c5SJed Brown PetscInt nvc=0; 30453b03a366Sstefano_zampini PetscBool twodim_flag=PETSC_FALSE; 30460c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 30473b03a366Sstefano_zampini if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > vertex_size ){ 30483b03a366Sstefano_zampini if(mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]==1){ /* 1 neigh */ 30490c7d97c5SJed Brown nfc++; 30503b03a366Sstefano_zampini } else { /* note that nec will be zero in 2d */ 30513b03a366Sstefano_zampini nec++; 30523b03a366Sstefano_zampini } 30530c7d97c5SJed Brown } else { 30543b03a366Sstefano_zampini nvc+=mat_graph->cptr[i+1]-mat_graph->cptr[i]; 30553b03a366Sstefano_zampini } 30563b03a366Sstefano_zampini } 30573b03a366Sstefano_zampini 30583b03a366Sstefano_zampini if(!nec) { /* we are in a 2d case -> no faces, only edges */ 30593b03a366Sstefano_zampini nec = nfc; 30603b03a366Sstefano_zampini nfc = 0; 30613b03a366Sstefano_zampini twodim_flag = PETSC_TRUE; 30623b03a366Sstefano_zampini } 30633b03a366Sstefano_zampini /* allocate IS arrays for faces, edges. Vertices need a single index set. 30643b03a366Sstefano_zampini Reusing space allocated in mat_graph->where for creating IS objects */ 30653b03a366Sstefano_zampini if(!pcbddc->vertices_flag && !pcbddc->edges_flag) { 30663b03a366Sstefano_zampini ierr = PetscMalloc(nfc*sizeof(IS),&pcbddc->ISForFaces);CHKERRQ(ierr); 30673b03a366Sstefano_zampini use_faces=PETSC_TRUE; 30683b03a366Sstefano_zampini } 30693b03a366Sstefano_zampini if(!pcbddc->vertices_flag && !pcbddc->faces_flag) { 30703b03a366Sstefano_zampini ierr = PetscMalloc(nec*sizeof(IS),&pcbddc->ISForEdges);CHKERRQ(ierr); 30713b03a366Sstefano_zampini use_edges=PETSC_TRUE; 30723b03a366Sstefano_zampini } 30733b03a366Sstefano_zampini nfc=0; 30743b03a366Sstefano_zampini nec=0; 30753b03a366Sstefano_zampini for (i=0; i<mat_graph->ncmps; i++) { 30763b03a366Sstefano_zampini if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > vertex_size ){ 30773b03a366Sstefano_zampini for(j=0;j<mat_graph->cptr[i+1]-mat_graph->cptr[i];j++) { 30783b03a366Sstefano_zampini mat_graph->where[j]=mat_graph->queue[mat_graph->cptr[i]+j]; 30793b03a366Sstefano_zampini } 30803b03a366Sstefano_zampini if(mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]==1){ 30813b03a366Sstefano_zampini if(twodim_flag) { 30823b03a366Sstefano_zampini if(use_edges) { 30833b03a366Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,mat_graph->where,PETSC_COPY_VALUES,&pcbddc->ISForEdges[nec]);CHKERRQ(ierr); 30843b03a366Sstefano_zampini nec++; 30853b03a366Sstefano_zampini } 30863b03a366Sstefano_zampini } else { 30873b03a366Sstefano_zampini if(use_faces) { 30883b03a366Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,mat_graph->where,PETSC_COPY_VALUES,&pcbddc->ISForFaces[nfc]);CHKERRQ(ierr); 30893b03a366Sstefano_zampini nfc++; 30903b03a366Sstefano_zampini } 30913b03a366Sstefano_zampini } 30923b03a366Sstefano_zampini } else { 30933b03a366Sstefano_zampini if(use_edges) { 30943b03a366Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,mat_graph->where,PETSC_COPY_VALUES,&pcbddc->ISForEdges[nec]);CHKERRQ(ierr); 30950c7d97c5SJed Brown nec++; 30960c7d97c5SJed Brown } 30970c7d97c5SJed Brown } 30980c7d97c5SJed Brown } 30993b03a366Sstefano_zampini } 31003b03a366Sstefano_zampini pcbddc->n_ISForFaces=nfc; 31013b03a366Sstefano_zampini pcbddc->n_ISForEdges=nec; 31023b03a366Sstefano_zampini nvc=0; 31030c7d97c5SJed Brown if( !pcbddc->constraints_flag ) { 31043b03a366Sstefano_zampini for (i=0; i<mat_graph->ncmps; i++) { 31053b03a366Sstefano_zampini if( mat_graph->cptr[i+1]-mat_graph->cptr[i] <= vertex_size ){ 31063b03a366Sstefano_zampini for( j=mat_graph->cptr[i];j<mat_graph->cptr[i+1];j++) { 31073b03a366Sstefano_zampini mat_graph->where[nvc]=mat_graph->queue[j]; 31080c7d97c5SJed Brown nvc++; 31090c7d97c5SJed Brown } 31100c7d97c5SJed Brown } 31110c7d97c5SJed Brown } 31120c7d97c5SJed Brown } 3113a0ba757dSStefano Zampini /* sort vertex set (by local ordering) */ 31143b03a366Sstefano_zampini ierr = PetscSortInt(nvc,mat_graph->where);CHKERRQ(ierr); 31153b03a366Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nvc,mat_graph->where,PETSC_COPY_VALUES,&pcbddc->ISForVertices);CHKERRQ(ierr); 31160c7d97c5SJed Brown 3117e269702eSStefano Zampini if(pcbddc->dbg_flag) { 3118e269702eSStefano Zampini 3119d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3120d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Details from PCBDDCManageLocalBoundaries for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 3121d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3122a0ba757dSStefano Zampini /* ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Graph (adjacency structure) of local Neumann mat\n");CHKERRQ(ierr); 3123a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3124e269702eSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++) { 3125a0ba757dSStefano 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); 3126e269702eSStefano Zampini for(j=mat_graph->xadj[i];j<mat_graph->xadj[i+1];j++){ 3127a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d ",mat_graph->adjncy[j]);CHKERRQ(ierr); 3128e269702eSStefano Zampini } 3129a0ba757dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n--------------------------------------------------------------\n");CHKERRQ(ierr); 3130da1bb401SStefano Zampini }*/ 3131d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Matrix graph has %d connected components", mat_graph->ncmps);CHKERRQ(ierr); 31320c7d97c5SJed Brown for(i=0;i<mat_graph->ncmps;i++) { 31333b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\nDetails for connected component number %02d: size %04d, count %01d. Nodes follow.\n", 31343b03a366Sstefano_zampini i,mat_graph->cptr[i+1]-mat_graph->cptr[i],mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]);CHKERRQ(ierr); 3135da1bb401SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"subdomains: "); 3136da1bb401SStefano Zampini for (j=0;j<mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]; j++) { 3137da1bb401SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d ",mat_graph->neighbours_set[mat_graph->queue[mat_graph->cptr[i]]][j]); 3138da1bb401SStefano Zampini } 3139da1bb401SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n"); 31400c7d97c5SJed Brown for (j=mat_graph->cptr[i]; j<mat_graph->cptr[i+1]; j++){ 3141da1bb401SStefano Zampini /* ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d (%d), ",queue_in_global_numbering[j],mat_graph->queue[j]);CHKERRQ(ierr); */ 3142da1bb401SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d, ",mat_graph->queue[j]);CHKERRQ(ierr); 31430c7d97c5SJed Brown } 31440c7d97c5SJed Brown } 3145da1bb401SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n--------------------------------------------------------------\n");CHKERRQ(ierr); 31463b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local vertices\n",PetscGlobalRank,nvc);CHKERRQ(ierr); 31473b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local faces\n",PetscGlobalRank,nfc);CHKERRQ(ierr); 31483b03a366Sstefano_zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local edges\n",PetscGlobalRank,nec);CHKERRQ(ierr); 3149d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 31500c7d97c5SJed Brown } 31510c7d97c5SJed Brown 3152a0ba757dSStefano Zampini /* Free graph structure */ 31530c7d97c5SJed Brown if(mat_graph->nvtxs){ 3154a0ba757dSStefano Zampini ierr = PetscFree4(mat_graph->where,mat_graph->count,mat_graph->cptr,mat_graph->queue);CHKERRQ(ierr); 3155a0ba757dSStefano Zampini ierr = PetscFree3(mat_graph->which_dof,mat_graph->touched,queue_in_global_numbering);CHKERRQ(ierr); 3156a0ba757dSStefano Zampini ierr = PetscFree(mat_graph->where_ncmps);CHKERRQ(ierr); 31570c7d97c5SJed Brown } 31580c7d97c5SJed Brown 31590c7d97c5SJed Brown PetscFunctionReturn(0); 31600c7d97c5SJed Brown 31610c7d97c5SJed Brown } 31620c7d97c5SJed Brown 31630c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 31640c7d97c5SJed Brown 31650c7d97c5SJed Brown /* The following code has been adapted from function IsConnectedSubdomain contained 3166da1bb401SStefano Zampini in source file contig.c of METIS library (version 5.0.1) 3167da1bb401SStefano Zampini It finds connected components of each partition labeled from 1 to n_dist */ 31680c7d97c5SJed Brown 31690c7d97c5SJed Brown #undef __FUNCT__ 31700c7d97c5SJed Brown #define __FUNCT__ "PCBDDCFindConnectedComponents" 31719c0446d6SStefano Zampini static PetscErrorCode PCBDDCFindConnectedComponents(PCBDDCGraph graph, PetscInt n_dist ) 31720c7d97c5SJed Brown { 31730c7d97c5SJed Brown PetscInt i, j, k, nvtxs, first, last, nleft, ncmps,pid,cum_queue,n,ncmps_pid; 31740c7d97c5SJed Brown PetscInt *xadj, *adjncy, *where, *queue; 31750c7d97c5SJed Brown PetscInt *cptr; 31760c7d97c5SJed Brown PetscBool *touched; 31770c7d97c5SJed Brown 31780c7d97c5SJed Brown PetscFunctionBegin; 31790c7d97c5SJed Brown 31800c7d97c5SJed Brown nvtxs = graph->nvtxs; 31810c7d97c5SJed Brown xadj = graph->xadj; 31820c7d97c5SJed Brown adjncy = graph->adjncy; 31830c7d97c5SJed Brown where = graph->where; 31840c7d97c5SJed Brown touched = graph->touched; 31850c7d97c5SJed Brown queue = graph->queue; 31860c7d97c5SJed Brown cptr = graph->cptr; 31870c7d97c5SJed Brown 31880c7d97c5SJed Brown for (i=0; i<nvtxs; i++) 31890c7d97c5SJed Brown touched[i] = PETSC_FALSE; 31900c7d97c5SJed Brown 31910c7d97c5SJed Brown cum_queue=0; 31920c7d97c5SJed Brown ncmps=0; 31930c7d97c5SJed Brown 31940c7d97c5SJed Brown for(n=0; n<n_dist; n++) { 3195da1bb401SStefano Zampini pid = n+1; /* partition labeled by 0 is discarded */ 31960c7d97c5SJed Brown nleft = 0; 31970c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 31980c7d97c5SJed Brown if (where[i] == pid) 31990c7d97c5SJed Brown nleft++; 32000c7d97c5SJed Brown } 32010c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 32020c7d97c5SJed Brown if (where[i] == pid) 32030c7d97c5SJed Brown break; 32040c7d97c5SJed Brown } 32050c7d97c5SJed Brown touched[i] = PETSC_TRUE; 32060c7d97c5SJed Brown queue[cum_queue] = i; 32070c7d97c5SJed Brown first = 0; last = 1; 32080c7d97c5SJed Brown cptr[ncmps] = cum_queue; /* This actually points to queue */ 32090c7d97c5SJed Brown ncmps_pid = 0; 32100c7d97c5SJed Brown while (first != nleft) { 32110c7d97c5SJed Brown if (first == last) { /* Find another starting vertex */ 32120c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 32130c7d97c5SJed Brown ncmps_pid++; 32140c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 32150c7d97c5SJed Brown if (where[i] == pid && !touched[i]) 32160c7d97c5SJed Brown break; 32170c7d97c5SJed Brown } 32180c7d97c5SJed Brown queue[cum_queue+last] = i; 32190c7d97c5SJed Brown last++; 32200c7d97c5SJed Brown touched[i] = PETSC_TRUE; 32210c7d97c5SJed Brown } 32220c7d97c5SJed Brown i = queue[cum_queue+first]; 32230c7d97c5SJed Brown first++; 32240c7d97c5SJed Brown for (j=xadj[i]; j<xadj[i+1]; j++) { 32250c7d97c5SJed Brown k = adjncy[j]; 32260c7d97c5SJed Brown if (where[k] == pid && !touched[k]) { 32270c7d97c5SJed Brown queue[cum_queue+last] = k; 32280c7d97c5SJed Brown last++; 32290c7d97c5SJed Brown touched[k] = PETSC_TRUE; 32300c7d97c5SJed Brown } 32310c7d97c5SJed Brown } 32320c7d97c5SJed Brown } 32330c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 32340c7d97c5SJed Brown ncmps_pid++; 32350c7d97c5SJed Brown cum_queue=cptr[ncmps]; 3236a0ba757dSStefano Zampini graph->where_ncmps[n] = ncmps_pid; 32370c7d97c5SJed Brown } 32380c7d97c5SJed Brown graph->ncmps = ncmps; 32390c7d97c5SJed Brown 32400c7d97c5SJed Brown PetscFunctionReturn(0); 32410c7d97c5SJed Brown } 32420c7d97c5SJed Brown 3243