1af0996ceSBarry Smith #include <petsc/private/petscimpl.h> 2ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 3ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcstructs.h> 4674ae819SStefano Zampini 5674ae819SStefano Zampini #undef __FUNCT__ 61b968477SStefano Zampini #define __FUNCT__ "PCBDDCGraphGetDirichletDofs" 71b968477SStefano Zampini PetscErrorCode PCBDDCGraphGetDirichletDofs(PCBDDCGraph graph, IS* dirdofs) 81b968477SStefano Zampini { 91b968477SStefano Zampini PetscErrorCode ierr; 101b968477SStefano Zampini 111b968477SStefano Zampini PetscFunctionBegin; 12*a07ea27aSStefano Zampini if (graph->dirdofs) { 13*a07ea27aSStefano Zampini ierr = PetscObjectReference((PetscObject)graph->dirdofs);CHKERRQ(ierr); 14*a07ea27aSStefano Zampini } else if (graph->has_dirichlet) { 15*a07ea27aSStefano Zampini PetscInt i,size; 16*a07ea27aSStefano Zampini PetscInt *dirdofs_idxs; 17*a07ea27aSStefano Zampini 181b968477SStefano Zampini size = 0; 191b968477SStefano Zampini for (i=0;i<graph->nvtxs;i++) { 201b968477SStefano Zampini if (graph->special_dof[i] == PCBDDCGRAPH_DIRICHLET_MARK) size++; 211b968477SStefano Zampini } 221b968477SStefano Zampini 231b968477SStefano Zampini ierr = PetscMalloc1(size,&dirdofs_idxs);CHKERRQ(ierr); 241b968477SStefano Zampini size = 0; 251b968477SStefano Zampini for (i=0;i<graph->nvtxs;i++) { 261b968477SStefano Zampini if (graph->special_dof[i] == PCBDDCGRAPH_DIRICHLET_MARK) dirdofs_idxs[size++] = i; 271b968477SStefano Zampini } 28*a07ea27aSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)graph->l2gmap),size,dirdofs_idxs,PETSC_OWN_POINTER,&graph->dirdofs);CHKERRQ(ierr); 29*a07ea27aSStefano Zampini ierr = PetscObjectReference((PetscObject)graph->dirdofs);CHKERRQ(ierr); 301b968477SStefano Zampini } 31*a07ea27aSStefano Zampini *dirdofs = graph->dirdofs; 321b968477SStefano Zampini PetscFunctionReturn(0); 331b968477SStefano Zampini } 341b968477SStefano Zampini 351b968477SStefano Zampini #undef __FUNCT__ 36674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGraphASCIIView" 37e49050b4SStefano Zampini PetscErrorCode PCBDDCGraphASCIIView(PCBDDCGraph graph, PetscInt verbosity_level, PetscViewer viewer) 38674ae819SStefano Zampini { 392b510759SStefano Zampini PetscInt i,j,tabs; 4093fb5fd3SStefano Zampini PetscInt* queue_in_global_numbering; 41674ae819SStefano Zampini PetscErrorCode ierr; 42674ae819SStefano Zampini 43674ae819SStefano Zampini PetscFunctionBegin; 44674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 452b510759SStefano Zampini ierr = PetscViewerASCIIGetTab(viewer,&tabs);CHKERRQ(ierr); 46674ae819SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 47674ae819SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 48674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Local BDDC graph for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 49674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Number of vertices %d\n",graph->nvtxs);CHKERRQ(ierr); 50e49050b4SStefano Zampini if (verbosity_level > 1) { 51674ae819SStefano Zampini for (i=0;i<graph->nvtxs;i++) { 52674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d:\n",i);CHKERRQ(ierr); 53674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer," which_dof: %d\n",graph->which_dof[i]);CHKERRQ(ierr); 5474e413f5SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer," special_dof: %d\n",graph->special_dof[i]);CHKERRQ(ierr); 55674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer," neighbours: %d\n",graph->count[i]);CHKERRQ(ierr); 562b510759SStefano Zampini ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 57674ae819SStefano Zampini if (graph->count[i]) { 58674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer," set of neighbours:");CHKERRQ(ierr); 59674ae819SStefano Zampini for (j=0;j<graph->count[i];j++) { 60674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer," %d",graph->neighbours_set[i][j]);CHKERRQ(ierr); 61674ae819SStefano Zampini } 62674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 63674ae819SStefano Zampini } 642b510759SStefano Zampini ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr); 652b510759SStefano Zampini ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 6651b0f6cfSStefano Zampini if (graph->mirrors) { 6751b0f6cfSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer," mirrors: %d\n",graph->mirrors[i]);CHKERRQ(ierr); 6851b0f6cfSStefano Zampini if (graph->mirrors[i]) { 692b510759SStefano Zampini ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 7051b0f6cfSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer," set of mirrors:");CHKERRQ(ierr); 7151b0f6cfSStefano Zampini for (j=0;j<graph->mirrors[i];j++) { 7251b0f6cfSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer," %d",graph->mirrors_set[i][j]);CHKERRQ(ierr); 7351b0f6cfSStefano Zampini } 7451b0f6cfSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 752b510759SStefano Zampini ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr); 762b510759SStefano Zampini ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7751b0f6cfSStefano Zampini } 7851b0f6cfSStefano Zampini } 79e49050b4SStefano Zampini if (verbosity_level > 2) { 80674ae819SStefano Zampini if (graph->xadj && graph->adjncy) { 81674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer," local adj list:");CHKERRQ(ierr); 822b510759SStefano Zampini ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 83674ae819SStefano Zampini for (j=graph->xadj[i];j<graph->xadj[i+1];j++) { 84674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer," %d",graph->adjncy[j]);CHKERRQ(ierr); 85674ae819SStefano Zampini } 86674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 872b510759SStefano Zampini ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr); 882b510759SStefano Zampini ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 89ec1c413dSStefano Zampini } else { 90ec1c413dSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer," no adj info\n");CHKERRQ(ierr); 91674ae819SStefano Zampini } 92e49050b4SStefano Zampini } 93674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer," interface subset id: %d\n",graph->subset[i]);CHKERRQ(ierr); 94674ae819SStefano Zampini if (graph->subset[i] && graph->subset_ncc) { 95674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer," ncc for subset: %d\n",graph->subset_ncc[graph->subset[i]-1]);CHKERRQ(ierr); 96674ae819SStefano Zampini } 97674ae819SStefano Zampini } 98e49050b4SStefano Zampini } 99674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Total number of connected components %d\n",graph->ncc);CHKERRQ(ierr); 100785e854fSJed Brown ierr = PetscMalloc1(graph->cptr[graph->ncc],&queue_in_global_numbering);CHKERRQ(ierr); 10193fb5fd3SStefano Zampini ierr = ISLocalToGlobalMappingApply(graph->l2gmap,graph->cptr[graph->ncc],graph->queue,queue_in_global_numbering);CHKERRQ(ierr); 102674ae819SStefano Zampini for (i=0;i<graph->ncc;i++) { 1031ce3d396SStefano Zampini PetscInt node_num=graph->queue[graph->cptr[i]]; 1041ce3d396SStefano Zampini PetscBool printcc = PETSC_FALSE; 105674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer," %d (neighs:",i);CHKERRQ(ierr); 1062b510759SStefano Zampini ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 107674ae819SStefano Zampini for (j=0;j<graph->count[node_num];j++) { 108674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer," %d",graph->neighbours_set[node_num][j]);CHKERRQ(ierr); 109674ae819SStefano Zampini } 110674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"):");CHKERRQ(ierr); 1111ce3d396SStefano Zampini if (verbosity_level > 1) { 1121ce3d396SStefano Zampini printcc = PETSC_TRUE; 113e635b14bSStefano Zampini } else if (graph->count[node_num] > 1 || (graph->count[node_num] == 1 && graph->special_dof[node_num] == PCBDDCGRAPH_NEUMANN_MARK)) { 1141ce3d396SStefano Zampini printcc = PETSC_TRUE; 1151ce3d396SStefano Zampini } 1161ce3d396SStefano Zampini if (printcc) { 117674ae819SStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 11893fb5fd3SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer," %d (%d)",graph->queue[j],queue_in_global_numbering[j]);CHKERRQ(ierr); 119674ae819SStefano Zampini } 1201ce3d396SStefano Zampini } 121674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 1222b510759SStefano Zampini ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr); 1232b510759SStefano Zampini ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 124674ae819SStefano Zampini } 12593fb5fd3SStefano Zampini ierr = PetscFree(queue_in_global_numbering);CHKERRQ(ierr); 126e49050b4SStefano Zampini if (graph->custom_minimal_size > 1 && verbosity_level > 1) { 127674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Custom minimal size %d\n",graph->custom_minimal_size);CHKERRQ(ierr); 128674ae819SStefano Zampini } 129674ae819SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 130674ae819SStefano Zampini PetscFunctionReturn(0); 131674ae819SStefano Zampini } 132674ae819SStefano Zampini 133674ae819SStefano Zampini #undef __FUNCT__ 134674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGraphGetCandidatesIS" 135a873d5d0SStefano Zampini PetscErrorCode PCBDDCGraphGetCandidatesIS(PCBDDCGraph graph, PetscInt *n_faces, IS *FacesIS[], PetscInt *n_edges, IS *EdgesIS[], IS *VerticesIS) 136674ae819SStefano Zampini { 137674ae819SStefano Zampini IS *ISForFaces,*ISForEdges,ISForVertices; 138adfc4fb2SStefano Zampini PetscInt i,nfc,nec,nvc,*idx; 139674ae819SStefano Zampini PetscErrorCode ierr; 140674ae819SStefano Zampini 141674ae819SStefano Zampini PetscFunctionBegin; 142674ae819SStefano Zampini /* loop on ccs to evalute number of faces, edges and vertices */ 143674ae819SStefano Zampini nfc = 0; 144674ae819SStefano Zampini nec = 0; 145674ae819SStefano Zampini nvc = 0; 146674ae819SStefano Zampini for (i=0;i<graph->ncc;i++) { 1471e1f2d93SStefano Zampini PetscInt repdof = graph->queue[graph->cptr[i]]; 148674ae819SStefano Zampini if (graph->cptr[i+1]-graph->cptr[i] > graph->custom_minimal_size) { 149e635b14bSStefano Zampini if (graph->count[repdof] == 1 && graph->special_dof[repdof] != PCBDDCGRAPH_NEUMANN_MARK) { 150674ae819SStefano Zampini nfc++; 151674ae819SStefano Zampini } else { /* note that nec will be zero in 2d */ 152674ae819SStefano Zampini nec++; 153674ae819SStefano Zampini } 154674ae819SStefano Zampini } else { 155674ae819SStefano Zampini nvc += graph->cptr[i+1]-graph->cptr[i]; 156674ae819SStefano Zampini } 157674ae819SStefano Zampini } 158adfc4fb2SStefano Zampini 1598e4af1ccSStefano Zampini /* check if we are in 2D or 3D */ 1608e4af1ccSStefano Zampini if (graph->twodim) { /* we are in a 2D case -> edges are shared by 2 subregions and faces don't exist */ 161674ae819SStefano Zampini nec = nfc; 162674ae819SStefano Zampini nfc = 0; 163674ae819SStefano Zampini } 164adfc4fb2SStefano Zampini 165674ae819SStefano Zampini /* allocate IS arrays for faces, edges. Vertices need a single index set. */ 166cf5a6209SStefano Zampini if (FacesIS) { 167785e854fSJed Brown ierr = PetscMalloc1(nfc,&ISForFaces);CHKERRQ(ierr); 168cf5a6209SStefano Zampini } 169cf5a6209SStefano Zampini if (EdgesIS) { 170785e854fSJed Brown ierr = PetscMalloc1(nec,&ISForEdges);CHKERRQ(ierr); 171cf5a6209SStefano Zampini } 172cf5a6209SStefano Zampini if (VerticesIS) { 173785e854fSJed Brown ierr = PetscMalloc1(nvc,&idx);CHKERRQ(ierr); 174cf5a6209SStefano Zampini } 175cf5a6209SStefano Zampini 176674ae819SStefano Zampini /* loop on ccs to compute index sets for faces and edges */ 177acc113dbSStefano Zampini if (!graph->queue_sorted) { 178acc113dbSStefano Zampini PetscInt *queue_global; 179acc113dbSStefano Zampini 180acc113dbSStefano Zampini ierr = PetscMalloc1(graph->cptr[graph->ncc],&queue_global);CHKERRQ(ierr); 181acc113dbSStefano Zampini ierr = ISLocalToGlobalMappingApply(graph->l2gmap,graph->cptr[graph->ncc],graph->queue,queue_global);CHKERRQ(ierr); 182acc113dbSStefano Zampini for (i=0;i<graph->ncc;i++) { 183acc113dbSStefano Zampini ierr = PetscSortIntWithArray(graph->cptr[i+1]-graph->cptr[i],&queue_global[graph->cptr[i]],&graph->queue[graph->cptr[i]]);CHKERRQ(ierr); 184acc113dbSStefano Zampini } 185acc113dbSStefano Zampini ierr = PetscFree(queue_global);CHKERRQ(ierr); 186acc113dbSStefano Zampini graph->queue_sorted = PETSC_TRUE; 187acc113dbSStefano Zampini } 188674ae819SStefano Zampini nfc = 0; 189674ae819SStefano Zampini nec = 0; 190674ae819SStefano Zampini for (i=0;i<graph->ncc;i++) { 1911e1f2d93SStefano Zampini PetscInt repdof = graph->queue[graph->cptr[i]]; 192674ae819SStefano Zampini if (graph->cptr[i+1]-graph->cptr[i] > graph->custom_minimal_size) { 193e635b14bSStefano Zampini if (graph->count[repdof] == 1 && graph->special_dof[repdof] != PCBDDCGRAPH_NEUMANN_MARK) { 1948e4af1ccSStefano Zampini if (graph->twodim) { 195cf5a6209SStefano Zampini if (EdgesIS) { 196674ae819SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,graph->cptr[i+1]-graph->cptr[i],&graph->queue[graph->cptr[i]],PETSC_COPY_VALUES,&ISForEdges[nec]);CHKERRQ(ierr); 197cf5a6209SStefano Zampini } 198674ae819SStefano Zampini nec++; 199674ae819SStefano Zampini } else { 200cf5a6209SStefano Zampini if (FacesIS) { 201674ae819SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,graph->cptr[i+1]-graph->cptr[i],&graph->queue[graph->cptr[i]],PETSC_COPY_VALUES,&ISForFaces[nfc]);CHKERRQ(ierr); 202cf5a6209SStefano Zampini } 203674ae819SStefano Zampini nfc++; 204674ae819SStefano Zampini } 205674ae819SStefano Zampini } else { 206cf5a6209SStefano Zampini if (EdgesIS) { 207674ae819SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,graph->cptr[i+1]-graph->cptr[i],&graph->queue[graph->cptr[i]],PETSC_COPY_VALUES,&ISForEdges[nec]);CHKERRQ(ierr); 208cf5a6209SStefano Zampini } 209674ae819SStefano Zampini nec++; 210674ae819SStefano Zampini } 211674ae819SStefano Zampini } 212674ae819SStefano Zampini } 213674ae819SStefano Zampini /* index set for vertices */ 214cf5a6209SStefano Zampini if (VerticesIS) { 215b8ffe317SStefano Zampini nvc = 0; 216674ae819SStefano Zampini for (i=0;i<graph->ncc;i++) { 217674ae819SStefano Zampini if (graph->cptr[i+1]-graph->cptr[i] <= graph->custom_minimal_size) { 218adfc4fb2SStefano Zampini PetscInt j; 219adfc4fb2SStefano Zampini 220674ae819SStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 221674ae819SStefano Zampini idx[nvc]=graph->queue[j]; 222674ae819SStefano Zampini nvc++; 223674ae819SStefano Zampini } 224674ae819SStefano Zampini } 225674ae819SStefano Zampini } 226674ae819SStefano Zampini /* sort vertex set (by local ordering) */ 227674ae819SStefano Zampini ierr = PetscSortInt(nvc,idx);CHKERRQ(ierr); 228674ae819SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nvc,idx,PETSC_OWN_POINTER,&ISForVertices);CHKERRQ(ierr); 229674ae819SStefano Zampini } 230674ae819SStefano Zampini /* get back info */ 231a873d5d0SStefano Zampini if (n_faces) *n_faces = nfc; 232d7796978SStefano Zampini if (FacesIS) { 233674ae819SStefano Zampini *FacesIS = ISForFaces; 234d7796978SStefano Zampini } 235a873d5d0SStefano Zampini if (n_edges) *n_edges = nec; 236d7796978SStefano Zampini if (EdgesIS) { 237674ae819SStefano Zampini *EdgesIS = ISForEdges; 238d7796978SStefano Zampini } 239d7796978SStefano Zampini if (VerticesIS) { 240674ae819SStefano Zampini *VerticesIS = ISForVertices; 241d7796978SStefano Zampini } 242674ae819SStefano Zampini PetscFunctionReturn(0); 243674ae819SStefano Zampini } 244674ae819SStefano Zampini 245674ae819SStefano Zampini #undef __FUNCT__ 246674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGraphComputeConnectedComponents" 247674ae819SStefano Zampini PetscErrorCode PCBDDCGraphComputeConnectedComponents(PCBDDCGraph graph) 248674ae819SStefano Zampini { 2494a060362SStefano Zampini PetscBool adapt_interface_reduced; 250674ae819SStefano Zampini MPI_Comm interface_comm; 2514a060362SStefano Zampini PetscMPIInt size; 2528e4af1ccSStefano Zampini PetscInt i; 2538e4af1ccSStefano Zampini PetscBool twodim; 254674ae819SStefano Zampini PetscErrorCode ierr; 255674ae819SStefano Zampini 256674ae819SStefano Zampini PetscFunctionBegin; 257674ae819SStefano Zampini /* compute connected components locally */ 258674ae819SStefano Zampini ierr = PetscObjectGetComm((PetscObject)(graph->l2gmap),&interface_comm);CHKERRQ(ierr); 259674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponentsLocal(graph);CHKERRQ(ierr); 260674ae819SStefano Zampini /* check consistency of connected components among neighbouring subdomains -> it adapt them in case it is needed */ 2614a060362SStefano Zampini ierr = MPI_Comm_size(interface_comm,&size);CHKERRQ(ierr); 2624a060362SStefano Zampini adapt_interface_reduced = PETSC_FALSE; 2634a060362SStefano Zampini if (size > 1) { 2644a060362SStefano Zampini PetscInt i; 2654a060362SStefano Zampini PetscBool adapt_interface = PETSC_FALSE; 266674ae819SStefano Zampini for (i=0;i<graph->n_subsets;i++) { 267674ae819SStefano Zampini /* We are not sure that on a given subset of the local interface, 268674ae819SStefano Zampini with two connected components, the latters be the same among sharing subdomains */ 269674ae819SStefano Zampini if (graph->subset_ncc[i] > 1) { 2704a060362SStefano Zampini adapt_interface = PETSC_TRUE; 271674ae819SStefano Zampini break; 272674ae819SStefano Zampini } 273674ae819SStefano Zampini } 2744a060362SStefano Zampini ierr = MPI_Allreduce(&adapt_interface,&adapt_interface_reduced,1,MPIU_BOOL,MPI_LOR,interface_comm);CHKERRQ(ierr); 2754a060362SStefano Zampini } 276674ae819SStefano Zampini 277674ae819SStefano Zampini if (graph->n_subsets && adapt_interface_reduced) { 278ec1c413dSStefano Zampini /* old csr stuff */ 279ec1c413dSStefano Zampini PetscInt *aux_new_xadj,*new_xadj,*new_adjncy; 2805b1b9aeaSStefano Zampini PetscInt *old_xadj,*old_adjncy; 281ec1c413dSStefano Zampini PetscBT subset_cc_adapt; 282ec1c413dSStefano Zampini /* MPI */ 283ec1c413dSStefano Zampini MPI_Request *send_requests,*recv_requests; 284ec1c413dSStefano Zampini PetscInt *send_buffer,*recv_buffer; 285ec1c413dSStefano Zampini PetscInt sum_requests,start_of_recv,start_of_send; 286ec1c413dSStefano Zampini PetscInt *cum_recv_counts; 287ec1c413dSStefano Zampini /* others */ 288ec1c413dSStefano Zampini PetscInt *labels; 289ec1c413dSStefano Zampini PetscInt global_subset_counter; 290ec1c413dSStefano Zampini PetscInt j,k,s; 2915b1b9aeaSStefano Zampini 292674ae819SStefano Zampini /* Retrict adjacency graph using information from previously computed connected components */ 293785e854fSJed Brown ierr = PetscMalloc1(graph->nvtxs,&aux_new_xadj);CHKERRQ(ierr); 294674ae819SStefano Zampini for (i=0;i<graph->nvtxs;i++) { 295674ae819SStefano Zampini aux_new_xadj[i]=1; 296674ae819SStefano Zampini } 297674ae819SStefano Zampini for (i=0;i<graph->ncc;i++) { 298674ae819SStefano Zampini k = graph->cptr[i+1]-graph->cptr[i]; 299674ae819SStefano Zampini for (j=0;j<k;j++) { 300674ae819SStefano Zampini aux_new_xadj[graph->queue[graph->cptr[i]+j]]=k; 301674ae819SStefano Zampini } 302674ae819SStefano Zampini } 303674ae819SStefano Zampini j = 0; 304674ae819SStefano Zampini for (i=0;i<graph->nvtxs;i++) { 305674ae819SStefano Zampini j += aux_new_xadj[i]; 306674ae819SStefano Zampini } 307854ce69bSBarry Smith ierr = PetscMalloc1(graph->nvtxs+1,&new_xadj);CHKERRQ(ierr); 308785e854fSJed Brown ierr = PetscMalloc1(j,&new_adjncy);CHKERRQ(ierr); 309674ae819SStefano Zampini new_xadj[0]=0; 310674ae819SStefano Zampini for (i=0;i<graph->nvtxs;i++) { 311674ae819SStefano Zampini new_xadj[i+1]=new_xadj[i]+aux_new_xadj[i]; 312674ae819SStefano Zampini if (aux_new_xadj[i]==1) { 313674ae819SStefano Zampini new_adjncy[new_xadj[i]]=i; 314674ae819SStefano Zampini } 315674ae819SStefano Zampini } 316674ae819SStefano Zampini ierr = PetscFree(aux_new_xadj);CHKERRQ(ierr); 317ec1c413dSStefano Zampini ierr = PetscMalloc1(graph->nvtxs,&labels);CHKERRQ(ierr); 318ec1c413dSStefano Zampini ierr = PetscMemzero(labels,graph->nvtxs*sizeof(*labels));CHKERRQ(ierr); 319674ae819SStefano Zampini for (i=0;i<graph->ncc;i++) { 320674ae819SStefano Zampini k = graph->cptr[i+1]-graph->cptr[i]; 321674ae819SStefano Zampini for (j=0;j<k;j++) { 322674ae819SStefano Zampini ierr = PetscMemcpy(&new_adjncy[new_xadj[graph->queue[graph->cptr[i]+j]]],&graph->queue[graph->cptr[i]],k*sizeof(PetscInt));CHKERRQ(ierr); 323ec1c413dSStefano Zampini labels[graph->queue[graph->cptr[i]+j]] = i; 324674ae819SStefano Zampini } 325674ae819SStefano Zampini } 3265b1b9aeaSStefano Zampini /* set temporarly new CSR into graph */ 3275b1b9aeaSStefano Zampini old_xadj = graph->xadj; 3285b1b9aeaSStefano Zampini old_adjncy = graph->adjncy; 329674ae819SStefano Zampini graph->xadj = new_xadj; 330674ae819SStefano Zampini graph->adjncy = new_adjncy; 331674ae819SStefano Zampini /* allocate some space */ 332854ce69bSBarry Smith ierr = PetscMalloc1(graph->n_subsets+1,&cum_recv_counts);CHKERRQ(ierr); 333674ae819SStefano Zampini ierr = PetscMemzero(cum_recv_counts,(graph->n_subsets+1)*sizeof(*cum_recv_counts));CHKERRQ(ierr); 334674ae819SStefano Zampini /* first count how many neighbours per connected component I will receive from */ 335674ae819SStefano Zampini cum_recv_counts[0]=0; 336ec1c413dSStefano Zampini for (i=0;i<graph->n_subsets;i++) { 337ec1c413dSStefano Zampini cum_recv_counts[i+1]=cum_recv_counts[i]+graph->count[graph->subsets[i][0]]; 338674ae819SStefano Zampini } 339ec1c413dSStefano Zampini ierr = PetscMalloc1(cum_recv_counts[graph->n_subsets],&recv_buffer);CHKERRQ(ierr); 340ec1c413dSStefano Zampini ierr = PetscMalloc2(cum_recv_counts[graph->n_subsets],&send_requests,cum_recv_counts[graph->n_subsets],&recv_requests);CHKERRQ(ierr); 341674ae819SStefano Zampini for (i=0;i<cum_recv_counts[graph->n_subsets];i++) { 342674ae819SStefano Zampini send_requests[i]=MPI_REQUEST_NULL; 343674ae819SStefano Zampini recv_requests[i]=MPI_REQUEST_NULL; 344674ae819SStefano Zampini } 345ec1c413dSStefano Zampini /* exchange with my neighbours the number of my connected components on the subset of interface */ 346674ae819SStefano Zampini sum_requests = 0; 347674ae819SStefano Zampini for (i=0;i<graph->n_subsets;i++) { 348ec1c413dSStefano Zampini PetscMPIInt neigh,tag; 349ec1c413dSStefano Zampini 350ec1c413dSStefano Zampini j = graph->subsets[i][0]; 351ec1c413dSStefano Zampini ierr = PetscMPIIntCast(2*graph->subset_ref_node[i],&tag);CHKERRQ(ierr); 352674ae819SStefano Zampini for (k=0;k<graph->count[j];k++) { 353674ae819SStefano Zampini ierr = PetscMPIIntCast(graph->neighbours_set[j][k],&neigh);CHKERRQ(ierr); 354674ae819SStefano Zampini ierr = MPI_Isend(&graph->subset_ncc[i],1,MPIU_INT,neigh,tag,interface_comm,&send_requests[sum_requests]);CHKERRQ(ierr); 355ec1c413dSStefano Zampini ierr = MPI_Irecv(&recv_buffer[sum_requests],1,MPIU_INT,neigh,tag,interface_comm,&recv_requests[sum_requests]);CHKERRQ(ierr); 356674ae819SStefano Zampini sum_requests++; 357674ae819SStefano Zampini } 358674ae819SStefano Zampini } 359674ae819SStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 360674ae819SStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 361ec1c413dSStefano Zampini /* determine the subsets I have to adapt */ 362ec1c413dSStefano Zampini ierr = PetscBTCreate(graph->n_subsets,&subset_cc_adapt);CHKERRQ(ierr); 363ec1c413dSStefano Zampini ierr = PetscBTMemzero(graph->n_subsets,subset_cc_adapt);CHKERRQ(ierr); 364674ae819SStefano Zampini for (i=0;i<graph->n_subsets;i++) { 365674ae819SStefano Zampini for (j=cum_recv_counts[i];j<cum_recv_counts[i+1];j++){ 366ec1c413dSStefano Zampini /* adapt if more than one cc is present */ 367ec1c413dSStefano Zampini if (graph->subset_ncc[i] > 1 || recv_buffer[j] > 1) { 368ec1c413dSStefano Zampini ierr = PetscBTSet(subset_cc_adapt,i); 369674ae819SStefano Zampini break; 370674ae819SStefano Zampini } 371674ae819SStefano Zampini } 372674ae819SStefano Zampini } 373ec1c413dSStefano Zampini ierr = PetscFree(recv_buffer);CHKERRQ(ierr); 374ec1c413dSStefano Zampini /* determine send/recv buffers sizes */ 375ec1c413dSStefano Zampini j = 0; 376674ae819SStefano Zampini for (i=0;i<graph->n_subsets;i++) { 377ec1c413dSStefano Zampini if (PetscBTLookup(subset_cc_adapt,i)) { 378ec1c413dSStefano Zampini j += graph->subsets_size[i]; 379674ae819SStefano Zampini } 380674ae819SStefano Zampini } 381ec1c413dSStefano Zampini k = 0; 382674ae819SStefano Zampini for (i=0;i<graph->n_subsets;i++) { 383ec1c413dSStefano Zampini if (PetscBTLookup(subset_cc_adapt,i)) { 384ec1c413dSStefano Zampini k += (cum_recv_counts[i+1]-cum_recv_counts[i])*graph->subsets_size[i]; 385674ae819SStefano Zampini } 386674ae819SStefano Zampini } 387ec1c413dSStefano Zampini ierr = PetscMalloc2(j,&send_buffer,k,&recv_buffer);CHKERRQ(ierr); 388ec1c413dSStefano Zampini 389ec1c413dSStefano Zampini /* fill send buffer */ 390ec1c413dSStefano Zampini j = 0; 391ec1c413dSStefano Zampini for (i=0;i<graph->n_subsets;i++) { 392ec1c413dSStefano Zampini if (PetscBTLookup(subset_cc_adapt,i)) { 393ec1c413dSStefano Zampini for (k=0;k<graph->subsets_size[i];k++) { 394ec1c413dSStefano Zampini send_buffer[j++] = labels[graph->subsets[i][k]]; 395674ae819SStefano Zampini } 396674ae819SStefano Zampini } 397674ae819SStefano Zampini } 398ec1c413dSStefano Zampini ierr = PetscFree(labels);CHKERRQ(ierr); 399ec1c413dSStefano Zampini 400674ae819SStefano Zampini /* now exchange the data */ 401674ae819SStefano Zampini start_of_recv = 0; 402674ae819SStefano Zampini start_of_send = 0; 403674ae819SStefano Zampini sum_requests = 0; 404674ae819SStefano Zampini for (i=0;i<graph->n_subsets;i++) { 405ec1c413dSStefano Zampini if (PetscBTLookup(subset_cc_adapt,i)) { 406ec1c413dSStefano Zampini PetscMPIInt neigh,tag; 407ec1c413dSStefano Zampini PetscInt size_of_send = graph->subsets_size[i]; 408ec1c413dSStefano Zampini 409ec1c413dSStefano Zampini j = graph->subsets[i][0]; 410ec1c413dSStefano Zampini ierr = PetscMPIIntCast(2*graph->subset_ref_node[i]+1,&tag);CHKERRQ(ierr); 411674ae819SStefano Zampini for (k=0;k<graph->count[j];k++) { 412674ae819SStefano Zampini ierr = PetscMPIIntCast(graph->neighbours_set[j][k],&neigh);CHKERRQ(ierr); 413ec1c413dSStefano Zampini ierr = MPI_Isend(&send_buffer[start_of_send],size_of_send,MPIU_INT,neigh,tag,interface_comm,&send_requests[sum_requests]);CHKERRQ(ierr); 414ec1c413dSStefano Zampini ierr = MPI_Irecv(&recv_buffer[start_of_recv],size_of_send,MPIU_INT,neigh,tag,interface_comm,&recv_requests[sum_requests]);CHKERRQ(ierr); 415ec1c413dSStefano Zampini start_of_recv += size_of_send; 416674ae819SStefano Zampini sum_requests++; 417674ae819SStefano Zampini } 418674ae819SStefano Zampini start_of_send += size_of_send; 419674ae819SStefano Zampini } 420674ae819SStefano Zampini } 421674ae819SStefano Zampini ierr = MPI_Waitall(sum_requests,recv_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 422674ae819SStefano Zampini ierr = MPI_Waitall(sum_requests,send_requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 423ec1c413dSStefano Zampini ierr = PetscFree2(send_requests,recv_requests);CHKERRQ(ierr); 424d52c4852SStefano Zampini 425674ae819SStefano Zampini start_of_recv = 0; 426674ae819SStefano Zampini global_subset_counter = 0; 427674ae819SStefano Zampini for (i=0;i<graph->n_subsets;i++) { 428ec1c413dSStefano Zampini if (PetscBTLookup(subset_cc_adapt,i)) { 429ec1c413dSStefano Zampini PetscInt **temp_buffer,temp_buffer_size,*private_label; 430ec1c413dSStefano Zampini 431674ae819SStefano Zampini /* allocate some temporary space */ 432ec1c413dSStefano Zampini temp_buffer_size = graph->subsets_size[i]; 433785e854fSJed Brown ierr = PetscMalloc1(temp_buffer_size,&temp_buffer);CHKERRQ(ierr); 434785e854fSJed Brown ierr = PetscMalloc1(temp_buffer_size*(cum_recv_counts[i+1]-cum_recv_counts[i]),&temp_buffer[0]);CHKERRQ(ierr); 435674ae819SStefano Zampini ierr = PetscMemzero(temp_buffer[0],temp_buffer_size*(cum_recv_counts[i+1]-cum_recv_counts[i])*sizeof(PetscInt));CHKERRQ(ierr); 436674ae819SStefano Zampini for (j=1;j<temp_buffer_size;j++) { 437674ae819SStefano Zampini temp_buffer[j] = temp_buffer[j-1]+cum_recv_counts[i+1]-cum_recv_counts[i]; 438674ae819SStefano Zampini } 439ec1c413dSStefano Zampini /* analyze contributions from neighbouring subdomains for i-th subset 440674ae819SStefano Zampini temp buffer structure: 441ec1c413dSStefano Zampini supposing part of the interface has dimension 5 442ec1c413dSStefano Zampini e.g with global dofs 0,1,2,3,4, locally ordered on the current process as 0,4,3,1,2 443ec1c413dSStefano Zampini 3 neighs procs having connected components: 444ec1c413dSStefano Zampini neigh 0: [0 1 4], [2 3], labels [4,7] (2 connected components) 445ec1c413dSStefano Zampini neigh 1: [0 1], [2 3 4], labels [3 2] (2 connected components) 446ec1c413dSStefano Zampini neigh 2: [0 4], [1], [2 3], labels [1 5 6] (3 connected components) 447674ae819SStefano Zampini tempbuffer (row-oriented) will be filled as: 448ec1c413dSStefano Zampini [ 4, 3, 1; 449ec1c413dSStefano Zampini 4, 2, 1; 450ec1c413dSStefano Zampini 7, 2, 6; 451ec1c413dSStefano Zampini 4, 3, 5; 452ec1c413dSStefano Zampini 7, 2, 6; ]; 453674ae819SStefano Zampini This way we can simply find intersections of ccs among neighs. 454ec1c413dSStefano Zampini The graph->subset array will need to be modified. The output for the example is [0], [1], [2 3], [4]; 455674ae819SStefano Zampini */ 456674ae819SStefano Zampini for (j=0;j<cum_recv_counts[i+1]-cum_recv_counts[i];j++) { 457ec1c413dSStefano Zampini for (k=0;k<temp_buffer_size;k++) { 458ec1c413dSStefano Zampini temp_buffer[k][j] = recv_buffer[start_of_recv+k]; 459674ae819SStefano Zampini } 460ec1c413dSStefano Zampini start_of_recv += temp_buffer_size; 461674ae819SStefano Zampini } 462ec1c413dSStefano Zampini ierr = PetscMalloc1(temp_buffer_size,&private_label);CHKERRQ(ierr); 463ec1c413dSStefano Zampini ierr = PetscMemzero(private_label,temp_buffer_size*sizeof(*private_label));CHKERRQ(ierr); 464674ae819SStefano Zampini for (j=0;j<temp_buffer_size;j++) { 465ec1c413dSStefano Zampini if (!private_label[j]) { /* found a new cc */ 466ec1c413dSStefano Zampini PetscBool same_set; 467ec1c413dSStefano Zampini 468674ae819SStefano Zampini global_subset_counter++; 469ec1c413dSStefano Zampini private_label[j] = global_subset_counter; 470674ae819SStefano Zampini for (k=j+1;k<temp_buffer_size;k++) { /* check for other nodes in new cc */ 471674ae819SStefano Zampini same_set = PETSC_TRUE; 472674ae819SStefano Zampini for (s=0;s<cum_recv_counts[i+1]-cum_recv_counts[i];s++) { 473674ae819SStefano Zampini if (temp_buffer[j][s] != temp_buffer[k][s]) { 474674ae819SStefano Zampini same_set = PETSC_FALSE; 475674ae819SStefano Zampini break; 476674ae819SStefano Zampini } 477674ae819SStefano Zampini } 478674ae819SStefano Zampini if (same_set) { 479ec1c413dSStefano Zampini private_label[k] = global_subset_counter; 480674ae819SStefano Zampini } 481674ae819SStefano Zampini } 482674ae819SStefano Zampini } 483674ae819SStefano Zampini } 484ec1c413dSStefano Zampini /* insert private labels in graph structure */ 485ec1c413dSStefano Zampini for (j=0;j<graph->subsets_size[i];j++) { 486ec1c413dSStefano Zampini graph->subset[graph->subsets[i][j]] = graph->n_subsets+private_label[j]; 487674ae819SStefano Zampini } 488ec1c413dSStefano Zampini ierr = PetscFree(private_label);CHKERRQ(ierr); 489674ae819SStefano Zampini ierr = PetscFree(temp_buffer[0]);CHKERRQ(ierr); 490674ae819SStefano Zampini ierr = PetscFree(temp_buffer);CHKERRQ(ierr); 491674ae819SStefano Zampini } 492674ae819SStefano Zampini } 49345b2a5aaSStefano Zampini ierr = PetscFree2(send_buffer,recv_buffer);CHKERRQ(ierr); 494674ae819SStefano Zampini ierr = PetscFree(cum_recv_counts);CHKERRQ(ierr); 495ec1c413dSStefano Zampini ierr = PetscBTDestroy(&subset_cc_adapt);CHKERRQ(ierr); 496ec1c413dSStefano Zampini /* We are ready to find for connected components which are consistent among neighbouring subdomains */ 497674ae819SStefano Zampini if (global_subset_counter) { 498df48933bSStefano Zampini ierr = PetscBTMemzero(graph->nvtxs,graph->touched);CHKERRQ(ierr); 499674ae819SStefano Zampini global_subset_counter = 0; 500674ae819SStefano Zampini for (i=0;i<graph->nvtxs;i++) { 501df48933bSStefano Zampini if (graph->subset[i] && !PetscBTLookup(graph->touched,i)) { 502674ae819SStefano Zampini global_subset_counter++; 503674ae819SStefano Zampini for (j=i+1;j<graph->nvtxs;j++) { 504df48933bSStefano Zampini if (!PetscBTLookup(graph->touched,j) && graph->subset[j]==graph->subset[i]) { 505674ae819SStefano Zampini graph->subset[j] = global_subset_counter; 506df48933bSStefano Zampini ierr = PetscBTSet(graph->touched,j);CHKERRQ(ierr); 507674ae819SStefano Zampini } 508674ae819SStefano Zampini } 509674ae819SStefano Zampini graph->subset[i] = global_subset_counter; 510df48933bSStefano Zampini ierr = PetscBTSet(graph->touched,i);CHKERRQ(ierr); 511674ae819SStefano Zampini } 512674ae819SStefano Zampini } 513674ae819SStefano Zampini /* refine connected components locally */ 514674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponentsLocal(graph);CHKERRQ(ierr); 515674ae819SStefano Zampini } 5165b1b9aeaSStefano Zampini /* restore original CSR graph of dofs */ 5175b1b9aeaSStefano Zampini ierr = PetscFree(new_xadj);CHKERRQ(ierr); 5185b1b9aeaSStefano Zampini ierr = PetscFree(new_adjncy);CHKERRQ(ierr); 5195b1b9aeaSStefano Zampini graph->xadj = old_xadj; 5205b1b9aeaSStefano Zampini graph->adjncy = old_adjncy; 521674ae819SStefano Zampini } 5228e4af1ccSStefano Zampini 5238e4af1ccSStefano Zampini /* Determine if we are in 2D or 3D */ 5248e4af1ccSStefano Zampini twodim = PETSC_TRUE; 5258e4af1ccSStefano Zampini for (i=0;i<graph->ncc;i++) { 5268e4af1ccSStefano Zampini PetscInt repdof = graph->queue[graph->cptr[i]]; 5278e4af1ccSStefano Zampini if (graph->cptr[i+1]-graph->cptr[i] > graph->custom_minimal_size) { 5288e4af1ccSStefano Zampini if (graph->count[repdof] > 1 || graph->special_dof[repdof] == PCBDDCGRAPH_NEUMANN_MARK) { 5298e4af1ccSStefano Zampini twodim = PETSC_FALSE; 5308e4af1ccSStefano Zampini break; 5318e4af1ccSStefano Zampini } 5328e4af1ccSStefano Zampini } 5338e4af1ccSStefano Zampini } 5348e4af1ccSStefano Zampini ierr = MPI_Allreduce(&twodim,&graph->twodim,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)graph->l2gmap));CHKERRQ(ierr); 535674ae819SStefano Zampini PetscFunctionReturn(0); 536674ae819SStefano Zampini } 537674ae819SStefano Zampini 538674ae819SStefano Zampini /* The following code has been adapted from function IsConnectedSubdomain contained 539674ae819SStefano Zampini in source file contig.c of METIS library (version 5.0.1) 540674ae819SStefano Zampini It finds connected components for each subset */ 541674ae819SStefano Zampini #undef __FUNCT__ 542674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGraphComputeConnectedComponentsLocal" 543674ae819SStefano Zampini PetscErrorCode PCBDDCGraphComputeConnectedComponentsLocal(PCBDDCGraph graph) 544674ae819SStefano Zampini { 545674ae819SStefano Zampini PetscInt i,j,k,first,last,nleft,ncc,pid,cum_queue,n,ncc_pid; 5464a060362SStefano Zampini PetscMPIInt size; 547674ae819SStefano Zampini PetscErrorCode ierr; 548674ae819SStefano Zampini 549674ae819SStefano Zampini PetscFunctionBegin; 550674ae819SStefano Zampini /* quiet return if no csr info is available */ 551674ae819SStefano Zampini if (!graph->xadj || !graph->adjncy) { 552674ae819SStefano Zampini PetscFunctionReturn(0); 553674ae819SStefano Zampini } 554674ae819SStefano Zampini 555674ae819SStefano Zampini /* reset any previous search of connected components */ 556df48933bSStefano Zampini ierr = PetscBTMemzero(graph->nvtxs,graph->touched);CHKERRQ(ierr); 557674ae819SStefano Zampini graph->n_subsets = 0; 5587babac9bSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)graph->l2gmap),&size);CHKERRQ(ierr); 5594a060362SStefano Zampini if (size == 1) { 560dc36bf05SStefano Zampini if (graph->nvtxs) { 5614a060362SStefano Zampini graph->n_subsets = 1; 5624a060362SStefano Zampini for (i=0;i<graph->nvtxs;i++) { 5634a060362SStefano Zampini graph->subset[i] = 1; 5644a060362SStefano Zampini } 565dc36bf05SStefano Zampini } 5664a060362SStefano Zampini } else { 567674ae819SStefano Zampini for (i=0;i<graph->nvtxs;i++) { 5680cf82fd6SStefano Zampini if (graph->special_dof[i] == PCBDDCGRAPH_DIRICHLET_MARK || !graph->count[i]) { 569df48933bSStefano Zampini ierr = PetscBTSet(graph->touched,i);CHKERRQ(ierr); 570674ae819SStefano Zampini graph->subset[i] = 0; 571674ae819SStefano Zampini } 572674ae819SStefano Zampini graph->n_subsets = PetscMax(graph->n_subsets,graph->subset[i]); 573674ae819SStefano Zampini } 5744a060362SStefano Zampini } 575674ae819SStefano Zampini ierr = PetscFree(graph->subset_ncc);CHKERRQ(ierr); 576785e854fSJed Brown ierr = PetscMalloc1(graph->n_subsets,&graph->subset_ncc);CHKERRQ(ierr); 577674ae819SStefano Zampini 578674ae819SStefano Zampini /* begin search for connected components */ 579674ae819SStefano Zampini cum_queue = 0; 580674ae819SStefano Zampini ncc = 0; 581674ae819SStefano Zampini for (n=0;n<graph->n_subsets;n++) { 582674ae819SStefano Zampini pid = n+1; /* partition labeled by 0 is discarded */ 583674ae819SStefano Zampini nleft = 0; 584674ae819SStefano Zampini for (i=0;i<graph->nvtxs;i++) { 585674ae819SStefano Zampini if (graph->subset[i] == pid) { 586674ae819SStefano Zampini nleft++; 587674ae819SStefano Zampini } 588674ae819SStefano Zampini } 589674ae819SStefano Zampini for (i=0; i<graph->nvtxs; i++) { 590674ae819SStefano Zampini if (graph->subset[i] == pid) { 591674ae819SStefano Zampini break; 592674ae819SStefano Zampini } 593674ae819SStefano Zampini } 594df48933bSStefano Zampini ierr = PetscBTSet(graph->touched,i);CHKERRQ(ierr); 595674ae819SStefano Zampini graph->queue[cum_queue] = i; 596674ae819SStefano Zampini first = 0; 597674ae819SStefano Zampini last = 1; 598674ae819SStefano Zampini graph->cptr[ncc] = cum_queue; 599674ae819SStefano Zampini ncc_pid = 0; 600674ae819SStefano Zampini while (first != nleft) { 601674ae819SStefano Zampini if (first == last) { 602674ae819SStefano Zampini graph->cptr[++ncc] = first+cum_queue; 603674ae819SStefano Zampini ncc_pid++; 604df48933bSStefano Zampini for (i=0; i<graph->nvtxs; i++) { /* TODO-> use a while! */ 605df48933bSStefano Zampini if (graph->subset[i] == pid && !PetscBTLookup(graph->touched,i)) { 606674ae819SStefano Zampini break; 607674ae819SStefano Zampini } 608674ae819SStefano Zampini } 609674ae819SStefano Zampini graph->queue[cum_queue+last] = i; 610674ae819SStefano Zampini last++; 611df48933bSStefano Zampini ierr = PetscBTSet(graph->touched,i);CHKERRQ(ierr); 612674ae819SStefano Zampini } 613674ae819SStefano Zampini i = graph->queue[cum_queue+first]; 614674ae819SStefano Zampini first++; 615674ae819SStefano Zampini for (j=graph->xadj[i];j<graph->xadj[i+1];j++) { 616674ae819SStefano Zampini k = graph->adjncy[j]; 617df48933bSStefano Zampini if (graph->subset[k] == pid && !PetscBTLookup(graph->touched,k)) { 618674ae819SStefano Zampini graph->queue[cum_queue+last] = k; 619674ae819SStefano Zampini last++; 620df48933bSStefano Zampini ierr = PetscBTSet(graph->touched,k);CHKERRQ(ierr); 621674ae819SStefano Zampini } 622674ae819SStefano Zampini } 623674ae819SStefano Zampini } 624674ae819SStefano Zampini graph->cptr[++ncc] = first+cum_queue; 625674ae819SStefano Zampini ncc_pid++; 626674ae819SStefano Zampini cum_queue = graph->cptr[ncc]; 627674ae819SStefano Zampini graph->subset_ncc[n] = ncc_pid; 628674ae819SStefano Zampini } 629674ae819SStefano Zampini graph->ncc = ncc; 630acc113dbSStefano Zampini graph->queue_sorted = PETSC_FALSE; 631674ae819SStefano Zampini PetscFunctionReturn(0); 632674ae819SStefano Zampini } 633674ae819SStefano Zampini 634674ae819SStefano Zampini #undef __FUNCT__ 635674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGraphSetUp" 636674ae819SStefano Zampini PetscErrorCode PCBDDCGraphSetUp(PCBDDCGraph graph, PetscInt custom_minimal_size, IS neumann_is, IS dirichlet_is, PetscInt n_ISForDofs, IS ISForDofs[], IS custom_primal_vertices) 637674ae819SStefano Zampini { 638674ae819SStefano Zampini VecScatter scatter_ctx; 639674ae819SStefano Zampini Vec local_vec,local_vec2,global_vec; 640674ae819SStefano Zampini IS to,from; 641674ae819SStefano Zampini MPI_Comm comm; 642674ae819SStefano Zampini PetscScalar *array,*array2; 643674ae819SStefano Zampini const PetscInt *is_indices; 644f0321c90SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared,*queue_global,*subset_ref_node_global; 645674ae819SStefano Zampini PetscInt i,j,k,s,total_counts,nodes_touched,is_size; 6467babac9bSStefano Zampini PetscMPIInt size; 64751b0f6cfSStefano Zampini PetscBool same_set,mirrors_found; 6487babac9bSStefano Zampini PetscErrorCode ierr; 649674ae819SStefano Zampini 650674ae819SStefano Zampini PetscFunctionBegin; 651*a07ea27aSStefano Zampini graph->has_dirichlet = PETSC_FALSE; 652*a07ea27aSStefano Zampini if (dirichlet_is) { 653*a07ea27aSStefano Zampini PetscCheckSameComm(graph->l2gmap,1,dirichlet_is,4); 654*a07ea27aSStefano Zampini graph->has_dirichlet = PETSC_TRUE; 655*a07ea27aSStefano Zampini } 656674ae819SStefano Zampini ierr = PetscObjectGetComm((PetscObject)(graph->l2gmap),&comm);CHKERRQ(ierr); 657674ae819SStefano Zampini /* custom_minimal_size */ 658674ae819SStefano Zampini graph->custom_minimal_size = PetscMax(graph->custom_minimal_size,custom_minimal_size); 659674ae819SStefano Zampini /* get info l2gmap and allocate work vectors */ 660674ae819SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 6612635a1d4SStefano Zampini /* check if we have any local periodic nodes (periodic BCs) */ 6622635a1d4SStefano Zampini mirrors_found = PETSC_FALSE; 6632635a1d4SStefano Zampini if (graph->nvtxs && n_neigh) { 6642635a1d4SStefano Zampini for (i=0; i<n_shared[0]; i++) graph->count[shared[0][i]] += 1; 6652635a1d4SStefano Zampini for (i=0; i<n_shared[0]; i++) { 6662635a1d4SStefano Zampini if (graph->count[shared[0][i]] > 1) { 6672635a1d4SStefano Zampini mirrors_found = PETSC_TRUE; 6682635a1d4SStefano Zampini break; 6692635a1d4SStefano Zampini } 6702635a1d4SStefano Zampini } 6712635a1d4SStefano Zampini } 6722635a1d4SStefano Zampini /* create some workspace objects */ 6732635a1d4SStefano Zampini local_vec = NULL; 6742635a1d4SStefano Zampini local_vec2 = NULL; 6752635a1d4SStefano Zampini global_vec = NULL; 6762635a1d4SStefano Zampini to = NULL; 6772635a1d4SStefano Zampini from = NULL; 6782635a1d4SStefano Zampini scatter_ctx = NULL; 6792635a1d4SStefano Zampini if (n_ISForDofs || dirichlet_is || neumann_is || custom_primal_vertices) { 680674ae819SStefano Zampini ierr = VecCreate(PETSC_COMM_SELF,&local_vec);CHKERRQ(ierr); 681674ae819SStefano Zampini ierr = VecSetSizes(local_vec,PETSC_DECIDE,graph->nvtxs);CHKERRQ(ierr); 682674ae819SStefano Zampini ierr = VecSetType(local_vec,VECSTANDARD);CHKERRQ(ierr); 683674ae819SStefano Zampini ierr = VecDuplicate(local_vec,&local_vec2);CHKERRQ(ierr); 684674ae819SStefano Zampini ierr = VecCreate(comm,&global_vec);CHKERRQ(ierr); 6857fb0e2dbSStefano Zampini ierr = VecSetSizes(global_vec,PETSC_DECIDE,graph->nvtxs_global);CHKERRQ(ierr); 686674ae819SStefano Zampini ierr = VecSetType(global_vec,VECSTANDARD);CHKERRQ(ierr); 687674ae819SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,graph->nvtxs,0,1,&to);CHKERRQ(ierr); 688674ae819SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(graph->l2gmap,to,&from);CHKERRQ(ierr); 689674ae819SStefano Zampini ierr = VecScatterCreate(global_vec,from,local_vec,to,&scatter_ctx);CHKERRQ(ierr); 6902635a1d4SStefano Zampini } else if (mirrors_found) { 6912635a1d4SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,graph->nvtxs,0,1,&to);CHKERRQ(ierr); 6922635a1d4SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(graph->l2gmap,to,&from);CHKERRQ(ierr); 69349eeff8cSStefano Zampini } 69451b0f6cfSStefano Zampini /* compute local mirrors (if any) */ 69551b0f6cfSStefano Zampini if (mirrors_found) { 69651b0f6cfSStefano Zampini PetscInt *local_indices,*global_indices; 69751b0f6cfSStefano Zampini /* get arrays of local and global indices */ 698785e854fSJed Brown ierr = PetscMalloc1(graph->nvtxs,&local_indices);CHKERRQ(ierr); 69951b0f6cfSStefano Zampini ierr = ISGetIndices(to,(const PetscInt**)&is_indices);CHKERRQ(ierr); 70051b0f6cfSStefano Zampini ierr = PetscMemcpy(local_indices,is_indices,graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 70151b0f6cfSStefano Zampini ierr = ISRestoreIndices(to,(const PetscInt**)&is_indices);CHKERRQ(ierr); 702785e854fSJed Brown ierr = PetscMalloc1(graph->nvtxs,&global_indices);CHKERRQ(ierr); 70351b0f6cfSStefano Zampini ierr = ISGetIndices(from,(const PetscInt**)&is_indices);CHKERRQ(ierr); 70451b0f6cfSStefano Zampini ierr = PetscMemcpy(global_indices,is_indices,graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 70551b0f6cfSStefano Zampini ierr = ISRestoreIndices(from,(const PetscInt**)&is_indices);CHKERRQ(ierr); 70651b0f6cfSStefano Zampini /* allocate space for mirrors */ 7078e5aaad5SJed Brown ierr = PetscMalloc2(graph->nvtxs,&graph->mirrors,graph->nvtxs,&graph->mirrors_set);CHKERRQ(ierr); 70851b0f6cfSStefano Zampini ierr = PetscMemzero(graph->mirrors,graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 70951b0f6cfSStefano Zampini graph->mirrors_set[0] = 0; 71051b0f6cfSStefano Zampini 71151b0f6cfSStefano Zampini k=0; 71251b0f6cfSStefano Zampini for (i=0;i<n_shared[0];i++) { 71351b0f6cfSStefano Zampini j=shared[0][i]; 71451b0f6cfSStefano Zampini if (graph->count[j] > 1) { 71551b0f6cfSStefano Zampini graph->mirrors[j]++; 71651b0f6cfSStefano Zampini k++; 71751b0f6cfSStefano Zampini } 71851b0f6cfSStefano Zampini } 71951b0f6cfSStefano Zampini /* allocate space for set of mirrors */ 720785e854fSJed Brown ierr = PetscMalloc1(k,&graph->mirrors_set[0]);CHKERRQ(ierr); 72151b0f6cfSStefano Zampini for (i=1;i<graph->nvtxs;i++) 72251b0f6cfSStefano Zampini graph->mirrors_set[i]=graph->mirrors_set[i-1]+graph->mirrors[i-1]; 72351b0f6cfSStefano Zampini 72451b0f6cfSStefano Zampini /* fill arrays */ 72551b0f6cfSStefano Zampini ierr = PetscMemzero(graph->mirrors,graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 72651b0f6cfSStefano Zampini for (j=0;j<n_shared[0];j++) { 72751b0f6cfSStefano Zampini i=shared[0][j]; 72851b0f6cfSStefano Zampini if (graph->count[i] > 1) 72951b0f6cfSStefano Zampini graph->mirrors_set[i][graph->mirrors[i]++]=global_indices[i]; 73051b0f6cfSStefano Zampini } 73151b0f6cfSStefano Zampini ierr = PetscSortIntWithArray(graph->nvtxs,global_indices,local_indices);CHKERRQ(ierr); 73251b0f6cfSStefano Zampini for (i=0;i<graph->nvtxs;i++) { 73351b0f6cfSStefano Zampini if (graph->mirrors[i] > 0) { 73451b0f6cfSStefano Zampini ierr = PetscFindInt(graph->mirrors_set[i][0],graph->nvtxs,global_indices,&k);CHKERRQ(ierr); 73551b0f6cfSStefano Zampini j = global_indices[k]; 73651b0f6cfSStefano Zampini while ( k > 0 && global_indices[k-1] == j) k--; 73751b0f6cfSStefano Zampini for (j=0;j<graph->mirrors[i];j++) { 73851b0f6cfSStefano Zampini graph->mirrors_set[i][j]=local_indices[k+j]; 73951b0f6cfSStefano Zampini } 74051b0f6cfSStefano Zampini ierr = PetscSortInt(graph->mirrors[i],graph->mirrors_set[i]);CHKERRQ(ierr); 74151b0f6cfSStefano Zampini } 74251b0f6cfSStefano Zampini } 74351b0f6cfSStefano Zampini ierr = PetscFree(local_indices);CHKERRQ(ierr); 74451b0f6cfSStefano Zampini ierr = PetscFree(global_indices);CHKERRQ(ierr); 74551b0f6cfSStefano Zampini } 74651b0f6cfSStefano Zampini ierr = PetscMemzero(graph->count,graph->nvtxs*sizeof(*graph->count));CHKERRQ(ierr); 747674ae819SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 748674ae819SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 74951b0f6cfSStefano Zampini 750674ae819SStefano Zampini /* Count total number of neigh per node */ 751674ae819SStefano Zampini k=0; 752674ae819SStefano Zampini for (i=1;i<n_neigh;i++) { 753674ae819SStefano Zampini k += n_shared[i]; 754674ae819SStefano Zampini for (j=0;j<n_shared[i];j++) { 755674ae819SStefano Zampini graph->count[shared[i][j]] += 1; 756674ae819SStefano Zampini } 757674ae819SStefano Zampini } 758674ae819SStefano Zampini /* Allocate space for storing the set of neighbours for each node */ 759674ae819SStefano Zampini if (graph->nvtxs) { 760785e854fSJed Brown ierr = PetscMalloc1(k,&graph->neighbours_set[0]);CHKERRQ(ierr); 761674ae819SStefano Zampini } 762674ae819SStefano Zampini for (i=1;i<graph->nvtxs;i++) { /* dont count myself */ 763674ae819SStefano Zampini graph->neighbours_set[i]=graph->neighbours_set[i-1]+graph->count[i-1]; 764674ae819SStefano Zampini } 765674ae819SStefano Zampini /* Get information for sharing subdomains */ 766674ae819SStefano Zampini ierr = PetscMemzero(graph->count,graph->nvtxs*sizeof(*graph->count));CHKERRQ(ierr); 767674ae819SStefano Zampini for (i=1;i<n_neigh;i++) { /* dont count myself */ 768674ae819SStefano Zampini s = n_shared[i]; 769674ae819SStefano Zampini for (j=0;j<s;j++) { 770674ae819SStefano Zampini k = shared[i][j]; 771674ae819SStefano Zampini graph->neighbours_set[k][graph->count[k]] = neigh[i]; 772674ae819SStefano Zampini graph->count[k] += 1; 773674ae819SStefano Zampini } 774674ae819SStefano Zampini } 775674ae819SStefano Zampini /* sort set of sharing subdomains */ 776674ae819SStefano Zampini for (i=0;i<graph->nvtxs;i++) { 77793fb5fd3SStefano Zampini ierr = PetscSortRemoveDupsInt(&graph->count[i],graph->neighbours_set[i]);CHKERRQ(ierr); 778674ae819SStefano Zampini } 7797fb0e2dbSStefano Zampini /* free memory allocated by ISLocalToGlobalMappingGetInfo */ 7807fb0e2dbSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 7817fb0e2dbSStefano Zampini 78267c9da69SStefano Zampini /* 78367c9da69SStefano Zampini Get info for dofs splitting 7845777c63cSStefano Zampini User can specify just a subset; an additional field is considered as a complementary field 78567c9da69SStefano Zampini */ 78667c9da69SStefano Zampini for (i=0;i<graph->nvtxs;i++) { 78767c9da69SStefano Zampini graph->which_dof[i] = n_ISForDofs; /* by default a dof belongs to the complement set */ 78867c9da69SStefano Zampini } 7895777c63cSStefano Zampini if (n_ISForDofs) { 7905777c63cSStefano Zampini ierr = VecSet(local_vec,-1.0);CHKERRQ(ierr); 7915777c63cSStefano Zampini } 792674ae819SStefano Zampini for (i=0;i<n_ISForDofs;i++) { 7935777c63cSStefano Zampini ierr = VecGetArray(local_vec,&array);CHKERRQ(ierr); 79463602bcaSStefano Zampini ierr = ISGetLocalSize(ISForDofs[i],&is_size);CHKERRQ(ierr); 795674ae819SStefano Zampini ierr = ISGetIndices(ISForDofs[i],(const PetscInt**)&is_indices);CHKERRQ(ierr); 796674ae819SStefano Zampini for (j=0;j<is_size;j++) { 797d50ed60aSStefano Zampini if (is_indices[j] > -1 && is_indices[j] < graph->nvtxs) { /* out of bounds indices (if any) are skipped */ 798674ae819SStefano Zampini graph->which_dof[is_indices[j]] = i; 7995777c63cSStefano Zampini array[is_indices[j]] = 1.*i; 800674ae819SStefano Zampini } 80167c9da69SStefano Zampini } 802674ae819SStefano Zampini ierr = ISRestoreIndices(ISForDofs[i],(const PetscInt**)&is_indices);CHKERRQ(ierr); 8035777c63cSStefano Zampini ierr = VecRestoreArray(local_vec,&array);CHKERRQ(ierr); 8045777c63cSStefano Zampini } 8055777c63cSStefano Zampini /* Check consistency among neighbours */ 8065777c63cSStefano Zampini if (n_ISForDofs) { 8075777c63cSStefano Zampini ierr = VecScatterBegin(scatter_ctx,local_vec,global_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8085777c63cSStefano Zampini ierr = VecScatterEnd(scatter_ctx,local_vec,global_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8095777c63cSStefano Zampini ierr = VecScatterBegin(scatter_ctx,global_vec,local_vec2,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8105777c63cSStefano Zampini ierr = VecScatterEnd(scatter_ctx,global_vec,local_vec2,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8115777c63cSStefano Zampini ierr = VecGetArray(local_vec,&array);CHKERRQ(ierr); 8125777c63cSStefano Zampini ierr = VecGetArray(local_vec2,&array2);CHKERRQ(ierr); 8135777c63cSStefano Zampini for (i=0;i<graph->nvtxs;i++){ 8145777c63cSStefano Zampini PetscInt field1,field2; 8155777c63cSStefano Zampini 8165777c63cSStefano Zampini field1 = (PetscInt)PetscRealPart(array[i]); 8175777c63cSStefano Zampini field2 = (PetscInt)PetscRealPart(array2[i]); 8185777c63cSStefano Zampini if (field1 != field2) { 8195777c63cSStefano Zampini SETERRQ3(comm,PETSC_ERR_USER,"Local node %d have been assigned two different field ids %d and %d at the same time\n",i,field1,field2); 8205777c63cSStefano Zampini } 8215777c63cSStefano Zampini } 8225777c63cSStefano Zampini ierr = VecRestoreArray(local_vec,&array);CHKERRQ(ierr); 8235777c63cSStefano Zampini ierr = VecRestoreArray(local_vec2,&array2);CHKERRQ(ierr); 824674ae819SStefano Zampini } 8257fb0e2dbSStefano Zampini if (neumann_is || dirichlet_is) { 826674ae819SStefano Zampini /* Take into account Neumann nodes */ 827674ae819SStefano Zampini ierr = VecSet(local_vec,0.0);CHKERRQ(ierr); 828674ae819SStefano Zampini ierr = VecSet(local_vec2,0.0);CHKERRQ(ierr); 829674ae819SStefano Zampini if (neumann_is) { 830674ae819SStefano Zampini ierr = VecGetArray(local_vec,&array);CHKERRQ(ierr); 83182ba6b80SStefano Zampini ierr = ISGetLocalSize(neumann_is,&is_size);CHKERRQ(ierr); 832674ae819SStefano Zampini ierr = ISGetIndices(neumann_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 833674ae819SStefano Zampini for (i=0;i<is_size;i++) { 834d50ed60aSStefano Zampini if (is_indices[i] > -1 && is_indices[i] < graph->nvtxs) { /* out of bounds indices (if any) are skipped */ 835674ae819SStefano Zampini array[is_indices[i]] = 1.0; 836674ae819SStefano Zampini } 8373c629590SStefano Zampini } 838674ae819SStefano Zampini ierr = ISRestoreIndices(neumann_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 839674ae819SStefano Zampini ierr = VecRestoreArray(local_vec,&array);CHKERRQ(ierr); 840674ae819SStefano Zampini } 841674ae819SStefano Zampini /* Neumann nodes: impose consistency among neighbours */ 842674ae819SStefano Zampini ierr = VecSet(global_vec,0.0);CHKERRQ(ierr); 843674ae819SStefano Zampini ierr = VecScatterBegin(scatter_ctx,local_vec,global_vec,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 844674ae819SStefano Zampini ierr = VecScatterEnd(scatter_ctx,local_vec,global_vec,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 845674ae819SStefano Zampini ierr = VecScatterBegin(scatter_ctx,global_vec,local_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 846674ae819SStefano Zampini ierr = VecScatterEnd(scatter_ctx,global_vec,local_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 847674ae819SStefano Zampini ierr = VecGetArray(local_vec,&array);CHKERRQ(ierr); 848674ae819SStefano Zampini for (i=0;i<graph->nvtxs;i++) { 8493c629590SStefano Zampini if (PetscRealPart(array[i]) > 0.1) { 8500cf82fd6SStefano Zampini graph->special_dof[i] = PCBDDCGRAPH_NEUMANN_MARK; 851674ae819SStefano Zampini } 852674ae819SStefano Zampini } 853674ae819SStefano Zampini ierr = VecRestoreArray(local_vec,&array);CHKERRQ(ierr); 854674ae819SStefano Zampini /* Take into account Dirichlet nodes */ 855674ae819SStefano Zampini ierr = VecSet(local_vec2,0.0);CHKERRQ(ierr); 856674ae819SStefano Zampini if (dirichlet_is) { 857674ae819SStefano Zampini ierr = VecGetArray(local_vec,&array);CHKERRQ(ierr); 858674ae819SStefano Zampini ierr = VecGetArray(local_vec2,&array2);CHKERRQ(ierr); 85982ba6b80SStefano Zampini ierr = ISGetLocalSize(dirichlet_is,&is_size);CHKERRQ(ierr); 860674ae819SStefano Zampini ierr = ISGetIndices(dirichlet_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 861674ae819SStefano Zampini for (i=0;i<is_size;i++){ 862d50ed60aSStefano Zampini if (is_indices[i] > -1 && is_indices[i] < graph->nvtxs) { /* out of bounds indices (if any) are skipped */ 863674ae819SStefano Zampini k = is_indices[i]; 864df48933bSStefano Zampini if (graph->count[k] && !PetscBTLookup(graph->touched,k)) { 8653c629590SStefano Zampini if (PetscRealPart(array[k]) > 0.1) { 8665777c63cSStefano Zampini SETERRQ1(comm,PETSC_ERR_USER,"BDDC cannot have boundary nodes which are marked Neumann and Dirichlet at the same time! Local node %d is wrong\n",k); 867674ae819SStefano Zampini } 868674ae819SStefano Zampini array2[k] = 1.0; 869674ae819SStefano Zampini } 870674ae819SStefano Zampini } 8713c629590SStefano Zampini } 872674ae819SStefano Zampini ierr = ISRestoreIndices(dirichlet_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 873674ae819SStefano Zampini ierr = VecRestoreArray(local_vec,&array);CHKERRQ(ierr); 874674ae819SStefano Zampini ierr = VecRestoreArray(local_vec2,&array2);CHKERRQ(ierr); 875674ae819SStefano Zampini } 876674ae819SStefano Zampini /* Dirichlet nodes: impose consistency among neighbours */ 877674ae819SStefano Zampini ierr = VecSet(global_vec,0.0);CHKERRQ(ierr); 878674ae819SStefano Zampini ierr = VecScatterBegin(scatter_ctx,local_vec2,global_vec,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 879674ae819SStefano Zampini ierr = VecScatterEnd(scatter_ctx,local_vec2,global_vec,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 880674ae819SStefano Zampini ierr = VecScatterBegin(scatter_ctx,global_vec,local_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 881674ae819SStefano Zampini ierr = VecScatterEnd(scatter_ctx,global_vec,local_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 882674ae819SStefano Zampini ierr = VecGetArray(local_vec,&array);CHKERRQ(ierr); 883674ae819SStefano Zampini for (i=0;i<graph->nvtxs;i++) { 8843c629590SStefano Zampini if (PetscRealPart(array[i]) > 0.1) { 885df48933bSStefano Zampini ierr = PetscBTSet(graph->touched,i);CHKERRQ(ierr); 886674ae819SStefano Zampini graph->subset[i] = 0; /* dirichlet nodes treated as internal -> is it ok? */ 8870cf82fd6SStefano Zampini graph->special_dof[i] = PCBDDCGRAPH_DIRICHLET_MARK; 888674ae819SStefano Zampini } 889674ae819SStefano Zampini } 890674ae819SStefano Zampini ierr = VecRestoreArray(local_vec,&array);CHKERRQ(ierr); 8917fb0e2dbSStefano Zampini } 89208a5cf49SStefano Zampini /* mark local periodic nodes (if any) and adapt CSR graph (if any) */ 89351b0f6cfSStefano Zampini if (graph->mirrors) { 89451b0f6cfSStefano Zampini for (i=0;i<graph->nvtxs;i++) 89551b0f6cfSStefano Zampini if (graph->mirrors[i]) 8960cf82fd6SStefano Zampini graph->special_dof[i] = PCBDDCGRAPH_LOCAL_PERIODIC_MARK; 89751b0f6cfSStefano Zampini 89808a5cf49SStefano Zampini if (graph->xadj && graph->adjncy) { 89908a5cf49SStefano Zampini PetscInt *new_xadj,*new_adjncy; 90051b0f6cfSStefano Zampini /* sort CSR graph */ 90151b0f6cfSStefano Zampini for (i=0;i<graph->nvtxs;i++) 90251b0f6cfSStefano Zampini ierr = PetscSortInt(graph->xadj[i+1]-graph->xadj[i],&graph->adjncy[graph->xadj[i]]);CHKERRQ(ierr); 90351b0f6cfSStefano Zampini 90451b0f6cfSStefano Zampini /* adapt local CSR graph in case of local periodicity */ 90551b0f6cfSStefano Zampini k=0; 90651b0f6cfSStefano Zampini for (i=0;i<graph->nvtxs;i++) 90751b0f6cfSStefano Zampini for (j=graph->xadj[i];j<graph->xadj[i+1];j++) 90851b0f6cfSStefano Zampini k += graph->mirrors[graph->adjncy[j]]; 90951b0f6cfSStefano Zampini 910854ce69bSBarry Smith ierr = PetscMalloc1(graph->nvtxs+1,&new_xadj);CHKERRQ(ierr); 911854ce69bSBarry Smith ierr = PetscMalloc1(k+graph->xadj[graph->nvtxs],&new_adjncy);CHKERRQ(ierr); 91251b0f6cfSStefano Zampini new_xadj[0]=0; 91351b0f6cfSStefano Zampini for (i=0;i<graph->nvtxs;i++) { 91451b0f6cfSStefano Zampini k = graph->xadj[i+1]-graph->xadj[i]; 91551b0f6cfSStefano Zampini ierr = PetscMemcpy(&new_adjncy[new_xadj[i]],&graph->adjncy[graph->xadj[i]],k*sizeof(PetscInt));CHKERRQ(ierr); 91651b0f6cfSStefano Zampini new_xadj[i+1]=new_xadj[i]+k; 91751b0f6cfSStefano Zampini for (j=graph->xadj[i];j<graph->xadj[i+1];j++) { 91851b0f6cfSStefano Zampini k = graph->mirrors[graph->adjncy[j]]; 91951b0f6cfSStefano Zampini ierr = PetscMemcpy(&new_adjncy[new_xadj[i+1]],graph->mirrors_set[graph->adjncy[j]],k*sizeof(PetscInt));CHKERRQ(ierr); 92051b0f6cfSStefano Zampini new_xadj[i+1]+=k; 92151b0f6cfSStefano Zampini } 92251b0f6cfSStefano Zampini k = new_xadj[i+1]-new_xadj[i]; 92351b0f6cfSStefano Zampini ierr = PetscSortRemoveDupsInt(&k,&new_adjncy[new_xadj[i]]);CHKERRQ(ierr); 92451b0f6cfSStefano Zampini new_xadj[i+1]=new_xadj[i]+k; 92551b0f6cfSStefano Zampini } 92651b0f6cfSStefano Zampini /* set new CSR into graph */ 92751b0f6cfSStefano Zampini ierr = PetscFree(graph->xadj);CHKERRQ(ierr); 92851b0f6cfSStefano Zampini ierr = PetscFree(graph->adjncy);CHKERRQ(ierr); 92951b0f6cfSStefano Zampini graph->xadj = new_xadj; 93051b0f6cfSStefano Zampini graph->adjncy = new_adjncy; 93151b0f6cfSStefano Zampini } 93208a5cf49SStefano Zampini } 93351b0f6cfSStefano Zampini 93417eb1463SStefano Zampini /* mark special nodes (if any) -> each will become a single node equivalence class */ 935674ae819SStefano Zampini if (custom_primal_vertices) { 93617eb1463SStefano Zampini ierr = VecSet(local_vec,0.0);CHKERRQ(ierr); 9379b70a373SStefano Zampini ierr = VecGetArray(local_vec,&array);CHKERRQ(ierr); 93863602bcaSStefano Zampini ierr = ISGetLocalSize(custom_primal_vertices,&is_size);CHKERRQ(ierr); 939674ae819SStefano Zampini ierr = ISGetIndices(custom_primal_vertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 940674ae819SStefano Zampini for (i=0;i<is_size;i++){ 9419b70a373SStefano Zampini if (is_indices[i] > -1 && is_indices[i] < graph->nvtxs) { /* out of bounds indices (if any) are skipped */ 9429b70a373SStefano Zampini array[is_indices[i]] = 1.0; 9439b70a373SStefano Zampini } 944674ae819SStefano Zampini } 945674ae819SStefano Zampini ierr = ISRestoreIndices(custom_primal_vertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 9469b70a373SStefano Zampini ierr = VecRestoreArray(local_vec,&array);CHKERRQ(ierr); 9479b70a373SStefano Zampini /* special nodes: impose consistency among neighbours */ 9489b70a373SStefano Zampini ierr = VecSet(global_vec,0.0);CHKERRQ(ierr); 9499b70a373SStefano Zampini ierr = VecScatterBegin(scatter_ctx,local_vec,global_vec,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9509b70a373SStefano Zampini ierr = VecScatterEnd(scatter_ctx,local_vec,global_vec,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9519b70a373SStefano Zampini ierr = VecScatterBegin(scatter_ctx,global_vec,local_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9529b70a373SStefano Zampini ierr = VecScatterEnd(scatter_ctx,global_vec,local_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9539b70a373SStefano Zampini ierr = VecGetArray(local_vec,&array);CHKERRQ(ierr); 9549b70a373SStefano Zampini j = 0; 9559b70a373SStefano Zampini for (i=0;i<graph->nvtxs;i++) { 9569b70a373SStefano Zampini if (PetscRealPart(array[i]) > 0.1 && graph->special_dof[i] != PCBDDCGRAPH_DIRICHLET_MARK) { 9579b70a373SStefano Zampini graph->special_dof[i] = PCBDDCGRAPH_SPECIAL_MARK-j; 9589b70a373SStefano Zampini j++; 9599b70a373SStefano Zampini } 9609b70a373SStefano Zampini } 9619b70a373SStefano Zampini ierr = VecRestoreArray(local_vec,&array);CHKERRQ(ierr); 96217eb1463SStefano Zampini } 9639b70a373SStefano Zampini 964674ae819SStefano Zampini /* mark interior nodes as touched and belonging to partition number 0 */ 965674ae819SStefano Zampini for (i=0;i<graph->nvtxs;i++) { 966674ae819SStefano Zampini if (!graph->count[i]) { 967df48933bSStefano Zampini ierr = PetscBTSet(graph->touched,i);CHKERRQ(ierr); 968674ae819SStefano Zampini graph->subset[i] = 0; 969674ae819SStefano Zampini } 970674ae819SStefano Zampini } 971674ae819SStefano Zampini /* init graph structure and compute default subsets */ 972674ae819SStefano Zampini nodes_touched=0; 973674ae819SStefano Zampini for (i=0;i<graph->nvtxs;i++) { 974df48933bSStefano Zampini if (PetscBTLookup(graph->touched,i)) { 975674ae819SStefano Zampini nodes_touched++; 976674ae819SStefano Zampini } 977674ae819SStefano Zampini } 978674ae819SStefano Zampini i = 0; 979674ae819SStefano Zampini graph->ncc = 0; 980674ae819SStefano Zampini total_counts = 0; 9817babac9bSStefano Zampini 9827babac9bSStefano Zampini /* allocated space for queues */ 9837babac9bSStefano Zampini ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 9847babac9bSStefano Zampini if (size == 1) { 9857babac9bSStefano Zampini ierr = PetscMalloc2(graph->nvtxs+1,&graph->cptr,graph->nvtxs,&graph->queue);CHKERRQ(ierr); 9867babac9bSStefano Zampini } else { 9877babac9bSStefano Zampini PetscInt nused = graph->nvtxs - nodes_touched; 9887babac9bSStefano Zampini ierr = PetscMalloc2(nused+1,&graph->cptr,nused,&graph->queue);CHKERRQ(ierr); 9897babac9bSStefano Zampini } 9907babac9bSStefano Zampini 991674ae819SStefano Zampini while (nodes_touched<graph->nvtxs) { 992674ae819SStefano Zampini /* find first untouched node in local ordering */ 993df48933bSStefano Zampini while (PetscBTLookup(graph->touched,i)) { 994674ae819SStefano Zampini i++; 995674ae819SStefano Zampini } 996df48933bSStefano Zampini ierr = PetscBTSet(graph->touched,i);CHKERRQ(ierr); 997674ae819SStefano Zampini graph->subset[i] = graph->ncc+1; 998674ae819SStefano Zampini graph->cptr[graph->ncc] = total_counts; 999674ae819SStefano Zampini graph->queue[total_counts] = i; 1000674ae819SStefano Zampini total_counts++; 1001674ae819SStefano Zampini nodes_touched++; 1002674ae819SStefano Zampini /* now find all other nodes having the same set of sharing subdomains */ 1003674ae819SStefano Zampini for (j=i+1;j<graph->nvtxs;j++) { 100474e413f5SStefano Zampini /* check for same number of sharing subdomains, dof number and same special mark */ 1005df48933bSStefano Zampini if (!PetscBTLookup(graph->touched,j) && graph->count[i] == graph->count[j] && graph->which_dof[i] == graph->which_dof[j] && graph->special_dof[i] == graph->special_dof[j]) { 1006674ae819SStefano Zampini /* check for same set of sharing subdomains */ 1007674ae819SStefano Zampini same_set=PETSC_TRUE; 1008674ae819SStefano Zampini for (k=0;k<graph->count[j];k++){ 1009674ae819SStefano Zampini if (graph->neighbours_set[i][k]!=graph->neighbours_set[j][k]) { 1010674ae819SStefano Zampini same_set=PETSC_FALSE; 1011674ae819SStefano Zampini } 1012674ae819SStefano Zampini } 1013674ae819SStefano Zampini /* I found a friend of mine */ 1014674ae819SStefano Zampini if (same_set) { 1015674ae819SStefano Zampini graph->subset[j]=graph->ncc+1; 1016df48933bSStefano Zampini ierr = PetscBTSet(graph->touched,j);CHKERRQ(ierr); 1017674ae819SStefano Zampini nodes_touched++; 1018674ae819SStefano Zampini graph->queue[total_counts] = j; 1019674ae819SStefano Zampini total_counts++; 1020674ae819SStefano Zampini } 1021674ae819SStefano Zampini } 1022674ae819SStefano Zampini } 1023674ae819SStefano Zampini graph->ncc++; 1024674ae819SStefano Zampini } 1025674ae819SStefano Zampini /* set default number of subsets (at this point no info on csr graph has been taken into account, so n_subsets = ncc */ 1026674ae819SStefano Zampini graph->n_subsets = graph->ncc; 1027785e854fSJed Brown ierr = PetscMalloc1(graph->n_subsets,&graph->subset_ncc);CHKERRQ(ierr); 1028674ae819SStefano Zampini for (i=0;i<graph->n_subsets;i++) { 1029674ae819SStefano Zampini graph->subset_ncc[i] = 1; 1030674ae819SStefano Zampini } 1031674ae819SStefano Zampini /* final pointer */ 1032674ae819SStefano Zampini graph->cptr[graph->ncc] = total_counts; 1033ec1c413dSStefano Zampini 1034ec1c413dSStefano Zampini /* save information on subsets (needed if we have to adapt the connected components later) */ 1035ec1c413dSStefano Zampini /* For consistency reasons (among neighbours), I need to sort (by global ordering) each subset */ 1036ec1c413dSStefano Zampini /* Get a reference node (min index in global ordering) for each subset for tagging messages */ 1037ec1c413dSStefano Zampini ierr = PetscMalloc2(graph->ncc,&subset_ref_node_global,graph->cptr[graph->ncc],&queue_global);CHKERRQ(ierr); 10383a5b03d1SStefano Zampini ierr = ISLocalToGlobalMappingApply(graph->l2gmap,graph->cptr[graph->ncc],graph->queue,queue_global);CHKERRQ(ierr); 1039ec1c413dSStefano Zampini for (j=0;j<graph->ncc;j++) { 1040ec1c413dSStefano Zampini ierr = PetscSortIntWithArray(graph->cptr[j+1]-graph->cptr[j],&queue_global[graph->cptr[j]],&graph->queue[graph->cptr[j]]);CHKERRQ(ierr); 1041ec1c413dSStefano Zampini subset_ref_node_global[j] = graph->queue[graph->cptr[j]]; 1042f0321c90SStefano Zampini } 1043acc113dbSStefano Zampini graph->queue_sorted = PETSC_TRUE; 10442f566a09SStefano Zampini if (graph->ncc) { 1045ec1c413dSStefano Zampini ierr = PetscMalloc2(graph->ncc,&graph->subsets_size,graph->ncc,&graph->subsets);CHKERRQ(ierr); 1046ec1c413dSStefano Zampini ierr = PetscMalloc1(graph->cptr[graph->ncc],&graph->subsets[0]);CHKERRQ(ierr); 1047ec1c413dSStefano Zampini ierr = PetscMemzero(graph->subsets[0],graph->cptr[graph->ncc]*sizeof(PetscInt));CHKERRQ(ierr); 1048ec1c413dSStefano Zampini for (j=1;j<graph->ncc;j++) { 1049ec1c413dSStefano Zampini graph->subsets_size[j-1] = graph->cptr[j] - graph->cptr[j-1]; 1050ec1c413dSStefano Zampini graph->subsets[j] = graph->subsets[j-1] + graph->subsets_size[j-1]; 1051ec1c413dSStefano Zampini } 1052ec1c413dSStefano Zampini graph->subsets_size[graph->ncc-1] = graph->cptr[graph->ncc] - graph->cptr[graph->ncc-1]; 1053ec1c413dSStefano Zampini for (j=0;j<graph->ncc;j++) { 1054ec1c413dSStefano Zampini ierr = PetscMemcpy(graph->subsets[j],&graph->queue[graph->cptr[j]],graph->subsets_size[j]*sizeof(PetscInt));CHKERRQ(ierr); 1055ec1c413dSStefano Zampini } 10562f566a09SStefano Zampini } 1057f0321c90SStefano Zampini /* renumber reference nodes */ 1058f0321c90SStefano Zampini ierr = PCBDDCSubsetNumbering(PetscObjectComm((PetscObject)(graph->l2gmap)),graph->l2gmap,graph->ncc,subset_ref_node_global,NULL,&k,&graph->subset_ref_node);CHKERRQ(ierr); 1059ec1c413dSStefano Zampini 1060ec1c413dSStefano Zampini /* free workspace */ 1061ec1c413dSStefano Zampini ierr = PetscFree2(subset_ref_node_global,queue_global);CHKERRQ(ierr); 1062674ae819SStefano Zampini ierr = VecDestroy(&local_vec);CHKERRQ(ierr); 1063674ae819SStefano Zampini ierr = VecDestroy(&local_vec2);CHKERRQ(ierr); 1064674ae819SStefano Zampini ierr = VecDestroy(&global_vec);CHKERRQ(ierr); 1065674ae819SStefano Zampini ierr = VecScatterDestroy(&scatter_ctx);CHKERRQ(ierr); 1066674ae819SStefano Zampini PetscFunctionReturn(0); 1067674ae819SStefano Zampini } 1068674ae819SStefano Zampini 1069674ae819SStefano Zampini #undef __FUNCT__ 1070674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGraphResetCSR" 1071674ae819SStefano Zampini PetscErrorCode PCBDDCGraphResetCSR(PCBDDCGraph graph) 1072674ae819SStefano Zampini { 1073674ae819SStefano Zampini PetscErrorCode ierr; 1074674ae819SStefano Zampini 1075674ae819SStefano Zampini PetscFunctionBegin; 1076674ae819SStefano Zampini ierr = PetscFree(graph->xadj);CHKERRQ(ierr); 1077674ae819SStefano Zampini ierr = PetscFree(graph->adjncy);CHKERRQ(ierr); 1078575ad6abSStefano Zampini graph->nvtxs_csr = 0; 1079674ae819SStefano Zampini PetscFunctionReturn(0); 1080674ae819SStefano Zampini } 1081674ae819SStefano Zampini 1082674ae819SStefano Zampini #undef __FUNCT__ 1083674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGraphReset" 1084674ae819SStefano Zampini PetscErrorCode PCBDDCGraphReset(PCBDDCGraph graph) 1085674ae819SStefano Zampini { 1086674ae819SStefano Zampini PetscErrorCode ierr; 1087674ae819SStefano Zampini 1088674ae819SStefano Zampini PetscFunctionBegin; 1089674ae819SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&graph->l2gmap);CHKERRQ(ierr); 1090674ae819SStefano Zampini ierr = PetscFree(graph->subset_ncc);CHKERRQ(ierr); 10913a5b03d1SStefano Zampini ierr = PetscFree(graph->subset_ref_node);CHKERRQ(ierr); 1092674ae819SStefano Zampini if (graph->nvtxs) { 1093674ae819SStefano Zampini ierr = PetscFree(graph->neighbours_set[0]);CHKERRQ(ierr); 1094674ae819SStefano Zampini } 1095df48933bSStefano Zampini ierr = PetscBTDestroy(&graph->touched);CHKERRQ(ierr); 10967babac9bSStefano Zampini ierr = PetscFree5(graph->count, 1097674ae819SStefano Zampini graph->neighbours_set, 1098674ae819SStefano Zampini graph->subset, 1099674ae819SStefano Zampini graph->which_dof, 1100df48933bSStefano Zampini graph->special_dof);CHKERRQ(ierr); 11017babac9bSStefano Zampini ierr = PetscFree2(graph->cptr,graph->queue);CHKERRQ(ierr); 110251b0f6cfSStefano Zampini if (graph->mirrors) { 110351b0f6cfSStefano Zampini ierr = PetscFree(graph->mirrors_set[0]);CHKERRQ(ierr); 110451b0f6cfSStefano Zampini } 110551b0f6cfSStefano Zampini ierr = PetscFree2(graph->mirrors,graph->mirrors_set);CHKERRQ(ierr); 1106ec1c413dSStefano Zampini if (graph->subsets) { 1107ec1c413dSStefano Zampini ierr = PetscFree(graph->subsets[0]);CHKERRQ(ierr); 1108ec1c413dSStefano Zampini } 1109ec1c413dSStefano Zampini ierr = PetscFree2(graph->subsets_size,graph->subsets);CHKERRQ(ierr); 1110*a07ea27aSStefano Zampini ierr = ISDestroy(&graph->dirdofs);CHKERRQ(ierr); 1111*a07ea27aSStefano Zampini graph->has_dirichlet = PETSC_FALSE; 1112674ae819SStefano Zampini graph->nvtxs = 0; 11137babac9bSStefano Zampini graph->nvtxs_global = 0; 1114674ae819SStefano Zampini graph->n_subsets = 0; 1115674ae819SStefano Zampini graph->custom_minimal_size = 1; 1116674ae819SStefano Zampini PetscFunctionReturn(0); 1117674ae819SStefano Zampini } 1118674ae819SStefano Zampini 1119674ae819SStefano Zampini #undef __FUNCT__ 1120674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGraphInit" 11217fb0e2dbSStefano Zampini PetscErrorCode PCBDDCGraphInit(PCBDDCGraph graph, ISLocalToGlobalMapping l2gmap, PetscInt N) 1122674ae819SStefano Zampini { 1123674ae819SStefano Zampini PetscInt n; 1124674ae819SStefano Zampini PetscErrorCode ierr; 1125674ae819SStefano Zampini 1126674ae819SStefano Zampini PetscFunctionBegin; 1127674ae819SStefano Zampini PetscValidPointer(graph,1); 1128674ae819SStefano Zampini PetscValidHeaderSpecific(l2gmap,IS_LTOGM_CLASSID,2); 11297babac9bSStefano Zampini PetscValidLogicalCollectiveInt(l2gmap,N,3); 11308e61c736SStefano Zampini /* raise an error if already allocated */ 11317babac9bSStefano Zampini if (graph->nvtxs_global) { 11328e61c736SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)l2gmap),PETSC_ERR_PLIB,"BDDCGraph already initialized"); 1133674ae819SStefano Zampini } 1134674ae819SStefano Zampini /* set number of vertices */ 1135674ae819SStefano Zampini ierr = PetscObjectReference((PetscObject)l2gmap);CHKERRQ(ierr); 1136674ae819SStefano Zampini graph->l2gmap = l2gmap; 1137674ae819SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 1138674ae819SStefano Zampini graph->nvtxs = n; 11397fb0e2dbSStefano Zampini graph->nvtxs_global = N; 1140674ae819SStefano Zampini /* allocate used space */ 1141df48933bSStefano Zampini ierr = PetscBTCreate(graph->nvtxs,&graph->touched);CHKERRQ(ierr); 11427babac9bSStefano Zampini ierr = PetscMalloc5(graph->nvtxs,&graph->count, 11438e5aaad5SJed Brown graph->nvtxs,&graph->neighbours_set, 11448e5aaad5SJed Brown graph->nvtxs,&graph->subset, 11458e5aaad5SJed Brown graph->nvtxs,&graph->which_dof, 11468e5aaad5SJed Brown graph->nvtxs,&graph->special_dof);CHKERRQ(ierr); 1147674ae819SStefano Zampini /* zeroes memory */ 1148674ae819SStefano Zampini ierr = PetscMemzero(graph->count,graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 1149674ae819SStefano Zampini ierr = PetscMemzero(graph->subset,graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 115063602bcaSStefano Zampini /* use -1 as a default value for which_dof array */ 115163602bcaSStefano Zampini for (n=0;n<graph->nvtxs;n++) graph->which_dof[n] = -1; 115274e413f5SStefano Zampini ierr = PetscMemzero(graph->special_dof,graph->nvtxs*sizeof(PetscInt));CHKERRQ(ierr); 1153674ae819SStefano Zampini /* zeroes first pointer to neighbour set */ 1154674ae819SStefano Zampini if (graph->nvtxs) { 1155674ae819SStefano Zampini graph->neighbours_set[0] = 0; 1156674ae819SStefano Zampini } 1157674ae819SStefano Zampini /* zeroes workspace for values of ncc */ 1158674ae819SStefano Zampini graph->subset_ncc = 0; 11593a5b03d1SStefano Zampini graph->subset_ref_node = 0; 1160674ae819SStefano Zampini PetscFunctionReturn(0); 1161674ae819SStefano Zampini } 1162674ae819SStefano Zampini 1163674ae819SStefano Zampini #undef __FUNCT__ 1164674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGraphDestroy" 1165674ae819SStefano Zampini PetscErrorCode PCBDDCGraphDestroy(PCBDDCGraph* graph) 1166674ae819SStefano Zampini { 1167674ae819SStefano Zampini PetscErrorCode ierr; 1168674ae819SStefano Zampini 1169674ae819SStefano Zampini PetscFunctionBegin; 1170674ae819SStefano Zampini ierr = PCBDDCGraphReset(*graph);CHKERRQ(ierr); 1171674ae819SStefano Zampini ierr = PetscFree(*graph);CHKERRQ(ierr); 1172674ae819SStefano Zampini PetscFunctionReturn(0); 1173674ae819SStefano Zampini } 1174674ae819SStefano Zampini 1175674ae819SStefano Zampini #undef __FUNCT__ 1176674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGraphCreate" 1177674ae819SStefano Zampini PetscErrorCode PCBDDCGraphCreate(PCBDDCGraph *graph) 1178674ae819SStefano Zampini { 1179674ae819SStefano Zampini PCBDDCGraph new_graph; 1180674ae819SStefano Zampini PetscErrorCode ierr; 1181674ae819SStefano Zampini 1182674ae819SStefano Zampini PetscFunctionBegin; 1183854ce69bSBarry Smith ierr = PetscNew(&new_graph);CHKERRQ(ierr); 1184674ae819SStefano Zampini new_graph->custom_minimal_size = 1; 1185674ae819SStefano Zampini *graph = new_graph; 1186674ae819SStefano Zampini PetscFunctionReturn(0); 1187674ae819SStefano Zampini } 1188