1af0996ceSBarry Smith #include <petsc/private/dmnetworkimpl.h> /*I "petscdmnetwork.h" I*/ 25f2c45f1SShri Abhyankar 35f2c45f1SShri Abhyankar /*@ 4556ed216SShri Abhyankar DMNetworkGetPlex - Gets the Plex DM associated with this network DM 5556ed216SShri Abhyankar 6556ed216SShri Abhyankar Not collective 7556ed216SShri Abhyankar 8556ed216SShri Abhyankar Input Parameters: 9556ed216SShri Abhyankar + netdm - the dm object 10556ed216SShri Abhyankar - plexmdm - the plex dm object 11556ed216SShri Abhyankar 12556ed216SShri Abhyankar Level: Advanced 13556ed216SShri Abhyankar 14556ed216SShri Abhyankar .seealso: DMNetworkCreate() 15556ed216SShri Abhyankar @*/ 16556ed216SShri Abhyankar PetscErrorCode DMNetworkGetPlex(DM netdm, DM *plexdm) 17556ed216SShri Abhyankar { 18556ed216SShri Abhyankar DM_Network *network = (DM_Network*) netdm->data; 19556ed216SShri Abhyankar 20556ed216SShri Abhyankar PetscFunctionBegin; 21556ed216SShri Abhyankar *plexdm = network->plex; 22556ed216SShri Abhyankar PetscFunctionReturn(0); 23556ed216SShri Abhyankar } 24556ed216SShri Abhyankar 25556ed216SShri Abhyankar /*@ 26*72c3e9f7SHong Zhang DMNetworkGetSizes - Gets the the number of subnetworks and coupling subnetworks 27*72c3e9f7SHong Zhang 28*72c3e9f7SHong Zhang Collective on dm 29*72c3e9f7SHong Zhang 30*72c3e9f7SHong Zhang Input Parameters: 31*72c3e9f7SHong Zhang + dm - the dm object 32*72c3e9f7SHong Zhang . Nsubnet - global number of subnetworks 33*72c3e9f7SHong Zhang - NsubnetCouple - global number of coupling subnetworks 34*72c3e9f7SHong Zhang 35*72c3e9f7SHong Zhang Level: Intermediate 36*72c3e9f7SHong Zhang 37*72c3e9f7SHong Zhang .seealso: DMNetworkCreate() 38*72c3e9f7SHong Zhang @*/ 39*72c3e9f7SHong Zhang PetscErrorCode DMNetworkGetSizes(DM netdm, PetscInt *Nsubnet, PetscInt *Ncsubnet) 40*72c3e9f7SHong Zhang { 41*72c3e9f7SHong Zhang DM_Network *network = (DM_Network*) netdm->data; 42*72c3e9f7SHong Zhang 43*72c3e9f7SHong Zhang PetscFunctionBegin; 44*72c3e9f7SHong Zhang *Nsubnet = network->nsubnet; 45*72c3e9f7SHong Zhang *Ncsubnet = network->ncsubnet; 46*72c3e9f7SHong Zhang PetscFunctionReturn(0); 47*72c3e9f7SHong Zhang } 48*72c3e9f7SHong Zhang 49*72c3e9f7SHong Zhang /*@ 50e2aaf10cSShri Abhyankar DMNetworkSetSizes - Sets the number of subnetworks, local and global vertices and edges for each subnetwork. 515f2c45f1SShri Abhyankar 52d083f849SBarry Smith Collective on dm 535f2c45f1SShri Abhyankar 545f2c45f1SShri Abhyankar Input Parameters: 555f2c45f1SShri Abhyankar + dm - the dm object 56caf410d2SHong Zhang . Nsubnet - global number of subnetworks 57caf410d2SHong Zhang . nV - number of local vertices for each subnetwork 58caf410d2SHong Zhang . nE - number of local edges for each subnetwork 59caf410d2SHong Zhang . NsubnetCouple - global number of coupling subnetworks 60caf410d2SHong Zhang - nec - number of local edges for each coupling subnetwork 615f2c45f1SShri Abhyankar 62caf410d2SHong Zhang You cannot change the sizes once they have been set. nV, nE are arrays of length Nsubnet, and nec is array of length NsubnetCouple. 635f2c45f1SShri Abhyankar 641b266c99SBarry Smith Level: intermediate 651b266c99SBarry Smith 661b266c99SBarry Smith .seealso: DMNetworkCreate() 675f2c45f1SShri Abhyankar @*/ 68caf410d2SHong Zhang PetscErrorCode DMNetworkSetSizes(DM dm,PetscInt Nsubnet,PetscInt nV[], PetscInt nE[],PetscInt NsubnetCouple,PetscInt nec[]) 695f2c45f1SShri Abhyankar { 705f2c45f1SShri Abhyankar PetscErrorCode ierr; 715f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 72e2aaf10cSShri Abhyankar PetscInt a[2],b[2],i; 735f2c45f1SShri Abhyankar 745f2c45f1SShri Abhyankar PetscFunctionBegin; 755f2c45f1SShri Abhyankar PetscValidHeaderSpecific(dm,DM_CLASSID,1); 76e2aaf10cSShri Abhyankar if (Nsubnet <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of subnetworks %D cannot be less than 1",Nsubnet); 777765340cSHong Zhang if (NsubnetCouple < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of coupling subnetworks %D cannot be less than 0",NsubnetCouple); 787765340cSHong Zhang 79caf410d2SHong Zhang PetscValidLogicalCollectiveInt(dm,Nsubnet,2); 80caf410d2SHong Zhang if (NsubnetCouple) PetscValidLogicalCollectiveInt(dm,NsubnetCouple,5); 817765340cSHong Zhang if (network->nsubnet != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Network sizes alread set, cannot resize the network"); 827765340cSHong Zhang 83caf410d2SHong Zhang if (!nV || !nE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Local vertex size or edge size must be provided"); 84f025b11dSHong Zhang 85caf410d2SHong Zhang network->nsubnet = Nsubnet + NsubnetCouple; 86caf410d2SHong Zhang network->ncsubnet = NsubnetCouple; 87caf410d2SHong Zhang ierr = PetscCalloc1(Nsubnet+NsubnetCouple,&network->subnet);CHKERRQ(ierr); 88caf410d2SHong Zhang 89caf410d2SHong Zhang /* ---------------------------------------------------------- 90caf410d2SHong Zhang p=v or e; P=V or E 91caf410d2SHong Zhang subnet[0].pStart = 0 92caf410d2SHong Zhang subnet[i+1].pStart = subnet[i].pEnd = subnet[i].pStart + (nE[i] or NV[i]) 93caf410d2SHong Zhang ----------------------------------------------------------------------- */ 94caf410d2SHong Zhang for (i=0; i < Nsubnet; i++) { 95caf410d2SHong Zhang /* Get global number of vertices and edges for subnet[i] */ 96caf410d2SHong Zhang a[0] = nV[i]; a[1] = nE[i]; /* local number of vertices (excluding ghost) and edges */ 977765340cSHong Zhang ierr = MPIU_Allreduce(a,b,2,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 98071fcb05SBarry Smith network->subnet[i].Nvtx = b[0]; 99071fcb05SBarry Smith network->subnet[i].Nedge = b[1]; 1007765340cSHong Zhang 101caf410d2SHong Zhang network->subnet[i].nvtx = nV[i]; /* local nvtx, without ghost */ 1027765340cSHong Zhang 103caf410d2SHong Zhang /* global subnet[].vStart and vEnd, used by DMNetworkLayoutSetUp() */ 104caf410d2SHong Zhang network->subnet[i].vStart = network->NVertices; 1057765340cSHong Zhang network->subnet[i].vEnd = network->subnet[i].vStart + network->subnet[i].Nvtx; 106caf410d2SHong Zhang 107caf410d2SHong Zhang network->nVertices += nV[i]; 1087765340cSHong Zhang network->NVertices += network->subnet[i].Nvtx; 1097765340cSHong Zhang 1107765340cSHong Zhang network->subnet[i].nedge = nE[i]; 1117765340cSHong Zhang network->subnet[i].eStart = network->nEdges; 112caf410d2SHong Zhang network->subnet[i].eEnd = network->subnet[i].eStart + nE[i]; 113caf410d2SHong Zhang network->nEdges += nE[i]; 114caf410d2SHong Zhang network->NEdges += network->subnet[i].Nedge; 115caf410d2SHong Zhang } 116caf410d2SHong Zhang 117caf410d2SHong Zhang /* coupling subnetwork */ 118caf410d2SHong Zhang for (; i < Nsubnet+NsubnetCouple; i++) { 119caf410d2SHong Zhang /* Get global number of coupling edges for subnet[i] */ 120caf410d2SHong Zhang ierr = MPIU_Allreduce(nec+(i-Nsubnet),&network->subnet[i].Nedge,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 121caf410d2SHong Zhang 122caf410d2SHong Zhang network->subnet[i].nvtx = 0; /* We design coupling subnetwork such that it does not have its own vertices */ 123caf410d2SHong Zhang network->subnet[i].vStart = network->nVertices; 124caf410d2SHong Zhang network->subnet[i].vEnd = network->subnet[i].vStart; 125caf410d2SHong Zhang 126caf410d2SHong Zhang network->subnet[i].nedge = nec[i-Nsubnet]; 127caf410d2SHong Zhang network->subnet[i].eStart = network->nEdges; 128caf410d2SHong Zhang network->subnet[i].eEnd = network->subnet[i].eStart + nec[i-Nsubnet]; 129caf410d2SHong Zhang network->nEdges += nec[i-Nsubnet]; 1307765340cSHong Zhang network->NEdges += network->subnet[i].Nedge; 1317765340cSHong Zhang } 1327765340cSHong Zhang PetscFunctionReturn(0); 1337765340cSHong Zhang } 1347765340cSHong Zhang 1355f2c45f1SShri Abhyankar /*@ 1365f2c45f1SShri Abhyankar DMNetworkSetEdgeList - Sets the list of local edges (vertex connectivity) for the network 1375f2c45f1SShri Abhyankar 138d083f849SBarry Smith Logically collective on dm 1395f2c45f1SShri Abhyankar 1405f2c45f1SShri Abhyankar Input Parameters: 141e3e68989SHong Zhang + dm - the dm object 142e3e68989SHong Zhang . edgelist - list of edges for each subnetwork 143e3e68989SHong Zhang - edgelistCouple - list of edges for each coupling subnetwork 1445f2c45f1SShri Abhyankar 1455f2c45f1SShri Abhyankar Notes: 1465f2c45f1SShri Abhyankar There is no copy involved in this operation, only the pointer is referenced. The edgelist should 1475f2c45f1SShri Abhyankar not be destroyed before the call to DMNetworkLayoutSetUp 1485f2c45f1SShri Abhyankar 1495f2c45f1SShri Abhyankar Level: intermediate 1505f2c45f1SShri Abhyankar 151e3e68989SHong Zhang Example usage: 152e3e68989SHong Zhang Consider the following 2 separate networks and a coupling network: 153e3e68989SHong Zhang 154e3e68989SHong Zhang .vb 155e3e68989SHong Zhang network 0: v0 -> v1 -> v2 -> v3 156e3e68989SHong Zhang network 1: v1 -> v2 -> v0 157e3e68989SHong Zhang coupling network: network 1: v2 -> network 0: v0 158e3e68989SHong Zhang .ve 159e3e68989SHong Zhang 160e3e68989SHong Zhang The resulting input 161e3e68989SHong Zhang edgelist[0] = [0 1 | 1 2 | 2 3]; 162e3e68989SHong Zhang edgelist[1] = [1 2 | 2 0] 163e3e68989SHong Zhang edgelistCouple[0] = [(network)1 (v)2 (network)0 (v)0]. 164e3e68989SHong Zhang 1655f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkSetSizes 1665f2c45f1SShri Abhyankar @*/ 1674e18019cSBarry Smith PetscErrorCode DMNetworkSetEdgeList(DM dm,PetscInt *edgelist[],PetscInt *edgelistCouple[]) 1685f2c45f1SShri Abhyankar { 1695f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 170*72c3e9f7SHong Zhang PetscInt i; 1715f2c45f1SShri Abhyankar 1725f2c45f1SShri Abhyankar PetscFunctionBegin; 173*72c3e9f7SHong Zhang for (i=0; i < (network->nsubnet-network->ncsubnet); i++) network->subnet[i].edgelist = edgelist[i]; 174*72c3e9f7SHong Zhang if (network->ncsubnet) { 175*72c3e9f7SHong Zhang PetscInt j = 0; 176*72c3e9f7SHong Zhang if (!edgelistCouple) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Must provide edgelist_couple"); 177*72c3e9f7SHong Zhang while (i < network->nsubnet) network->subnet[i++].edgelist = edgelistCouple[j++]; 178e3e68989SHong Zhang } 1795f2c45f1SShri Abhyankar PetscFunctionReturn(0); 1805f2c45f1SShri Abhyankar } 1815f2c45f1SShri Abhyankar 1825f2c45f1SShri Abhyankar /*@ 1835f2c45f1SShri Abhyankar DMNetworkLayoutSetUp - Sets up the bare layout (graph) for the network 1845f2c45f1SShri Abhyankar 185d083f849SBarry Smith Collective on dm 1865f2c45f1SShri Abhyankar 1875f2c45f1SShri Abhyankar Input Parameters 1885f2c45f1SShri Abhyankar . DM - the dmnetwork object 1895f2c45f1SShri Abhyankar 1905f2c45f1SShri Abhyankar Notes: 1915f2c45f1SShri Abhyankar This routine should be called after the network sizes and edgelists have been provided. It creates 1925f2c45f1SShri Abhyankar the bare layout of the network and sets up the network to begin insertion of components. 1935f2c45f1SShri Abhyankar 1945f2c45f1SShri Abhyankar All the components should be registered before calling this routine. 1955f2c45f1SShri Abhyankar 1965f2c45f1SShri Abhyankar Level: intermediate 1975f2c45f1SShri Abhyankar 1985f2c45f1SShri Abhyankar .seealso: DMNetworkSetSizes, DMNetworkSetEdgeList 1995f2c45f1SShri Abhyankar @*/ 2005f2c45f1SShri Abhyankar PetscErrorCode DMNetworkLayoutSetUp(DM dm) 2015f2c45f1SShri Abhyankar { 2025f2c45f1SShri Abhyankar PetscErrorCode ierr; 2035f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 204caf410d2SHong Zhang PetscInt numCorners=2,spacedim=2,dim = 1; /* One dimensional network */ 2053ebf9fb9SHong Zhang PetscReal *vertexcoords=NULL; 206caf410d2SHong Zhang PetscInt i,j,ctr,nsubnet,*eowners,np,*edges,*subnetvtx,vStart; 207caf410d2SHong Zhang PetscInt k,netid,vid, *vidxlTog,*edgelist_couple=NULL; 208caf410d2SHong Zhang const PetscInt *cone; 209caf410d2SHong Zhang MPI_Comm comm; 210caf410d2SHong Zhang PetscMPIInt size,rank; 2116500d4abSHong Zhang 2126500d4abSHong Zhang PetscFunctionBegin; 213caf410d2SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 214caf410d2SHong Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 215caf410d2SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 2166500d4abSHong Zhang 217caf410d2SHong Zhang /* Create the local edgelist for the network by concatenating local input edgelists of the subnetworks */ 218caf410d2SHong Zhang ierr = PetscCalloc2(numCorners*network->nVertices,&vertexcoords,2*network->nEdges,&edges);CHKERRQ(ierr); 2197765340cSHong Zhang nsubnet = network->nsubnet - network->ncsubnet; 220caf410d2SHong Zhang ctr = 0; 2217765340cSHong Zhang for (i=0; i < nsubnet; i++) { 2226500d4abSHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 223ba38b151SHong Zhang edges[2*ctr] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j]; 224ba38b151SHong Zhang edges[2*ctr+1] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j+1]; 2256500d4abSHong Zhang ctr++; 2266500d4abSHong Zhang } 2276500d4abSHong Zhang } 2287765340cSHong Zhang 229caf410d2SHong Zhang /* Append local coupling edgelists of the subnetworks */ 2307765340cSHong Zhang i = nsubnet; /* netid of coupling subnet */ 2317765340cSHong Zhang nsubnet = network->nsubnet; 2327765340cSHong Zhang while (i < nsubnet) { 233991cf414SHong Zhang edgelist_couple = network->subnet[i].edgelist; 234*72c3e9f7SHong Zhang 2356500d4abSHong Zhang k = 0; 2366500d4abSHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 2376500d4abSHong Zhang netid = edgelist_couple[k]; vid = edgelist_couple[k+1]; 238caf410d2SHong Zhang edges[2*ctr] = network->subnet[netid].vStart + vid; k += 2; 2396500d4abSHong Zhang 2406500d4abSHong Zhang netid = edgelist_couple[k]; vid = edgelist_couple[k+1]; 241caf410d2SHong Zhang edges[2*ctr+1] = network->subnet[netid].vStart + vid; k+=2; 2426500d4abSHong Zhang ctr++; 2436500d4abSHong Zhang } 2447765340cSHong Zhang i++; 2457765340cSHong Zhang } 246caf410d2SHong Zhang /* 247caf410d2SHong Zhang if (rank == 0) { 248caf410d2SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"[%d] edgelist:\n",rank); 2496500d4abSHong Zhang for(i=0; i < network->nEdges; i++) { 250caf410d2SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"[%D %D]",edges[2*i],edges[2*i+1]);CHKERRQ(ierr); 2516500d4abSHong Zhang printf("\n"); 2526500d4abSHong Zhang } 253caf410d2SHong Zhang } 254caf410d2SHong Zhang */ 2556500d4abSHong Zhang 256caf410d2SHong Zhang /* Create network->plex */ 257acdb140fSBarry Smith #if defined(PETSC_USE_64BIT_INDICES) 258acdb140fSBarry Smith { 259caf410d2SHong Zhang int *edges64; 260caf410d2SHong Zhang np = network->nEdges*numCorners; 261caf410d2SHong Zhang ierr = PetscMalloc1(np,&edges64);CHKERRQ(ierr); 262caf410d2SHong Zhang for (i=0; i<np; i++) edges64[i] = (int)edges[i]; 263caf410d2SHong Zhang 264caf410d2SHong Zhang if (size == 1) { 265caf410d2SHong Zhang ierr = DMPlexCreateFromCellList(comm,dim,network->nEdges,network->nVertices,numCorners,PETSC_FALSE,(const int*)edges64,spacedim,(const double*)vertexcoords,&network->plex);CHKERRQ(ierr); 266caf410d2SHong Zhang } else { 2673ebf9fb9SHong Zhang ierr = DMPlexCreateFromCellListParallel(comm,dim,network->nEdges,network->nVertices,numCorners,PETSC_FALSE,(const int*)edges64,spacedim,(const PetscReal*)vertexcoords,NULL,&network->plex);CHKERRQ(ierr); 268acdb140fSBarry Smith } 269caf410d2SHong Zhang ierr = PetscFree(edges64);CHKERRQ(ierr); 270acdb140fSBarry Smith } 271acdb140fSBarry Smith #else 272caf410d2SHong Zhang if (size == 1) { 273caf410d2SHong Zhang ierr = DMPlexCreateFromCellList(comm,dim,network->nEdges,network->nVertices,numCorners,PETSC_FALSE,(const int*)edges,spacedim,(const double*)vertexcoords,&network->plex);CHKERRQ(ierr); 274caf410d2SHong Zhang } else { 2753ebf9fb9SHong Zhang ierr = DMPlexCreateFromCellListParallel(comm,dim,network->nEdges,network->nVertices,numCorners,PETSC_FALSE,(const int*)edges,spacedim,(const PetscReal*)vertexcoords,NULL,&network->plex);CHKERRQ(ierr); 2766500d4abSHong Zhang } 277caf410d2SHong Zhang #endif 2786500d4abSHong Zhang 2796500d4abSHong Zhang ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr); 2806500d4abSHong Zhang ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr); 2816500d4abSHong Zhang ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr); 282caf410d2SHong Zhang vStart = network->vStart; 2836500d4abSHong Zhang 284caf410d2SHong Zhang ierr = PetscSectionCreate(comm,&network->DataSection);CHKERRQ(ierr); 285caf410d2SHong Zhang ierr = PetscSectionCreate(comm,&network->DofSection);CHKERRQ(ierr); 2866500d4abSHong Zhang ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr); 2876500d4abSHong Zhang ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr); 2886500d4abSHong Zhang 289caf410d2SHong Zhang network->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 290caf410d2SHong Zhang np = network->pEnd - network->pStart; 291caf410d2SHong Zhang ierr = PetscCalloc2(np,&network->header,np,&network->cvalue);CHKERRQ(ierr); 292caf410d2SHong Zhang 293caf410d2SHong Zhang /* Create vidxlTog: maps local vertex index to global index */ 294caf410d2SHong Zhang np = network->vEnd - vStart; 295caf410d2SHong Zhang ierr = PetscMalloc2(np,&vidxlTog,size+1,&eowners);CHKERRQ(ierr); 296caf410d2SHong Zhang ctr = 0; 297caf410d2SHong Zhang for (i=network->eStart; i<network->eEnd; i++) { 298caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,i,&cone);CHKERRQ(ierr); 299caf410d2SHong Zhang vidxlTog[cone[0] - vStart] = edges[2*ctr]; 300caf410d2SHong Zhang vidxlTog[cone[1] - vStart] = edges[2*ctr+1]; 301caf410d2SHong Zhang ctr++; 302caf410d2SHong Zhang } 303caf410d2SHong Zhang ierr = PetscFree2(vertexcoords,edges);CHKERRQ(ierr); 304caf410d2SHong Zhang 3056500d4abSHong Zhang /* Create vertices and edges array for the subnetworks */ 3066500d4abSHong Zhang for (j=0; j < network->nsubnet; j++) { 3076500d4abSHong Zhang ierr = PetscCalloc1(network->subnet[j].nedge,&network->subnet[j].edges);CHKERRQ(ierr); 308caf410d2SHong Zhang 3096500d4abSHong Zhang /* Temporarily setting nvtx and nedge to 0 so we can use them as counters in the below for loop. 3106500d4abSHong Zhang These get updated when the vertices and edges are added. */ 311caf410d2SHong Zhang network->subnet[j].nvtx = 0; 312caf410d2SHong Zhang network->subnet[j].nedge = 0; 3136500d4abSHong Zhang } 314caf410d2SHong Zhang ierr = PetscCalloc1(np,&network->subnetvtx);CHKERRQ(ierr); 3156500d4abSHong Zhang 316caf410d2SHong Zhang 317caf410d2SHong Zhang /* Get edge ownership */ 318caf410d2SHong Zhang np = network->eEnd - network->eStart; 319caf410d2SHong Zhang ierr = MPI_Allgather(&np,1,MPIU_INT,eowners+1,1,MPIU_INT,comm);CHKERRQ(ierr); 320caf410d2SHong Zhang eowners[0] = 0; 321caf410d2SHong Zhang for (i=2; i<=size; i++) eowners[i] += eowners[i-1]; 322caf410d2SHong Zhang 323caf410d2SHong Zhang i = 0; j = 0; 324caf410d2SHong Zhang while (i < np) { /* local edges, including coupling edges */ 325caf410d2SHong Zhang network->header[i].index = i + eowners[rank]; /* Global edge index */ 326caf410d2SHong Zhang 327caf410d2SHong Zhang if (j < network->nsubnet && i < network->subnet[j].eEnd) { 3286500d4abSHong Zhang network->header[i].subnetid = j; /* Subnetwork id */ 3296500d4abSHong Zhang network->subnet[j].edges[network->subnet[j].nedge++] = i; 330caf410d2SHong Zhang 331caf410d2SHong Zhang network->header[i].ndata = 0; 332caf410d2SHong Zhang ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr); 333caf410d2SHong Zhang network->header[i].offset[0] = 0; 334caf410d2SHong Zhang i++; 335caf410d2SHong Zhang } 336caf410d2SHong Zhang if (i >= network->subnet[j].eEnd) j++; 337caf410d2SHong Zhang } 338caf410d2SHong Zhang 339caf410d2SHong Zhang /* Count network->subnet[*].nvtx */ 340caf410d2SHong Zhang for (i=vStart; i<network->vEnd; i++) { /* local vertices, including ghosts */ 341caf410d2SHong Zhang k = vidxlTog[i-vStart]; 342caf410d2SHong Zhang for (j=0; j < network->nsubnet; j++) { 343caf410d2SHong Zhang if (network->subnet[j].vStart <= k && k < network->subnet[j].vEnd) { 344caf410d2SHong Zhang network->subnet[j].nvtx++; 3456500d4abSHong Zhang break; 3466500d4abSHong Zhang } 3476500d4abSHong Zhang } 3486500d4abSHong Zhang } 3496500d4abSHong Zhang 350caf410d2SHong Zhang /* Set network->subnet[*].vertices on array network->subnetvtx */ 351caf410d2SHong Zhang subnetvtx = network->subnetvtx; 3526500d4abSHong Zhang for (j=0; j<network->nsubnet; j++) { 353caf410d2SHong Zhang network->subnet[j].vertices = subnetvtx; 354caf410d2SHong Zhang subnetvtx += network->subnet[j].nvtx; 355caf410d2SHong Zhang network->subnet[j].nvtx = 0; 356caf410d2SHong Zhang } 357caf410d2SHong Zhang 358caf410d2SHong Zhang /* Set vertex array for the subnetworks */ 359caf410d2SHong Zhang for (i=vStart; i<network->vEnd; i++) { /* local vertices, including ghosts */ 360caf410d2SHong Zhang network->header[i].index = vidxlTog[i-vStart]; /* Global vertex index */ 361caf410d2SHong Zhang 362caf410d2SHong Zhang k = vidxlTog[i-vStart]; 363caf410d2SHong Zhang for (j=0; j < network->nsubnet; j++) { 364caf410d2SHong Zhang if (network->subnet[j].vStart <= k && k < network->subnet[j].vEnd) { 3656500d4abSHong Zhang network->header[i].subnetid = j; 3666500d4abSHong Zhang network->subnet[j].vertices[network->subnet[j].nvtx++] = i; 3676500d4abSHong Zhang break; 3686500d4abSHong Zhang } 3696500d4abSHong Zhang } 370caf410d2SHong Zhang 3716500d4abSHong Zhang network->header[i].ndata = 0; 3726500d4abSHong Zhang ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr); 373caf410d2SHong Zhang network->header[i].offset[0] = 0; 3746500d4abSHong Zhang } 3756500d4abSHong Zhang 376caf410d2SHong Zhang ierr = PetscFree2(vidxlTog,eowners);CHKERRQ(ierr); 3775f2c45f1SShri Abhyankar PetscFunctionReturn(0); 3785f2c45f1SShri Abhyankar } 3795f2c45f1SShri Abhyankar 38094ef8ddeSSatish Balay /*@C 3812727e31bSShri Abhyankar DMNetworkGetSubnetworkInfo - Returns the info for the subnetwork 3822727e31bSShri Abhyankar 3832727e31bSShri Abhyankar Input Parameters 384caf410d2SHong Zhang + dm - the DM object 3852727e31bSShri Abhyankar - id - the ID (integer) of the subnetwork 3862727e31bSShri Abhyankar 3872727e31bSShri Abhyankar Output Parameters 3882727e31bSShri Abhyankar + nv - number of vertices (local) 3892727e31bSShri Abhyankar . ne - number of edges (local) 3902727e31bSShri Abhyankar . vtx - local vertices for this subnetwork 391a2b725a8SWilliam Gropp - edge - local edges for this subnetwork 3922727e31bSShri Abhyankar 3932727e31bSShri Abhyankar Notes: 3942727e31bSShri Abhyankar Cannot call this routine before DMNetworkLayoutSetup() 3952727e31bSShri Abhyankar 39606dd6b0eSSatish Balay Level: intermediate 39706dd6b0eSSatish Balay 3982727e31bSShri Abhyankar .seealso: DMNetworkLayoutSetUp, DMNetworkCreate 3992727e31bSShri Abhyankar @*/ 400caf410d2SHong Zhang PetscErrorCode DMNetworkGetSubnetworkInfo(DM dm,PetscInt id,PetscInt *nv, PetscInt *ne,const PetscInt **vtx, const PetscInt **edge) 4012727e31bSShri Abhyankar { 402caf410d2SHong Zhang DM_Network *network = (DM_Network*)dm->data; 4032727e31bSShri Abhyankar 4042727e31bSShri Abhyankar PetscFunctionBegin; 405*72c3e9f7SHong Zhang if (id >= network->nsubnet) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Subnet ID %D exceeds the num of subnets %D",id,network->nsubnet); 4062727e31bSShri Abhyankar *nv = network->subnet[id].nvtx; 4072727e31bSShri Abhyankar *ne = network->subnet[id].nedge; 4082727e31bSShri Abhyankar *vtx = network->subnet[id].vertices; 4092727e31bSShri Abhyankar *edge = network->subnet[id].edges; 4102727e31bSShri Abhyankar PetscFunctionReturn(0); 4112727e31bSShri Abhyankar } 4122727e31bSShri Abhyankar 4132727e31bSShri Abhyankar /*@C 414caf410d2SHong Zhang DMNetworkGetSubnetworkCoupleInfo - Returns the info for the coupling subnetwork 415caf410d2SHong Zhang 416caf410d2SHong Zhang Input Parameters 417caf410d2SHong Zhang + dm - the DM object 418caf410d2SHong Zhang - id - the ID (integer) of the coupling subnetwork 419caf410d2SHong Zhang 420caf410d2SHong Zhang Output Parameters 421caf410d2SHong Zhang + ne - number of edges (local) 422caf410d2SHong Zhang - edge - local edges for this coupling subnetwork 423caf410d2SHong Zhang 424caf410d2SHong Zhang Notes: 425caf410d2SHong Zhang Cannot call this routine before DMNetworkLayoutSetup() 426caf410d2SHong Zhang 427caf410d2SHong Zhang Level: intermediate 428caf410d2SHong Zhang 429caf410d2SHong Zhang .seealso: DMNetworkGetSubnetworkInfo, DMNetworkLayoutSetUp, DMNetworkCreate 430caf410d2SHong Zhang @*/ 431caf410d2SHong Zhang PetscErrorCode DMNetworkGetSubnetworkCoupleInfo(DM dm,PetscInt id,PetscInt *ne,const PetscInt **edge) 432caf410d2SHong Zhang { 433caf410d2SHong Zhang DM_Network *net = (DM_Network*)dm->data; 434*72c3e9f7SHong Zhang PetscInt id1; 435caf410d2SHong Zhang 436caf410d2SHong Zhang PetscFunctionBegin; 437*72c3e9f7SHong Zhang if (net->ncsubnet) { 438*72c3e9f7SHong Zhang if (id >= net->ncsubnet) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Subnet ID %D exceeds the num of coupling subnets %D",id,net->ncsubnet); 439*72c3e9f7SHong Zhang 440*72c3e9f7SHong Zhang id1 = id + net->nsubnet - net->ncsubnet; 441caf410d2SHong Zhang *ne = net->subnet[id1].nedge; 442caf410d2SHong Zhang *edge = net->subnet[id1].edges; 443*72c3e9f7SHong Zhang } else { 444*72c3e9f7SHong Zhang *ne = 0; 445*72c3e9f7SHong Zhang *edge = NULL; 446*72c3e9f7SHong Zhang } 447caf410d2SHong Zhang PetscFunctionReturn(0); 448caf410d2SHong Zhang } 449caf410d2SHong Zhang 450caf410d2SHong Zhang /*@C 4515f2c45f1SShri Abhyankar DMNetworkRegisterComponent - Registers the network component 4525f2c45f1SShri Abhyankar 453d083f849SBarry Smith Logically collective on dm 4545f2c45f1SShri Abhyankar 4555f2c45f1SShri Abhyankar Input Parameters 4565f2c45f1SShri Abhyankar + dm - the network object 4575f2c45f1SShri Abhyankar . name - the component name 4585f2c45f1SShri Abhyankar - size - the storage size in bytes for this component data 4595f2c45f1SShri Abhyankar 4605f2c45f1SShri Abhyankar Output Parameters 4615f2c45f1SShri Abhyankar . key - an integer key that defines the component 4625f2c45f1SShri Abhyankar 4635f2c45f1SShri Abhyankar Notes 4645f2c45f1SShri Abhyankar This routine should be called by all processors before calling DMNetworkLayoutSetup(). 4655f2c45f1SShri Abhyankar 4665f2c45f1SShri Abhyankar Level: intermediate 4675f2c45f1SShri Abhyankar 4685f2c45f1SShri Abhyankar .seealso: DMNetworkLayoutSetUp, DMNetworkCreate 4695f2c45f1SShri Abhyankar @*/ 470caf410d2SHong Zhang PetscErrorCode DMNetworkRegisterComponent(DM dm,const char *name,size_t size,PetscInt *key) 4715f2c45f1SShri Abhyankar { 4725f2c45f1SShri Abhyankar PetscErrorCode ierr; 4735f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 4745f2c45f1SShri Abhyankar DMNetworkComponent *component=&network->component[network->ncomponent]; 4755f2c45f1SShri Abhyankar PetscBool flg=PETSC_FALSE; 4765f2c45f1SShri Abhyankar PetscInt i; 4775f2c45f1SShri Abhyankar 4785f2c45f1SShri Abhyankar PetscFunctionBegin; 4795f2c45f1SShri Abhyankar for (i=0; i < network->ncomponent; i++) { 4805f2c45f1SShri Abhyankar ierr = PetscStrcmp(component->name,name,&flg);CHKERRQ(ierr); 4815f2c45f1SShri Abhyankar if (flg) { 4825f2c45f1SShri Abhyankar *key = i; 4835f2c45f1SShri Abhyankar PetscFunctionReturn(0); 4845f2c45f1SShri Abhyankar } 4856d64e262SShri Abhyankar } 4866d64e262SShri Abhyankar if(network->ncomponent == MAX_COMPONENTS) { 4876d64e262SShri Abhyankar SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Number of components registered exceeds the max %D",MAX_COMPONENTS); 4885f2c45f1SShri Abhyankar } 4895f2c45f1SShri Abhyankar 4905f2c45f1SShri Abhyankar ierr = PetscStrcpy(component->name,name);CHKERRQ(ierr); 4915f2c45f1SShri Abhyankar component->size = size/sizeof(DMNetworkComponentGenericDataType); 4925f2c45f1SShri Abhyankar *key = network->ncomponent; 4935f2c45f1SShri Abhyankar network->ncomponent++; 4945f2c45f1SShri Abhyankar PetscFunctionReturn(0); 4955f2c45f1SShri Abhyankar } 4965f2c45f1SShri Abhyankar 4975f2c45f1SShri Abhyankar /*@ 4985f2c45f1SShri Abhyankar DMNetworkGetVertexRange - Get the bounds [start, end) for the vertices. 4995f2c45f1SShri Abhyankar 5005f2c45f1SShri Abhyankar Not Collective 5015f2c45f1SShri Abhyankar 5025f2c45f1SShri Abhyankar Input Parameters: 503a2b725a8SWilliam Gropp . dm - The DMNetwork object 5045f2c45f1SShri Abhyankar 5055f2c45f1SShri Abhyankar Output Paramters: 5065f2c45f1SShri Abhyankar + vStart - The first vertex point 5075f2c45f1SShri Abhyankar - vEnd - One beyond the last vertex point 5085f2c45f1SShri Abhyankar 5095f2c45f1SShri Abhyankar Level: intermediate 5105f2c45f1SShri Abhyankar 5115f2c45f1SShri Abhyankar .seealso: DMNetworkGetEdgeRange 5125f2c45f1SShri Abhyankar @*/ 5135f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVertexRange(DM dm,PetscInt *vStart,PetscInt *vEnd) 5145f2c45f1SShri Abhyankar { 5155f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 5165f2c45f1SShri Abhyankar 5175f2c45f1SShri Abhyankar PetscFunctionBegin; 5185f2c45f1SShri Abhyankar if (vStart) *vStart = network->vStart; 5195f2c45f1SShri Abhyankar if (vEnd) *vEnd = network->vEnd; 5205f2c45f1SShri Abhyankar PetscFunctionReturn(0); 5215f2c45f1SShri Abhyankar } 5225f2c45f1SShri Abhyankar 5235f2c45f1SShri Abhyankar /*@ 5245f2c45f1SShri Abhyankar DMNetworkGetEdgeRange - Get the bounds [start, end) for the edges. 5255f2c45f1SShri Abhyankar 5265f2c45f1SShri Abhyankar Not Collective 5275f2c45f1SShri Abhyankar 5285f2c45f1SShri Abhyankar Input Parameters: 529a2b725a8SWilliam Gropp . dm - The DMNetwork object 5305f2c45f1SShri Abhyankar 5315f2c45f1SShri Abhyankar Output Paramters: 5325f2c45f1SShri Abhyankar + eStart - The first edge point 5335f2c45f1SShri Abhyankar - eEnd - One beyond the last edge point 5345f2c45f1SShri Abhyankar 5355f2c45f1SShri Abhyankar Level: intermediate 5365f2c45f1SShri Abhyankar 5375f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange 5385f2c45f1SShri Abhyankar @*/ 5395f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetEdgeRange(DM dm,PetscInt *eStart,PetscInt *eEnd) 5405f2c45f1SShri Abhyankar { 5415f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 5425f2c45f1SShri Abhyankar 5435f2c45f1SShri Abhyankar PetscFunctionBegin; 5445f2c45f1SShri Abhyankar if (eStart) *eStart = network->eStart; 5455f2c45f1SShri Abhyankar if (eEnd) *eEnd = network->eEnd; 5465f2c45f1SShri Abhyankar PetscFunctionReturn(0); 5475f2c45f1SShri Abhyankar } 5485f2c45f1SShri Abhyankar 5497b6afd5bSHong Zhang /*@ 550e85e6aecSHong Zhang DMNetworkGetGlobalEdgeIndex - Get the user global numbering for the edge. 5517b6afd5bSHong Zhang 5527b6afd5bSHong Zhang Not Collective 5537b6afd5bSHong Zhang 5547b6afd5bSHong Zhang Input Parameters: 5557b6afd5bSHong Zhang + dm - DMNetwork object 556e85e6aecSHong Zhang - p - edge point 5577b6afd5bSHong Zhang 5587b6afd5bSHong Zhang Output Paramters: 559e85e6aecSHong Zhang . index - user global numbering for the edge 5607b6afd5bSHong Zhang 5617b6afd5bSHong Zhang Level: intermediate 5627b6afd5bSHong Zhang 563e85e6aecSHong Zhang .seealso: DMNetworkGetGlobalVertexIndex 5647b6afd5bSHong Zhang @*/ 565e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalEdgeIndex(DM dm,PetscInt p,PetscInt *index) 5667b6afd5bSHong Zhang { 5677b6afd5bSHong Zhang PetscErrorCode ierr; 5687b6afd5bSHong Zhang DM_Network *network = (DM_Network*)dm->data; 5697b6afd5bSHong Zhang PetscInt offsetp; 5707b6afd5bSHong Zhang DMNetworkComponentHeader header; 5717b6afd5bSHong Zhang 5727b6afd5bSHong Zhang PetscFunctionBegin; 573caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 5747b6afd5bSHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 5757b6afd5bSHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 576e85e6aecSHong Zhang *index = header->index; 5777b6afd5bSHong Zhang PetscFunctionReturn(0); 5787b6afd5bSHong Zhang } 5797b6afd5bSHong Zhang 5805f2c45f1SShri Abhyankar /*@ 581e85e6aecSHong Zhang DMNetworkGetGlobalVertexIndex - Get the user global numbering for the vertex. 582e85e6aecSHong Zhang 583e85e6aecSHong Zhang Not Collective 584e85e6aecSHong Zhang 585e85e6aecSHong Zhang Input Parameters: 586e85e6aecSHong Zhang + dm - DMNetwork object 587e85e6aecSHong Zhang - p - vertex point 588e85e6aecSHong Zhang 589e85e6aecSHong Zhang Output Paramters: 590e85e6aecSHong Zhang . index - user global numbering for the vertex 591e85e6aecSHong Zhang 592e85e6aecSHong Zhang Level: intermediate 593e85e6aecSHong Zhang 594e85e6aecSHong Zhang .seealso: DMNetworkGetGlobalEdgeIndex 595e85e6aecSHong Zhang @*/ 596e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalVertexIndex(DM dm,PetscInt p,PetscInt *index) 597e85e6aecSHong Zhang { 598e85e6aecSHong Zhang PetscErrorCode ierr; 599e85e6aecSHong Zhang DM_Network *network = (DM_Network*)dm->data; 600e85e6aecSHong Zhang PetscInt offsetp; 601e85e6aecSHong Zhang DMNetworkComponentHeader header; 602e85e6aecSHong Zhang 603e85e6aecSHong Zhang PetscFunctionBegin; 604caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 605e85e6aecSHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 606e85e6aecSHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 607e85e6aecSHong Zhang *index = header->index; 608e85e6aecSHong Zhang PetscFunctionReturn(0); 609e85e6aecSHong Zhang } 610e85e6aecSHong Zhang 611c3b11c7cSShri Abhyankar /* 612c3b11c7cSShri Abhyankar DMNetworkGetComponentKeyOffset - Gets the type along with the offset for indexing the 613c3b11c7cSShri Abhyankar component value from the component data array 614c3b11c7cSShri Abhyankar 615c3b11c7cSShri Abhyankar Not Collective 616c3b11c7cSShri Abhyankar 617c3b11c7cSShri Abhyankar Input Parameters: 618c3b11c7cSShri Abhyankar + dm - The DMNetwork object 619c3b11c7cSShri Abhyankar . p - vertex/edge point 620c3b11c7cSShri Abhyankar - compnum - component number 621c3b11c7cSShri Abhyankar 622c3b11c7cSShri Abhyankar Output Parameters: 623c3b11c7cSShri Abhyankar + compkey - the key obtained when registering the component 624c3b11c7cSShri Abhyankar - offset - offset into the component data array associated with the vertex/edge point 625c3b11c7cSShri Abhyankar 626c3b11c7cSShri Abhyankar Notes: 627c3b11c7cSShri Abhyankar Typical usage: 628c3b11c7cSShri Abhyankar 629c3b11c7cSShri Abhyankar DMNetworkGetComponentDataArray(dm, &arr); 630c3b11c7cSShri Abhyankar DMNetworkGetVertex/EdgeRange(dm,&Start,&End); 631c3b11c7cSShri Abhyankar Loop over vertices or edges 632c3b11c7cSShri Abhyankar DMNetworkGetNumComponents(dm,v,&numcomps); 633c3b11c7cSShri Abhyankar Loop over numcomps 634c3b11c7cSShri Abhyankar DMNetworkGetComponentKeyOffset(dm,v,compnum,&key,&offset); 635c3b11c7cSShri Abhyankar compdata = (UserCompDataType)(arr+offset); 636c3b11c7cSShri Abhyankar 637c3b11c7cSShri Abhyankar Level: intermediate 638c3b11c7cSShri Abhyankar 639c3b11c7cSShri Abhyankar .seealso: DMNetworkGetNumComponents, DMNetworkGetComponentDataArray, 640c3b11c7cSShri Abhyankar */ 641c3b11c7cSShri Abhyankar PetscErrorCode DMNetworkGetComponentKeyOffset(DM dm,PetscInt p, PetscInt compnum, PetscInt *compkey, PetscInt *offset) 642c3b11c7cSShri Abhyankar { 643c3b11c7cSShri Abhyankar PetscErrorCode ierr; 644c3b11c7cSShri Abhyankar PetscInt offsetp; 645c3b11c7cSShri Abhyankar DMNetworkComponentHeader header; 646c3b11c7cSShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 647c3b11c7cSShri Abhyankar 648c3b11c7cSShri Abhyankar PetscFunctionBegin; 649c3b11c7cSShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 650c3b11c7cSShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 651c3b11c7cSShri Abhyankar if (compkey) *compkey = header->key[compnum]; 652c3b11c7cSShri Abhyankar if (offset) *offset = offsetp+network->dataheadersize+header->offset[compnum]; 653c3b11c7cSShri Abhyankar PetscFunctionReturn(0); 654c3b11c7cSShri Abhyankar } 655c3b11c7cSShri Abhyankar 656c3b11c7cSShri Abhyankar /*@ 657c3b11c7cSShri Abhyankar DMNetworkGetComponent - Returns the network component and its key 658c3b11c7cSShri Abhyankar 659c3b11c7cSShri Abhyankar Not Collective 660c3b11c7cSShri Abhyankar 661c3b11c7cSShri Abhyankar Input Parameters 662c3b11c7cSShri Abhyankar + dm - DMNetwork object 663c3b11c7cSShri Abhyankar . p - edge or vertex point 664c3b11c7cSShri Abhyankar - compnum - component number 665c3b11c7cSShri Abhyankar 666c3b11c7cSShri Abhyankar Output Parameters: 667c3b11c7cSShri Abhyankar + compkey - the key set for this computing during registration 668c3b11c7cSShri Abhyankar - component - the component data 669c3b11c7cSShri Abhyankar 670c3b11c7cSShri Abhyankar Notes: 671c3b11c7cSShri Abhyankar Typical usage: 672c3b11c7cSShri Abhyankar 673c3b11c7cSShri Abhyankar DMNetworkGetVertex/EdgeRange(dm,&Start,&End); 674c3b11c7cSShri Abhyankar Loop over vertices or edges 675c3b11c7cSShri Abhyankar DMNetworkGetNumComponents(dm,v,&numcomps); 676c3b11c7cSShri Abhyankar Loop over numcomps 677c3b11c7cSShri Abhyankar DMNetworkGetComponent(dm,v,compnum,&key,&component); 678c3b11c7cSShri Abhyankar 679c3b11c7cSShri Abhyankar Level: intermediate 680c3b11c7cSShri Abhyankar 681c3b11c7cSShri Abhyankar .seealso: DMNetworkGetNumComponents, DMNetworkGetVariableOffset 682c3b11c7cSShri Abhyankar @*/ 683c3b11c7cSShri Abhyankar PetscErrorCode DMNetworkGetComponent(DM dm, PetscInt p, PetscInt compnum, PetscInt *key, void **component) 684c3b11c7cSShri Abhyankar { 685c3b11c7cSShri Abhyankar PetscErrorCode ierr; 686c3b11c7cSShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 687e108cb99SStefano Zampini PetscInt offsetd = 0; 688c3b11c7cSShri Abhyankar 689c3b11c7cSShri Abhyankar PetscFunctionBegin; 690c3b11c7cSShri Abhyankar ierr = DMNetworkGetComponentKeyOffset(dm,p,compnum,key,&offsetd);CHKERRQ(ierr); 691c3b11c7cSShri Abhyankar *component = network->componentdataarray+offsetd; 692c3b11c7cSShri Abhyankar PetscFunctionReturn(0); 693c3b11c7cSShri Abhyankar } 694c3b11c7cSShri Abhyankar 695e85e6aecSHong Zhang /*@ 696325661f6SSatish Balay DMNetworkAddComponent - Adds a network component at the given point (vertex/edge) 6975f2c45f1SShri Abhyankar 6985f2c45f1SShri Abhyankar Not Collective 6995f2c45f1SShri Abhyankar 7005f2c45f1SShri Abhyankar Input Parameters: 7015f2c45f1SShri Abhyankar + dm - The DMNetwork object 7025f2c45f1SShri Abhyankar . p - vertex/edge point 7035f2c45f1SShri Abhyankar . componentkey - component key returned while registering the component 7045f2c45f1SShri Abhyankar - compvalue - pointer to the data structure for the component 7055f2c45f1SShri Abhyankar 7065f2c45f1SShri Abhyankar Level: intermediate 7075f2c45f1SShri Abhyankar 7085f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange, DMNetworkGetEdgeRange, DMNetworkRegisterComponent 7095f2c45f1SShri Abhyankar @*/ 7105f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddComponent(DM dm, PetscInt p,PetscInt componentkey,void* compvalue) 7115f2c45f1SShri Abhyankar { 7125f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 71343a39a44SBarry Smith DMNetworkComponent *component = &network->component[componentkey]; 7145f2c45f1SShri Abhyankar DMNetworkComponentHeader header = &network->header[p]; 7155f2c45f1SShri Abhyankar DMNetworkComponentValue cvalue = &network->cvalue[p]; 7165f2c45f1SShri Abhyankar PetscErrorCode ierr; 7175f2c45f1SShri Abhyankar 7185f2c45f1SShri Abhyankar PetscFunctionBegin; 719fa58f0a9SHong Zhang if (header->ndata == MAX_DATA_AT_POINT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Number of components at a point exceeds the max %D",MAX_DATA_AT_POINT); 720fa58f0a9SHong Zhang 72143a39a44SBarry Smith header->size[header->ndata] = component->size; 72243a39a44SBarry Smith ierr = PetscSectionAddDof(network->DataSection,p,component->size);CHKERRQ(ierr); 7235f2c45f1SShri Abhyankar header->key[header->ndata] = componentkey; 7245f2c45f1SShri Abhyankar if (header->ndata != 0) header->offset[header->ndata] = header->offset[header->ndata-1] + header->size[header->ndata-1]; 7255f2c45f1SShri Abhyankar 7265f2c45f1SShri Abhyankar cvalue->data[header->ndata] = (void*)compvalue; 7275f2c45f1SShri Abhyankar header->ndata++; 7285f2c45f1SShri Abhyankar PetscFunctionReturn(0); 7295f2c45f1SShri Abhyankar } 7305f2c45f1SShri Abhyankar 7315f2c45f1SShri Abhyankar /*@ 7325f2c45f1SShri Abhyankar DMNetworkGetNumComponents - Get the number of components at a vertex/edge 7335f2c45f1SShri Abhyankar 7345f2c45f1SShri Abhyankar Not Collective 7355f2c45f1SShri Abhyankar 7365f2c45f1SShri Abhyankar Input Parameters: 7375f2c45f1SShri Abhyankar + dm - The DMNetwork object 738a2b725a8SWilliam Gropp - p - vertex/edge point 7395f2c45f1SShri Abhyankar 7405f2c45f1SShri Abhyankar Output Parameters: 7415f2c45f1SShri Abhyankar . numcomponents - Number of components at the vertex/edge 7425f2c45f1SShri Abhyankar 7435f2c45f1SShri Abhyankar Level: intermediate 7445f2c45f1SShri Abhyankar 7455f2c45f1SShri Abhyankar .seealso: DMNetworkRegisterComponent, DMNetworkAddComponent 7465f2c45f1SShri Abhyankar @*/ 7475f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents) 7485f2c45f1SShri Abhyankar { 7495f2c45f1SShri Abhyankar PetscErrorCode ierr; 7505f2c45f1SShri Abhyankar PetscInt offset; 7515f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 7525f2c45f1SShri Abhyankar 7535f2c45f1SShri Abhyankar PetscFunctionBegin; 7545f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 7555f2c45f1SShri Abhyankar *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 7565f2c45f1SShri Abhyankar PetscFunctionReturn(0); 7575f2c45f1SShri Abhyankar } 7585f2c45f1SShri Abhyankar 7595f2c45f1SShri Abhyankar /*@ 7605f2c45f1SShri Abhyankar DMNetworkGetVariableOffset - Get the offset for accessing the variable associated with the given vertex/edge from the local vector. 7615f2c45f1SShri Abhyankar 7625f2c45f1SShri Abhyankar Not Collective 7635f2c45f1SShri Abhyankar 7645f2c45f1SShri Abhyankar Input Parameters: 7655f2c45f1SShri Abhyankar + dm - The DMNetwork object 7665f2c45f1SShri Abhyankar - p - the edge/vertex point 7675f2c45f1SShri Abhyankar 7685f2c45f1SShri Abhyankar Output Parameters: 7695f2c45f1SShri Abhyankar . offset - the offset 7705f2c45f1SShri Abhyankar 7715f2c45f1SShri Abhyankar Level: intermediate 7725f2c45f1SShri Abhyankar 7735f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 7745f2c45f1SShri Abhyankar @*/ 7755f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableOffset(DM dm,PetscInt p,PetscInt *offset) 7765f2c45f1SShri Abhyankar { 7775f2c45f1SShri Abhyankar PetscErrorCode ierr; 7785f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 7795f2c45f1SShri Abhyankar 7805f2c45f1SShri Abhyankar PetscFunctionBegin; 7811bb6d2a8SBarry Smith ierr = PetscSectionGetOffset(network->plex->localSection,p,offset);CHKERRQ(ierr); 7825f2c45f1SShri Abhyankar PetscFunctionReturn(0); 7835f2c45f1SShri Abhyankar } 7845f2c45f1SShri Abhyankar 7855f2c45f1SShri Abhyankar /*@ 7865f2c45f1SShri Abhyankar DMNetworkGetVariableGlobalOffset - Get the global offset for the variable associated with the given vertex/edge from the global vector. 7875f2c45f1SShri Abhyankar 7885f2c45f1SShri Abhyankar Not Collective 7895f2c45f1SShri Abhyankar 7905f2c45f1SShri Abhyankar Input Parameters: 7915f2c45f1SShri Abhyankar + dm - The DMNetwork object 7925f2c45f1SShri Abhyankar - p - the edge/vertex point 7935f2c45f1SShri Abhyankar 7945f2c45f1SShri Abhyankar Output Parameters: 7955f2c45f1SShri Abhyankar . offsetg - the offset 7965f2c45f1SShri Abhyankar 7975f2c45f1SShri Abhyankar Level: intermediate 7985f2c45f1SShri Abhyankar 7995f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableOffset, DMGetLocalVector 8005f2c45f1SShri Abhyankar @*/ 8015f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableGlobalOffset(DM dm,PetscInt p,PetscInt *offsetg) 8025f2c45f1SShri Abhyankar { 8035f2c45f1SShri Abhyankar PetscErrorCode ierr; 8045f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 8055f2c45f1SShri Abhyankar 8065f2c45f1SShri Abhyankar PetscFunctionBegin; 8071bb6d2a8SBarry Smith ierr = PetscSectionGetOffset(network->plex->globalSection,p,offsetg);CHKERRQ(ierr); 8086fefedf4SHong Zhang if (*offsetg < 0) *offsetg = -(*offsetg + 1); /* Convert to actual global offset for ghost vertex */ 8095f2c45f1SShri Abhyankar PetscFunctionReturn(0); 8105f2c45f1SShri Abhyankar } 8115f2c45f1SShri Abhyankar 81224121865SAdrian Maldonado /*@ 81324121865SAdrian Maldonado DMNetworkGetEdgeOffset - Get the offset for accessing the variable associated with the given edge from the local subvector. 81424121865SAdrian Maldonado 81524121865SAdrian Maldonado Not Collective 81624121865SAdrian Maldonado 81724121865SAdrian Maldonado Input Parameters: 81824121865SAdrian Maldonado + dm - The DMNetwork object 81924121865SAdrian Maldonado - p - the edge point 82024121865SAdrian Maldonado 82124121865SAdrian Maldonado Output Parameters: 82224121865SAdrian Maldonado . offset - the offset 82324121865SAdrian Maldonado 82424121865SAdrian Maldonado Level: intermediate 82524121865SAdrian Maldonado 82624121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 82724121865SAdrian Maldonado @*/ 82824121865SAdrian Maldonado PetscErrorCode DMNetworkGetEdgeOffset(DM dm,PetscInt p,PetscInt *offset) 82924121865SAdrian Maldonado { 83024121865SAdrian Maldonado PetscErrorCode ierr; 83124121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 83224121865SAdrian Maldonado 83324121865SAdrian Maldonado PetscFunctionBegin; 83424121865SAdrian Maldonado 83524121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->edge.DofSection,p,offset);CHKERRQ(ierr); 83624121865SAdrian Maldonado PetscFunctionReturn(0); 83724121865SAdrian Maldonado } 83824121865SAdrian Maldonado 83924121865SAdrian Maldonado /*@ 84024121865SAdrian Maldonado DMNetworkGetVertexOffset - Get the offset for accessing the variable associated with the given vertex from the local subvector. 84124121865SAdrian Maldonado 84224121865SAdrian Maldonado Not Collective 84324121865SAdrian Maldonado 84424121865SAdrian Maldonado Input Parameters: 84524121865SAdrian Maldonado + dm - The DMNetwork object 84624121865SAdrian Maldonado - p - the vertex point 84724121865SAdrian Maldonado 84824121865SAdrian Maldonado Output Parameters: 84924121865SAdrian Maldonado . offset - the offset 85024121865SAdrian Maldonado 85124121865SAdrian Maldonado Level: intermediate 85224121865SAdrian Maldonado 85324121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 85424121865SAdrian Maldonado @*/ 85524121865SAdrian Maldonado PetscErrorCode DMNetworkGetVertexOffset(DM dm,PetscInt p,PetscInt *offset) 85624121865SAdrian Maldonado { 85724121865SAdrian Maldonado PetscErrorCode ierr; 85824121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 85924121865SAdrian Maldonado 86024121865SAdrian Maldonado PetscFunctionBegin; 86124121865SAdrian Maldonado 86224121865SAdrian Maldonado p -= network->vStart; 86324121865SAdrian Maldonado 86424121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->vertex.DofSection,p,offset);CHKERRQ(ierr); 86524121865SAdrian Maldonado PetscFunctionReturn(0); 86624121865SAdrian Maldonado } 8675f2c45f1SShri Abhyankar /*@ 8685f2c45f1SShri Abhyankar DMNetworkAddNumVariables - Add number of variables associated with a given point. 8695f2c45f1SShri Abhyankar 8705f2c45f1SShri Abhyankar Not Collective 8715f2c45f1SShri Abhyankar 8725f2c45f1SShri Abhyankar Input Parameters: 8735f2c45f1SShri Abhyankar + dm - The DMNetworkObject 8745f2c45f1SShri Abhyankar . p - the vertex/edge point 8755f2c45f1SShri Abhyankar - nvar - number of additional variables 8765f2c45f1SShri Abhyankar 8775f2c45f1SShri Abhyankar Level: intermediate 8785f2c45f1SShri Abhyankar 8795f2c45f1SShri Abhyankar .seealso: DMNetworkSetNumVariables 8805f2c45f1SShri Abhyankar @*/ 8815f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddNumVariables(DM dm,PetscInt p,PetscInt nvar) 8825f2c45f1SShri Abhyankar { 8835f2c45f1SShri Abhyankar PetscErrorCode ierr; 8845f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 8855f2c45f1SShri Abhyankar 8865f2c45f1SShri Abhyankar PetscFunctionBegin; 8875f2c45f1SShri Abhyankar ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr); 8885f2c45f1SShri Abhyankar PetscFunctionReturn(0); 8895f2c45f1SShri Abhyankar } 8905f2c45f1SShri Abhyankar 89127f51fceSHong Zhang /*@ 89227f51fceSHong Zhang DMNetworkGetNumVariables - Gets number of variables for a vertex/edge point. 89327f51fceSHong Zhang 89427f51fceSHong Zhang Not Collective 89527f51fceSHong Zhang 89627f51fceSHong Zhang Input Parameters: 89727f51fceSHong Zhang + dm - The DMNetworkObject 89827f51fceSHong Zhang - p - the vertex/edge point 89927f51fceSHong Zhang 90027f51fceSHong Zhang Output Parameters: 90127f51fceSHong Zhang . nvar - number of variables 90227f51fceSHong Zhang 90327f51fceSHong Zhang Level: intermediate 90427f51fceSHong Zhang 90527f51fceSHong Zhang .seealso: DMNetworkAddNumVariables, DMNetworkSddNumVariables 90627f51fceSHong Zhang @*/ 90727f51fceSHong Zhang PetscErrorCode DMNetworkGetNumVariables(DM dm,PetscInt p,PetscInt *nvar) 90827f51fceSHong Zhang { 90927f51fceSHong Zhang PetscErrorCode ierr; 91027f51fceSHong Zhang DM_Network *network = (DM_Network*)dm->data; 91127f51fceSHong Zhang 91227f51fceSHong Zhang PetscFunctionBegin; 91327f51fceSHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 91427f51fceSHong Zhang PetscFunctionReturn(0); 91527f51fceSHong Zhang } 91627f51fceSHong Zhang 9175f2c45f1SShri Abhyankar /*@ 9185f2c45f1SShri Abhyankar DMNetworkSetNumVariables - Sets number of variables for a vertex/edge point. 9195f2c45f1SShri Abhyankar 9205f2c45f1SShri Abhyankar Not Collective 9215f2c45f1SShri Abhyankar 9225f2c45f1SShri Abhyankar Input Parameters: 9235f2c45f1SShri Abhyankar + dm - The DMNetworkObject 9245f2c45f1SShri Abhyankar . p - the vertex/edge point 9255f2c45f1SShri Abhyankar - nvar - number of variables 9265f2c45f1SShri Abhyankar 9275f2c45f1SShri Abhyankar Level: intermediate 9285f2c45f1SShri Abhyankar 9295f2c45f1SShri Abhyankar .seealso: DMNetworkAddNumVariables 9305f2c45f1SShri Abhyankar @*/ 9315f2c45f1SShri Abhyankar PetscErrorCode DMNetworkSetNumVariables(DM dm,PetscInt p,PetscInt nvar) 9325f2c45f1SShri Abhyankar { 9335f2c45f1SShri Abhyankar PetscErrorCode ierr; 9345f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 9355f2c45f1SShri Abhyankar 9365f2c45f1SShri Abhyankar PetscFunctionBegin; 9375f2c45f1SShri Abhyankar ierr = PetscSectionSetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 9385f2c45f1SShri Abhyankar PetscFunctionReturn(0); 9395f2c45f1SShri Abhyankar } 9405f2c45f1SShri Abhyankar 9415f2c45f1SShri Abhyankar /* Sets up the array that holds the data for all components and its associated section. This 9425f2c45f1SShri Abhyankar function is called during DMSetUp() */ 9435f2c45f1SShri Abhyankar PetscErrorCode DMNetworkComponentSetUp(DM dm) 9445f2c45f1SShri Abhyankar { 9455f2c45f1SShri Abhyankar PetscErrorCode ierr; 9465f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 947e53b5ba3SHong Zhang PetscInt arr_size,p,offset,offsetp,ncomp,i; 9485f2c45f1SShri Abhyankar DMNetworkComponentHeader header; 9495f2c45f1SShri Abhyankar DMNetworkComponentValue cvalue; 9505f2c45f1SShri Abhyankar DMNetworkComponentGenericDataType *componentdataarray; 9515f2c45f1SShri Abhyankar 9525f2c45f1SShri Abhyankar PetscFunctionBegin; 9535f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr); 9545f2c45f1SShri Abhyankar ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr); 95575b160a0SShri Abhyankar ierr = PetscMalloc1(arr_size,&network->componentdataarray);CHKERRQ(ierr); 9565f2c45f1SShri Abhyankar componentdataarray = network->componentdataarray; 9575f2c45f1SShri Abhyankar for (p = network->pStart; p < network->pEnd; p++) { 9585f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 9595f2c45f1SShri Abhyankar /* Copy header */ 9605f2c45f1SShri Abhyankar header = &network->header[p]; 961302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offsetp,header,network->dataheadersize*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 9625f2c45f1SShri Abhyankar /* Copy data */ 9635f2c45f1SShri Abhyankar cvalue = &network->cvalue[p]; 9645f2c45f1SShri Abhyankar ncomp = header->ndata; 9655f2c45f1SShri Abhyankar for (i = 0; i < ncomp; i++) { 9665f2c45f1SShri Abhyankar offset = offsetp + network->dataheadersize + header->offset[i]; 967302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 9685f2c45f1SShri Abhyankar } 9695f2c45f1SShri Abhyankar } 9705f2c45f1SShri Abhyankar PetscFunctionReturn(0); 9715f2c45f1SShri Abhyankar } 9725f2c45f1SShri Abhyankar 9735f2c45f1SShri Abhyankar /* Sets up the section for dofs. This routine is called during DMSetUp() */ 9745f2c45f1SShri Abhyankar PetscErrorCode DMNetworkVariablesSetUp(DM dm) 9755f2c45f1SShri Abhyankar { 9765f2c45f1SShri Abhyankar PetscErrorCode ierr; 9775f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 9785f2c45f1SShri Abhyankar 9795f2c45f1SShri Abhyankar PetscFunctionBegin; 9805f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr); 9815f2c45f1SShri Abhyankar PetscFunctionReturn(0); 9825f2c45f1SShri Abhyankar } 9835f2c45f1SShri Abhyankar 9845f2c45f1SShri Abhyankar /*@C 9855f2c45f1SShri Abhyankar DMNetworkGetComponentDataArray - Returns the component data array 9865f2c45f1SShri Abhyankar 9875f2c45f1SShri Abhyankar Not Collective 9885f2c45f1SShri Abhyankar 9895f2c45f1SShri Abhyankar Input Parameters: 9905f2c45f1SShri Abhyankar . dm - The DMNetwork Object 9915f2c45f1SShri Abhyankar 9925f2c45f1SShri Abhyankar Output Parameters: 9935f2c45f1SShri Abhyankar . componentdataarray - array that holds data for all components 9945f2c45f1SShri Abhyankar 9955f2c45f1SShri Abhyankar Level: intermediate 9965f2c45f1SShri Abhyankar 997a730d845SHong Zhang .seealso: DMNetworkGetComponentKeyOffset, DMNetworkGetNumComponents 9985f2c45f1SShri Abhyankar @*/ 9995f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetComponentDataArray(DM dm,DMNetworkComponentGenericDataType **componentdataarray) 10005f2c45f1SShri Abhyankar { 10015f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10025f2c45f1SShri Abhyankar 10035f2c45f1SShri Abhyankar PetscFunctionBegin; 10045f2c45f1SShri Abhyankar *componentdataarray = network->componentdataarray; 10055f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10065f2c45f1SShri Abhyankar } 10075f2c45f1SShri Abhyankar 100824121865SAdrian Maldonado /* Get a subsection from a range of points */ 100924121865SAdrian Maldonado PetscErrorCode DMNetworkGetSubSection_private(PetscSection master, PetscInt pstart, PetscInt pend,PetscSection *subsection) 101024121865SAdrian Maldonado { 101124121865SAdrian Maldonado PetscErrorCode ierr; 101224121865SAdrian Maldonado PetscInt i, nvar; 101324121865SAdrian Maldonado 101424121865SAdrian Maldonado PetscFunctionBegin; 101524121865SAdrian Maldonado ierr = PetscSectionCreate(PetscObjectComm((PetscObject)master), subsection);CHKERRQ(ierr); 101624121865SAdrian Maldonado ierr = PetscSectionSetChart(*subsection, 0, pend - pstart);CHKERRQ(ierr); 101724121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 101824121865SAdrian Maldonado ierr = PetscSectionGetDof(master,i,&nvar);CHKERRQ(ierr); 101924121865SAdrian Maldonado ierr = PetscSectionSetDof(*subsection, i - pstart, nvar);CHKERRQ(ierr); 102024121865SAdrian Maldonado } 102124121865SAdrian Maldonado 102224121865SAdrian Maldonado ierr = PetscSectionSetUp(*subsection);CHKERRQ(ierr); 102324121865SAdrian Maldonado PetscFunctionReturn(0); 102424121865SAdrian Maldonado } 102524121865SAdrian Maldonado 102624121865SAdrian Maldonado /* Create a submap of points with a GlobalToLocal structure */ 102724121865SAdrian Maldonado PetscErrorCode DMNetworkSetSubMap_private(PetscInt pstart, PetscInt pend, ISLocalToGlobalMapping *map) 102824121865SAdrian Maldonado { 102924121865SAdrian Maldonado PetscErrorCode ierr; 103024121865SAdrian Maldonado PetscInt i, *subpoints; 103124121865SAdrian Maldonado 103224121865SAdrian Maldonado PetscFunctionBegin; 103324121865SAdrian Maldonado /* Create index sets to map from "points" to "subpoints" */ 103424121865SAdrian Maldonado ierr = PetscMalloc1(pend - pstart, &subpoints);CHKERRQ(ierr); 103524121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 103624121865SAdrian Maldonado subpoints[i - pstart] = i; 103724121865SAdrian Maldonado } 1038459726d8SSatish Balay ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,pend-pstart,subpoints,PETSC_COPY_VALUES,map);CHKERRQ(ierr); 103924121865SAdrian Maldonado ierr = PetscFree(subpoints);CHKERRQ(ierr); 104024121865SAdrian Maldonado PetscFunctionReturn(0); 104124121865SAdrian Maldonado } 104224121865SAdrian Maldonado 104324121865SAdrian Maldonado /*@ 104424121865SAdrian Maldonado DMNetworkAssembleGraphStructures - Assembles vertex and edge data structures. Must be called after DMNetworkDistribute. 104524121865SAdrian Maldonado 104624121865SAdrian Maldonado Collective 104724121865SAdrian Maldonado 104824121865SAdrian Maldonado Input Parameters: 104924121865SAdrian Maldonado . dm - The DMNetworkObject 105024121865SAdrian Maldonado 105124121865SAdrian Maldonado Note: the routine will create alternative orderings for the vertices and edges. Assume global network points are: 105224121865SAdrian Maldonado 105324121865SAdrian Maldonado points = [0 1 2 3 4 5 6] 105424121865SAdrian Maldonado 1055caf410d2SHong Zhang where edges = [0,1,2,3] and vertices = [4,5,6]. The new orderings will be specific to the subset (i.e vertices = [0,1,2] <- [4,5,6]). 105624121865SAdrian Maldonado 105724121865SAdrian Maldonado With this new ordering a local PetscSection, global PetscSection and PetscSF will be created specific to the subset. 105824121865SAdrian Maldonado 105924121865SAdrian Maldonado Level: intermediate 106024121865SAdrian Maldonado 106124121865SAdrian Maldonado @*/ 106224121865SAdrian Maldonado PetscErrorCode DMNetworkAssembleGraphStructures(DM dm) 106324121865SAdrian Maldonado { 106424121865SAdrian Maldonado PetscErrorCode ierr; 106524121865SAdrian Maldonado MPI_Comm comm; 10669852e123SBarry Smith PetscMPIInt rank, size; 106724121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 106824121865SAdrian Maldonado 1069eab1376dSHong Zhang PetscFunctionBegin; 107024121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 107124121865SAdrian Maldonado ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 10729852e123SBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 107324121865SAdrian Maldonado 107424121865SAdrian Maldonado /* Create maps for vertices and edges */ 107524121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 107624121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->eStart,network->eEnd,&network->edge.mapping);CHKERRQ(ierr); 107724121865SAdrian Maldonado 107824121865SAdrian Maldonado /* Create local sub-sections */ 107924121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->vStart,network->vEnd,&network->vertex.DofSection);CHKERRQ(ierr); 108024121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->eStart,network->eEnd,&network->edge.DofSection);CHKERRQ(ierr); 108124121865SAdrian Maldonado 10829852e123SBarry Smith if (size > 1) { 108324121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 108422bbedd7SHong Zhang 108524121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->vertex.DofSection, network->vertex.sf, PETSC_FALSE, PETSC_FALSE, &network->vertex.GlobalDofSection);CHKERRQ(ierr); 108624121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->edge.mapping, &network->edge.sf);CHKERRQ(ierr); 108724121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->edge.DofSection, network->edge.sf, PETSC_FALSE, PETSC_FALSE, &network->edge.GlobalDofSection);CHKERRQ(ierr); 108824121865SAdrian Maldonado } else { 108924121865SAdrian Maldonado /* create structures for vertex */ 109024121865SAdrian Maldonado ierr = PetscSectionClone(network->vertex.DofSection,&network->vertex.GlobalDofSection);CHKERRQ(ierr); 109124121865SAdrian Maldonado /* create structures for edge */ 109224121865SAdrian Maldonado ierr = PetscSectionClone(network->edge.DofSection,&network->edge.GlobalDofSection);CHKERRQ(ierr); 109324121865SAdrian Maldonado } 109424121865SAdrian Maldonado 109524121865SAdrian Maldonado /* Add viewers */ 109624121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->edge.GlobalDofSection,"Global edge dof section");CHKERRQ(ierr); 109724121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->vertex.GlobalDofSection,"Global vertex dof section");CHKERRQ(ierr); 109824121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->edge.GlobalDofSection, NULL, "-edge_global_section_view");CHKERRQ(ierr); 109924121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->vertex.GlobalDofSection, NULL, "-vertex_global_section_view");CHKERRQ(ierr); 110024121865SAdrian Maldonado PetscFunctionReturn(0); 110124121865SAdrian Maldonado } 11027b6afd5bSHong Zhang 11035f2c45f1SShri Abhyankar /*@ 11045f2c45f1SShri Abhyankar DMNetworkDistribute - Distributes the network and moves associated component data. 11055f2c45f1SShri Abhyankar 11065f2c45f1SShri Abhyankar Collective 11075f2c45f1SShri Abhyankar 11085f2c45f1SShri Abhyankar Input Parameter: 1109d3464fd4SAdrian Maldonado + DM - the DMNetwork object 11105f2c45f1SShri Abhyankar - overlap - The overlap of partitions, 0 is the default 11115f2c45f1SShri Abhyankar 11125f2c45f1SShri Abhyankar Notes: 11138b171c8eSHong Zhang Distributes the network with <overlap>-overlapping partitioning of the edges. 11145f2c45f1SShri Abhyankar 11155f2c45f1SShri Abhyankar Level: intermediate 11165f2c45f1SShri Abhyankar 11175f2c45f1SShri Abhyankar .seealso: DMNetworkCreate 11185f2c45f1SShri Abhyankar @*/ 1119d3464fd4SAdrian Maldonado PetscErrorCode DMNetworkDistribute(DM *dm,PetscInt overlap) 11205f2c45f1SShri Abhyankar { 1121d3464fd4SAdrian Maldonado MPI_Comm comm; 11225f2c45f1SShri Abhyankar PetscErrorCode ierr; 1123d3464fd4SAdrian Maldonado PetscMPIInt size; 1124d3464fd4SAdrian Maldonado DM_Network *oldDMnetwork = (DM_Network*)((*dm)->data); 1125d3464fd4SAdrian Maldonado DM_Network *newDMnetwork; 1126caf410d2SHong Zhang PetscSF pointsf=NULL; 11275f2c45f1SShri Abhyankar DM newDM; 1128caf410d2SHong Zhang PetscInt j,e,v,offset,*subnetvtx; 112951ac5effSHong Zhang PetscPartitioner part; 1130b9c6e19dSShri Abhyankar DMNetworkComponentHeader header; 11315f2c45f1SShri Abhyankar 11325f2c45f1SShri Abhyankar PetscFunctionBegin; 1133d3464fd4SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)*dm,&comm);CHKERRQ(ierr); 1134d3464fd4SAdrian Maldonado ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 1135d3464fd4SAdrian Maldonado if (size == 1) PetscFunctionReturn(0); 1136d3464fd4SAdrian Maldonado 1137d3464fd4SAdrian Maldonado ierr = DMNetworkCreate(PetscObjectComm((PetscObject)*dm),&newDM);CHKERRQ(ierr); 11385f2c45f1SShri Abhyankar newDMnetwork = (DM_Network*)newDM->data; 11395f2c45f1SShri Abhyankar newDMnetwork->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 114051ac5effSHong Zhang 114151ac5effSHong Zhang /* Enable runtime options for petscpartitioner */ 114251ac5effSHong Zhang ierr = DMPlexGetPartitioner(oldDMnetwork->plex,&part);CHKERRQ(ierr); 114351ac5effSHong Zhang ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); 114451ac5effSHong Zhang 11455f2c45f1SShri Abhyankar /* Distribute plex dm and dof section */ 114680cf41d5SMatthew G. Knepley ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr); 114751ac5effSHong Zhang 11485f2c45f1SShri Abhyankar /* Distribute dof section */ 1149d3464fd4SAdrian Maldonado ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DofSection);CHKERRQ(ierr); 11505f2c45f1SShri Abhyankar ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr); 1151d3464fd4SAdrian Maldonado ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DataSection);CHKERRQ(ierr); 115251ac5effSHong Zhang 11535f2c45f1SShri Abhyankar /* Distribute data and associated section */ 115431da1fc8SHong Zhang ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr); 115524121865SAdrian Maldonado 11565f2c45f1SShri Abhyankar ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr); 11575f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr); 11585f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr); 11595f2c45f1SShri Abhyankar newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart; 11606fefedf4SHong Zhang newDMnetwork->nVertices = newDMnetwork->vEnd - newDMnetwork->vStart; 11616fefedf4SHong Zhang newDMnetwork->NVertices = oldDMnetwork->NVertices; 11625f2c45f1SShri Abhyankar newDMnetwork->NEdges = oldDMnetwork->NEdges; 116324121865SAdrian Maldonado 11641bb6d2a8SBarry Smith /* Set Dof section as the section for dm */ 116592fd8e1eSJed Brown ierr = DMSetLocalSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr); 1166e87a4003SBarry Smith ierr = DMGetGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr); 11675f2c45f1SShri Abhyankar 1168b9c6e19dSShri Abhyankar /* Set up subnetwork info in the newDM */ 1169b9c6e19dSShri Abhyankar newDMnetwork->nsubnet = oldDMnetwork->nsubnet; 1170caf410d2SHong Zhang newDMnetwork->ncsubnet = oldDMnetwork->ncsubnet; 1171b9c6e19dSShri Abhyankar ierr = PetscCalloc1(newDMnetwork->nsubnet,&newDMnetwork->subnet);CHKERRQ(ierr); 1172b9c6e19dSShri Abhyankar /* Copy over the global number of vertices and edges in each subnetwork. Note that these are already 1173b9c6e19dSShri Abhyankar calculated in DMNetworkLayoutSetUp() 1174b9c6e19dSShri Abhyankar */ 1175b9c6e19dSShri Abhyankar for(j=0; j < newDMnetwork->nsubnet; j++) { 1176b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nvtx = oldDMnetwork->subnet[j].Nvtx; 1177b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nedge = oldDMnetwork->subnet[j].Nedge; 1178b9c6e19dSShri Abhyankar } 1179b9c6e19dSShri Abhyankar 1180b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++ ) { 1181b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 1182b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1183b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nedge++; 1184b9c6e19dSShri Abhyankar } 1185b9c6e19dSShri Abhyankar 1186b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++ ) { 1187b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1188b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1189b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nvtx++; 1190b9c6e19dSShri Abhyankar } 1191b9c6e19dSShri Abhyankar 1192b9c6e19dSShri Abhyankar /* Now create the vertices and edge arrays for the subnetworks */ 1193caf410d2SHong Zhang ierr = PetscCalloc1(newDMnetwork->vEnd-newDMnetwork->vStart,&newDMnetwork->subnetvtx);CHKERRQ(ierr); 1194caf410d2SHong Zhang subnetvtx = newDMnetwork->subnetvtx; 1195caf410d2SHong Zhang 1196b9c6e19dSShri Abhyankar for (j=0; j<newDMnetwork->nsubnet; j++) { 1197b9c6e19dSShri Abhyankar ierr = PetscCalloc1(newDMnetwork->subnet[j].nedge,&newDMnetwork->subnet[j].edges);CHKERRQ(ierr); 1198caf410d2SHong Zhang newDMnetwork->subnet[j].vertices = subnetvtx; 1199caf410d2SHong Zhang subnetvtx += newDMnetwork->subnet[j].nvtx; 1200caf410d2SHong Zhang 1201b9c6e19dSShri Abhyankar /* Temporarily setting nvtx and nedge to 0 so we can use them as counters in the below for loop. 1202b9c6e19dSShri Abhyankar These get updated when the vertices and edges are added. */ 1203b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].nvtx = newDMnetwork->subnet[j].nedge = 0; 1204b9c6e19dSShri Abhyankar } 1205b9c6e19dSShri Abhyankar 1206b9c6e19dSShri Abhyankar /* Set the vertices and edges in each subnetwork */ 1207b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++ ) { 1208b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 1209b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1210b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].edges[newDMnetwork->subnet[header->subnetid].nedge++] = e; 1211b9c6e19dSShri Abhyankar } 1212b9c6e19dSShri Abhyankar 1213b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++ ) { 1214b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1215b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1216b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].vertices[newDMnetwork->subnet[header->subnetid].nvtx++] = v; 1217b9c6e19dSShri Abhyankar } 1218b9c6e19dSShri Abhyankar 1219caf410d2SHong Zhang newDM->setupcalled = (*dm)->setupcalled; 122022bbedd7SHong Zhang newDMnetwork->distributecalled = PETSC_TRUE; 1221caf410d2SHong Zhang 122224121865SAdrian Maldonado /* Destroy point SF */ 122324121865SAdrian Maldonado ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr); 122424121865SAdrian Maldonado 1225d3464fd4SAdrian Maldonado ierr = DMDestroy(dm);CHKERRQ(ierr); 1226d3464fd4SAdrian Maldonado *dm = newDM; 12275f2c45f1SShri Abhyankar PetscFunctionReturn(0); 12285f2c45f1SShri Abhyankar } 12295f2c45f1SShri Abhyankar 123024121865SAdrian Maldonado /*@C 123124121865SAdrian Maldonado PetscSFGetSubSF - Returns an SF for a specific subset of points. Leaves are re-numbered to reflect the new ordering. 123224121865SAdrian Maldonado 123324121865SAdrian Maldonado Input Parameters: 123424121865SAdrian Maldonado + masterSF - the original SF structure 123524121865SAdrian Maldonado - map - a ISLocalToGlobal mapping that contains the subset of points 123624121865SAdrian Maldonado 123724121865SAdrian Maldonado Output Parameters: 123824121865SAdrian Maldonado . subSF - a subset of the masterSF for the desired subset. 123924121865SAdrian Maldonado */ 124024121865SAdrian Maldonado 124124121865SAdrian Maldonado PetscErrorCode PetscSFGetSubSF(PetscSF mastersf, ISLocalToGlobalMapping map, PetscSF *subSF) { 124224121865SAdrian Maldonado 124324121865SAdrian Maldonado PetscErrorCode ierr; 124424121865SAdrian Maldonado PetscInt nroots, nleaves, *ilocal_sub; 124524121865SAdrian Maldonado PetscInt i, *ilocal_map, nroots_sub, nleaves_sub = 0; 124624121865SAdrian Maldonado PetscInt *local_points, *remote_points; 124724121865SAdrian Maldonado PetscSFNode *iremote_sub; 124824121865SAdrian Maldonado const PetscInt *ilocal; 124924121865SAdrian Maldonado const PetscSFNode *iremote; 125024121865SAdrian Maldonado 125124121865SAdrian Maldonado PetscFunctionBegin; 125224121865SAdrian Maldonado ierr = PetscSFGetGraph(mastersf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr); 125324121865SAdrian Maldonado 125424121865SAdrian Maldonado /* Look for leaves that pertain to the subset of points. Get the local ordering */ 125524121865SAdrian Maldonado ierr = PetscMalloc1(nleaves,&ilocal_map);CHKERRQ(ierr); 125624121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nleaves,ilocal,NULL,ilocal_map);CHKERRQ(ierr); 125724121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 125824121865SAdrian Maldonado if (ilocal_map[i] != -1) nleaves_sub += 1; 125924121865SAdrian Maldonado } 126024121865SAdrian Maldonado /* Re-number ilocal with subset numbering. Need information from roots */ 126124121865SAdrian Maldonado ierr = PetscMalloc2(nroots,&local_points,nroots,&remote_points);CHKERRQ(ierr); 126224121865SAdrian Maldonado for (i = 0; i < nroots; i++) local_points[i] = i; 126324121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nroots,local_points,NULL,local_points);CHKERRQ(ierr); 126424121865SAdrian Maldonado ierr = PetscSFBcastBegin(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr); 126524121865SAdrian Maldonado ierr = PetscSFBcastEnd(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr); 126624121865SAdrian Maldonado /* Fill up graph using local (that is, local to the subset) numbering. */ 12674b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&ilocal_sub);CHKERRQ(ierr); 12684b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&iremote_sub);CHKERRQ(ierr); 126924121865SAdrian Maldonado nleaves_sub = 0; 127024121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 127124121865SAdrian Maldonado if (ilocal_map[i] != -1) { 127224121865SAdrian Maldonado ilocal_sub[nleaves_sub] = ilocal_map[i]; 12734b70a8deSAdrian Maldonado iremote_sub[nleaves_sub].rank = iremote[i].rank; 127424121865SAdrian Maldonado iremote_sub[nleaves_sub].index = remote_points[ilocal[i]]; 127524121865SAdrian Maldonado nleaves_sub += 1; 127624121865SAdrian Maldonado } 127724121865SAdrian Maldonado } 127824121865SAdrian Maldonado ierr = PetscFree2(local_points,remote_points);CHKERRQ(ierr); 127924121865SAdrian Maldonado ierr = ISLocalToGlobalMappingGetSize(map,&nroots_sub);CHKERRQ(ierr); 128024121865SAdrian Maldonado 128124121865SAdrian Maldonado /* Create new subSF */ 128224121865SAdrian Maldonado ierr = PetscSFCreate(PETSC_COMM_WORLD,subSF);CHKERRQ(ierr); 128324121865SAdrian Maldonado ierr = PetscSFSetFromOptions(*subSF);CHKERRQ(ierr); 12844b70a8deSAdrian Maldonado ierr = PetscSFSetGraph(*subSF,nroots_sub,nleaves_sub,ilocal_sub,PETSC_OWN_POINTER,iremote_sub,PETSC_COPY_VALUES);CHKERRQ(ierr); 128524121865SAdrian Maldonado ierr = PetscFree(ilocal_map);CHKERRQ(ierr); 12864b70a8deSAdrian Maldonado ierr = PetscFree(iremote_sub);CHKERRQ(ierr); 128724121865SAdrian Maldonado PetscFunctionReturn(0); 128824121865SAdrian Maldonado } 128924121865SAdrian Maldonado 12905f2c45f1SShri Abhyankar /*@C 12915f2c45f1SShri Abhyankar DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point 12925f2c45f1SShri Abhyankar 12935f2c45f1SShri Abhyankar Not Collective 12945f2c45f1SShri Abhyankar 12955f2c45f1SShri Abhyankar Input Parameters: 12965f2c45f1SShri Abhyankar + dm - The DMNetwork object 12975f2c45f1SShri Abhyankar - p - the vertex point 12985f2c45f1SShri Abhyankar 12995f2c45f1SShri Abhyankar Output Paramters: 13005f2c45f1SShri Abhyankar + nedges - number of edges connected to this vertex point 13015f2c45f1SShri Abhyankar - edges - List of edge points 13025f2c45f1SShri Abhyankar 13035f2c45f1SShri Abhyankar Level: intermediate 13045f2c45f1SShri Abhyankar 13055f2c45f1SShri Abhyankar Fortran Notes: 13065f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 13075f2c45f1SShri Abhyankar include petsc.h90 in your code. 13085f2c45f1SShri Abhyankar 1309d842c372SHong Zhang .seealso: DMNetworkCreate, DMNetworkGetConnectedVertices 13105f2c45f1SShri Abhyankar @*/ 13115f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[]) 13125f2c45f1SShri Abhyankar { 13135f2c45f1SShri Abhyankar PetscErrorCode ierr; 13145f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 13155f2c45f1SShri Abhyankar 13165f2c45f1SShri Abhyankar PetscFunctionBegin; 13175f2c45f1SShri Abhyankar ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr); 13185f2c45f1SShri Abhyankar ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr); 13195f2c45f1SShri Abhyankar PetscFunctionReturn(0); 13205f2c45f1SShri Abhyankar } 13215f2c45f1SShri Abhyankar 13225f2c45f1SShri Abhyankar /*@C 1323d842c372SHong Zhang DMNetworkGetConnectedVertices - Return the connected vertices for this edge point 13245f2c45f1SShri Abhyankar 13255f2c45f1SShri Abhyankar Not Collective 13265f2c45f1SShri Abhyankar 13275f2c45f1SShri Abhyankar Input Parameters: 13285f2c45f1SShri Abhyankar + dm - The DMNetwork object 13295f2c45f1SShri Abhyankar - p - the edge point 13305f2c45f1SShri Abhyankar 13315f2c45f1SShri Abhyankar Output Paramters: 13325f2c45f1SShri Abhyankar . vertices - vertices connected to this edge 13335f2c45f1SShri Abhyankar 13345f2c45f1SShri Abhyankar Level: intermediate 13355f2c45f1SShri Abhyankar 13365f2c45f1SShri Abhyankar Fortran Notes: 13375f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 13385f2c45f1SShri Abhyankar include petsc.h90 in your code. 13395f2c45f1SShri Abhyankar 13405f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkGetSupportingEdges 13415f2c45f1SShri Abhyankar @*/ 1342d842c372SHong Zhang PetscErrorCode DMNetworkGetConnectedVertices(DM dm,PetscInt edge,const PetscInt *vertices[]) 13435f2c45f1SShri Abhyankar { 13445f2c45f1SShri Abhyankar PetscErrorCode ierr; 13455f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 13465f2c45f1SShri Abhyankar 13475f2c45f1SShri Abhyankar PetscFunctionBegin; 13485f2c45f1SShri Abhyankar ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr); 13495f2c45f1SShri Abhyankar PetscFunctionReturn(0); 13505f2c45f1SShri Abhyankar } 13515f2c45f1SShri Abhyankar 13525f2c45f1SShri Abhyankar /*@ 13535f2c45f1SShri Abhyankar DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex 13545f2c45f1SShri Abhyankar 13555f2c45f1SShri Abhyankar Not Collective 13565f2c45f1SShri Abhyankar 13575f2c45f1SShri Abhyankar Input Parameters: 13585f2c45f1SShri Abhyankar + dm - The DMNetwork object 1359a2b725a8SWilliam Gropp - p - the vertex point 13605f2c45f1SShri Abhyankar 13615f2c45f1SShri Abhyankar Output Parameter: 13625f2c45f1SShri Abhyankar . isghost - TRUE if the vertex is a ghost point 13635f2c45f1SShri Abhyankar 13645f2c45f1SShri Abhyankar Level: intermediate 13655f2c45f1SShri Abhyankar 1366d842c372SHong Zhang .seealso: DMNetworkCreate, DMNetworkGetConnectedVertices, DMNetworkGetVertexRange 13675f2c45f1SShri Abhyankar @*/ 13685f2c45f1SShri Abhyankar PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost) 13695f2c45f1SShri Abhyankar { 13705f2c45f1SShri Abhyankar PetscErrorCode ierr; 13715f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 13725f2c45f1SShri Abhyankar PetscInt offsetg; 13735f2c45f1SShri Abhyankar PetscSection sectiong; 13745f2c45f1SShri Abhyankar 13755f2c45f1SShri Abhyankar PetscFunctionBegin; 1376caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 13775f2c45f1SShri Abhyankar *isghost = PETSC_FALSE; 1378e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§iong);CHKERRQ(ierr); 13795f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr); 13805f2c45f1SShri Abhyankar if (offsetg < 0) *isghost = PETSC_TRUE; 13815f2c45f1SShri Abhyankar PetscFunctionReturn(0); 13825f2c45f1SShri Abhyankar } 13835f2c45f1SShri Abhyankar 13845f2c45f1SShri Abhyankar PetscErrorCode DMSetUp_Network(DM dm) 13855f2c45f1SShri Abhyankar { 13865f2c45f1SShri Abhyankar PetscErrorCode ierr; 13875f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 13885f2c45f1SShri Abhyankar 13895f2c45f1SShri Abhyankar PetscFunctionBegin; 13905f2c45f1SShri Abhyankar ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr); 13915f2c45f1SShri Abhyankar ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr); 13925f2c45f1SShri Abhyankar 139392fd8e1eSJed Brown ierr = DMSetLocalSection(network->plex,network->DofSection);CHKERRQ(ierr); 1394e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr); 13959e1d080bSHong Zhang 13969e1d080bSHong Zhang dm->setupcalled = PETSC_TRUE; 13979e1d080bSHong Zhang ierr = DMViewFromOptions(dm,NULL,"-dm_view");CHKERRQ(ierr); 13985f2c45f1SShri Abhyankar PetscFunctionReturn(0); 13995f2c45f1SShri Abhyankar } 14005f2c45f1SShri Abhyankar 14011ad426b7SHong Zhang /*@ 140217df6e9eSHong Zhang DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices 14031ad426b7SHong Zhang -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)? 14041ad426b7SHong Zhang 14051ad426b7SHong Zhang Collective 14061ad426b7SHong Zhang 14071ad426b7SHong Zhang Input Parameters: 140883b2e829SHong Zhang + dm - The DMNetwork object 140983b2e829SHong Zhang . eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges 141083b2e829SHong Zhang - vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices 14111ad426b7SHong Zhang 14121ad426b7SHong Zhang Level: intermediate 14131ad426b7SHong Zhang 14141ad426b7SHong Zhang @*/ 141583b2e829SHong Zhang PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg) 14161ad426b7SHong Zhang { 14171ad426b7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 14188675203cSHong Zhang PetscErrorCode ierr; 141966b4e0ffSHong Zhang PetscInt nVertices = network->nVertices; 14201ad426b7SHong Zhang 14211ad426b7SHong Zhang PetscFunctionBegin; 142283b2e829SHong Zhang network->userEdgeJacobian = eflg; 142383b2e829SHong Zhang network->userVertexJacobian = vflg; 14248675203cSHong Zhang 14258675203cSHong Zhang if (eflg && !network->Je) { 14268675203cSHong Zhang ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr); 14278675203cSHong Zhang } 14288675203cSHong Zhang 142966b4e0ffSHong Zhang if (vflg && !network->Jv && nVertices) { 14308675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 143166b4e0ffSHong Zhang PetscInt nedges_total; 14328675203cSHong Zhang const PetscInt *edges; 14338675203cSHong Zhang 14348675203cSHong Zhang /* count nvertex_total */ 14358675203cSHong Zhang nedges_total = 0; 14368675203cSHong Zhang ierr = PetscMalloc1(nVertices+1,&vptr);CHKERRQ(ierr); 14378675203cSHong Zhang 14388675203cSHong Zhang vptr[0] = 0; 14398675203cSHong Zhang for (i=0; i<nVertices; i++) { 14408675203cSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,i+vStart,&nedges,&edges);CHKERRQ(ierr); 14418675203cSHong Zhang nedges_total += nedges; 14428675203cSHong Zhang vptr[i+1] = vptr[i] + 2*nedges + 1; 14438675203cSHong Zhang } 14448675203cSHong Zhang 14458675203cSHong Zhang ierr = PetscCalloc1(2*nedges_total+nVertices,&network->Jv);CHKERRQ(ierr); 14468675203cSHong Zhang network->Jvptr = vptr; 14478675203cSHong Zhang } 14481ad426b7SHong Zhang PetscFunctionReturn(0); 14491ad426b7SHong Zhang } 14501ad426b7SHong Zhang 14511ad426b7SHong Zhang /*@ 145283b2e829SHong Zhang DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network 145383b2e829SHong Zhang 145483b2e829SHong Zhang Not Collective 145583b2e829SHong Zhang 145683b2e829SHong Zhang Input Parameters: 145783b2e829SHong Zhang + dm - The DMNetwork object 145883b2e829SHong Zhang . p - the edge point 14593e97b6e8SHong Zhang - J - array (size = 3) of Jacobian submatrices for this edge point: 14603e97b6e8SHong Zhang J[0]: this edge 1461d842c372SHong Zhang J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedVertices() 146283b2e829SHong Zhang 146383b2e829SHong Zhang Level: intermediate 146483b2e829SHong Zhang 146583b2e829SHong Zhang .seealso: DMNetworkVertexSetMatrix 146683b2e829SHong Zhang @*/ 146783b2e829SHong Zhang PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[]) 146883b2e829SHong Zhang { 146983b2e829SHong Zhang DM_Network *network=(DM_Network*)dm->data; 147083b2e829SHong Zhang 147183b2e829SHong Zhang PetscFunctionBegin; 14728675203cSHong Zhang if (!network->Je) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix"); 14738675203cSHong Zhang 14748675203cSHong Zhang if (J) { 1475883e35e8SHong Zhang network->Je[3*p] = J[0]; 1476883e35e8SHong Zhang network->Je[3*p+1] = J[1]; 1477883e35e8SHong Zhang network->Je[3*p+2] = J[2]; 14788675203cSHong Zhang } 147983b2e829SHong Zhang PetscFunctionReturn(0); 148083b2e829SHong Zhang } 148183b2e829SHong Zhang 148283b2e829SHong Zhang /*@ 148376ddfea5SHong Zhang DMNetworkVertexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network 14841ad426b7SHong Zhang 14851ad426b7SHong Zhang Not Collective 14861ad426b7SHong Zhang 14871ad426b7SHong Zhang Input Parameters: 14881ad426b7SHong Zhang + dm - The DMNetwork object 14891ad426b7SHong Zhang . p - the vertex point 14903e97b6e8SHong Zhang - J - array of Jacobian (size = 2*(num of supporting edges) + 1) submatrices for this vertex point: 14913e97b6e8SHong Zhang J[0]: this vertex 14923e97b6e8SHong Zhang J[1+2*i]: i-th supporting edge 14933e97b6e8SHong Zhang J[1+2*i+1]: i-th connected vertex 14941ad426b7SHong Zhang 14951ad426b7SHong Zhang Level: intermediate 14961ad426b7SHong Zhang 149783b2e829SHong Zhang .seealso: DMNetworkEdgeSetMatrix 14981ad426b7SHong Zhang @*/ 1499883e35e8SHong Zhang PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[]) 15005f2c45f1SShri Abhyankar { 15015f2c45f1SShri Abhyankar PetscErrorCode ierr; 15025f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 15038675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 1504883e35e8SHong Zhang const PetscInt *edges; 15055f2c45f1SShri Abhyankar 15065f2c45f1SShri Abhyankar PetscFunctionBegin; 15078675203cSHong Zhang if (!network->Jv) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix"); 1508883e35e8SHong Zhang 15098675203cSHong Zhang if (J) { 1510883e35e8SHong Zhang vptr = network->Jvptr; 15113e97b6e8SHong Zhang network->Jv[vptr[p-vStart]] = J[0]; /* Set Jacobian for this vertex */ 15123e97b6e8SHong Zhang 15133e97b6e8SHong Zhang /* Set Jacobian for each supporting edge and connected vertex */ 1514883e35e8SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr); 1515883e35e8SHong Zhang for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i]; 15168675203cSHong Zhang } 1517883e35e8SHong Zhang PetscFunctionReturn(0); 1518883e35e8SHong Zhang } 1519883e35e8SHong Zhang 1520e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 15215cf7da58SHong Zhang { 15225cf7da58SHong Zhang PetscErrorCode ierr; 15235cf7da58SHong Zhang PetscInt j; 15245cf7da58SHong Zhang PetscScalar val=(PetscScalar)ncols; 15255cf7da58SHong Zhang 15265cf7da58SHong Zhang PetscFunctionBegin; 15275cf7da58SHong Zhang if (!ghost) { 15285cf7da58SHong Zhang for (j=0; j<nrows; j++) { 15295cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 15305cf7da58SHong Zhang } 15315cf7da58SHong Zhang } else { 15325cf7da58SHong Zhang for (j=0; j<nrows; j++) { 15335cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 15345cf7da58SHong Zhang } 15355cf7da58SHong Zhang } 15365cf7da58SHong Zhang PetscFunctionReturn(0); 15375cf7da58SHong Zhang } 15385cf7da58SHong Zhang 1539e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 15405cf7da58SHong Zhang { 15415cf7da58SHong Zhang PetscErrorCode ierr; 15425cf7da58SHong Zhang PetscInt j,ncols_u; 15435cf7da58SHong Zhang PetscScalar val; 15445cf7da58SHong Zhang 15455cf7da58SHong Zhang PetscFunctionBegin; 15465cf7da58SHong Zhang if (!ghost) { 15475cf7da58SHong Zhang for (j=0; j<nrows; j++) { 15485cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 15495cf7da58SHong Zhang val = (PetscScalar)ncols_u; 15505cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 15515cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 15525cf7da58SHong Zhang } 15535cf7da58SHong Zhang } else { 15545cf7da58SHong Zhang for (j=0; j<nrows; j++) { 15555cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 15565cf7da58SHong Zhang val = (PetscScalar)ncols_u; 15575cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 15585cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 15595cf7da58SHong Zhang } 15605cf7da58SHong Zhang } 15615cf7da58SHong Zhang PetscFunctionReturn(0); 15625cf7da58SHong Zhang } 15635cf7da58SHong Zhang 1564e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 15655cf7da58SHong Zhang { 15665cf7da58SHong Zhang PetscErrorCode ierr; 15675cf7da58SHong Zhang 15685cf7da58SHong Zhang PetscFunctionBegin; 15695cf7da58SHong Zhang if (Ju) { 15705cf7da58SHong Zhang ierr = MatSetPreallocationUserblock_private(Ju,nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 15715cf7da58SHong Zhang } else { 15725cf7da58SHong Zhang ierr = MatSetPreallocationDenseblock_private(nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 15735cf7da58SHong Zhang } 15745cf7da58SHong Zhang PetscFunctionReturn(0); 15755cf7da58SHong Zhang } 15765cf7da58SHong Zhang 1577e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 1578883e35e8SHong Zhang { 1579883e35e8SHong Zhang PetscErrorCode ierr; 1580883e35e8SHong Zhang PetscInt j,*cols; 1581883e35e8SHong Zhang PetscScalar *zeros; 1582883e35e8SHong Zhang 1583883e35e8SHong Zhang PetscFunctionBegin; 1584883e35e8SHong Zhang ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr); 1585883e35e8SHong Zhang for (j=0; j<ncols; j++) cols[j] = j+ cstart; 1586883e35e8SHong Zhang ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr); 1587883e35e8SHong Zhang ierr = PetscFree2(cols,zeros);CHKERRQ(ierr); 15881ad426b7SHong Zhang PetscFunctionReturn(0); 15891ad426b7SHong Zhang } 1590a4e85ca8SHong Zhang 1591e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 15923e97b6e8SHong Zhang { 15933e97b6e8SHong Zhang PetscErrorCode ierr; 15943e97b6e8SHong Zhang PetscInt j,M,N,row,col,ncols_u; 15953e97b6e8SHong Zhang const PetscInt *cols; 15963e97b6e8SHong Zhang PetscScalar zero=0.0; 15973e97b6e8SHong Zhang 15983e97b6e8SHong Zhang PetscFunctionBegin; 15993e97b6e8SHong Zhang ierr = MatGetSize(Ju,&M,&N);CHKERRQ(ierr); 16003e97b6e8SHong Zhang if (nrows != M || ncols != N) SETERRQ4(PetscObjectComm((PetscObject)Ju),PETSC_ERR_USER,"%D by %D must equal %D by %D",nrows,ncols,M,N); 16013e97b6e8SHong Zhang 16023e97b6e8SHong Zhang for (row=0; row<nrows; row++) { 16033e97b6e8SHong Zhang ierr = MatGetRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 16043e97b6e8SHong Zhang for (j=0; j<ncols_u; j++) { 16053e97b6e8SHong Zhang col = cols[j] + cstart; 16063e97b6e8SHong Zhang ierr = MatSetValues(*J,1,&rows[row],1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr); 16073e97b6e8SHong Zhang } 16083e97b6e8SHong Zhang ierr = MatRestoreRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 16093e97b6e8SHong Zhang } 16103e97b6e8SHong Zhang PetscFunctionReturn(0); 16113e97b6e8SHong Zhang } 16121ad426b7SHong Zhang 1613e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 1614a4e85ca8SHong Zhang { 1615a4e85ca8SHong Zhang PetscErrorCode ierr; 1616f4431b8cSHong Zhang 1617a4e85ca8SHong Zhang PetscFunctionBegin; 1618a4e85ca8SHong Zhang if (Ju) { 1619a4e85ca8SHong Zhang ierr = MatSetUserblock_private(Ju,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 1620a4e85ca8SHong Zhang } else { 1621a4e85ca8SHong Zhang ierr = MatSetDenseblock_private(nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 1622a4e85ca8SHong Zhang } 1623a4e85ca8SHong Zhang PetscFunctionReturn(0); 1624a4e85ca8SHong Zhang } 1625a4e85ca8SHong Zhang 162624121865SAdrian Maldonado /* Creates a GlobalToLocal mapping with a Local and Global section. This is akin to the routine DMGetLocalToGlobalMapping but without the need of providing a dm. 162724121865SAdrian Maldonado */ 162824121865SAdrian Maldonado PetscErrorCode CreateSubGlobalToLocalMapping_private(PetscSection globalsec, PetscSection localsec, ISLocalToGlobalMapping *ltog) 162924121865SAdrian Maldonado { 163024121865SAdrian Maldonado PetscErrorCode ierr; 163124121865SAdrian Maldonado PetscInt i,size,dof; 163224121865SAdrian Maldonado PetscInt *glob2loc; 163324121865SAdrian Maldonado 163424121865SAdrian Maldonado PetscFunctionBegin; 163524121865SAdrian Maldonado ierr = PetscSectionGetStorageSize(localsec,&size);CHKERRQ(ierr); 163624121865SAdrian Maldonado ierr = PetscMalloc1(size,&glob2loc);CHKERRQ(ierr); 163724121865SAdrian Maldonado 163824121865SAdrian Maldonado for (i = 0; i < size; i++) { 163924121865SAdrian Maldonado ierr = PetscSectionGetOffset(globalsec,i,&dof);CHKERRQ(ierr); 164024121865SAdrian Maldonado dof = (dof >= 0) ? dof : -(dof + 1); 164124121865SAdrian Maldonado glob2loc[i] = dof; 164224121865SAdrian Maldonado } 164324121865SAdrian Maldonado 164424121865SAdrian Maldonado ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,size,glob2loc,PETSC_OWN_POINTER,ltog);CHKERRQ(ierr); 164524121865SAdrian Maldonado #if 0 164624121865SAdrian Maldonado ierr = PetscIntView(size,glob2loc,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 164724121865SAdrian Maldonado #endif 164824121865SAdrian Maldonado PetscFunctionReturn(0); 164924121865SAdrian Maldonado } 165024121865SAdrian Maldonado 165101ad2aeeSHong Zhang #include <petsc/private/matimpl.h> 16529e1d080bSHong Zhang 16539e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network_Nest(DM dm,Mat *J) 16541ad426b7SHong Zhang { 16551ad426b7SHong Zhang PetscErrorCode ierr; 16561ad426b7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 16579e1d080bSHong Zhang PetscMPIInt rank, size; 165824121865SAdrian Maldonado PetscInt eDof,vDof; 165924121865SAdrian Maldonado Mat j11,j12,j21,j22,bA[2][2]; 16609e1d080bSHong Zhang MPI_Comm comm; 166124121865SAdrian Maldonado ISLocalToGlobalMapping eISMap,vISMap; 166224121865SAdrian Maldonado 16639e1d080bSHong Zhang PetscFunctionBegin; 166424121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 166524121865SAdrian Maldonado ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 166624121865SAdrian Maldonado ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 166724121865SAdrian Maldonado 166824121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->edge.GlobalDofSection,&eDof);CHKERRQ(ierr); 166924121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->vertex.GlobalDofSection,&vDof);CHKERRQ(ierr); 167024121865SAdrian Maldonado 167101ad2aeeSHong Zhang ierr = MatCreate(comm, &j11);CHKERRQ(ierr); 167224121865SAdrian Maldonado ierr = MatSetSizes(j11, eDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 167324121865SAdrian Maldonado ierr = MatSetType(j11, MATMPIAIJ);CHKERRQ(ierr); 167424121865SAdrian Maldonado 167501ad2aeeSHong Zhang ierr = MatCreate(comm, &j12);CHKERRQ(ierr); 167624121865SAdrian Maldonado ierr = MatSetSizes(j12, eDof, vDof, PETSC_DETERMINE ,PETSC_DETERMINE);CHKERRQ(ierr); 167724121865SAdrian Maldonado ierr = MatSetType(j12, MATMPIAIJ);CHKERRQ(ierr); 167824121865SAdrian Maldonado 167901ad2aeeSHong Zhang ierr = MatCreate(comm, &j21);CHKERRQ(ierr); 168024121865SAdrian Maldonado ierr = MatSetSizes(j21, vDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 168124121865SAdrian Maldonado ierr = MatSetType(j21, MATMPIAIJ);CHKERRQ(ierr); 168224121865SAdrian Maldonado 168301ad2aeeSHong Zhang ierr = MatCreate(comm, &j22);CHKERRQ(ierr); 168424121865SAdrian Maldonado ierr = MatSetSizes(j22, vDof, vDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 168524121865SAdrian Maldonado ierr = MatSetType(j22, MATMPIAIJ);CHKERRQ(ierr); 168624121865SAdrian Maldonado 16873f6a6bdaSHong Zhang bA[0][0] = j11; 16883f6a6bdaSHong Zhang bA[0][1] = j12; 16893f6a6bdaSHong Zhang bA[1][0] = j21; 16903f6a6bdaSHong Zhang bA[1][1] = j22; 169124121865SAdrian Maldonado 169224121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->edge.GlobalDofSection,network->edge.DofSection,&eISMap);CHKERRQ(ierr); 169324121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->vertex.GlobalDofSection,network->vertex.DofSection,&vISMap);CHKERRQ(ierr); 169424121865SAdrian Maldonado 169524121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j11,eISMap,eISMap);CHKERRQ(ierr); 169624121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j12,eISMap,vISMap);CHKERRQ(ierr); 169724121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j21,vISMap,eISMap);CHKERRQ(ierr); 169824121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j22,vISMap,vISMap);CHKERRQ(ierr); 169924121865SAdrian Maldonado 170024121865SAdrian Maldonado ierr = MatSetUp(j11);CHKERRQ(ierr); 170124121865SAdrian Maldonado ierr = MatSetUp(j12);CHKERRQ(ierr); 170224121865SAdrian Maldonado ierr = MatSetUp(j21);CHKERRQ(ierr); 170324121865SAdrian Maldonado ierr = MatSetUp(j22);CHKERRQ(ierr); 170424121865SAdrian Maldonado 170501ad2aeeSHong Zhang ierr = MatCreateNest(comm,2,NULL,2,NULL,&bA[0][0],J);CHKERRQ(ierr); 170624121865SAdrian Maldonado ierr = MatSetUp(*J);CHKERRQ(ierr); 170724121865SAdrian Maldonado ierr = MatNestSetVecType(*J,VECNEST);CHKERRQ(ierr); 170824121865SAdrian Maldonado ierr = MatDestroy(&j11);CHKERRQ(ierr); 170924121865SAdrian Maldonado ierr = MatDestroy(&j12);CHKERRQ(ierr); 171024121865SAdrian Maldonado ierr = MatDestroy(&j21);CHKERRQ(ierr); 171124121865SAdrian Maldonado ierr = MatDestroy(&j22);CHKERRQ(ierr); 171224121865SAdrian Maldonado 171324121865SAdrian Maldonado ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 171424121865SAdrian Maldonado ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17159e1d080bSHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 171624121865SAdrian Maldonado 171724121865SAdrian Maldonado /* Free structures */ 171824121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&eISMap);CHKERRQ(ierr); 171924121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&vISMap);CHKERRQ(ierr); 172024121865SAdrian Maldonado PetscFunctionReturn(0); 17219e1d080bSHong Zhang } 17229e1d080bSHong Zhang 17239e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J) 17249e1d080bSHong Zhang { 17259e1d080bSHong Zhang PetscErrorCode ierr; 17269e1d080bSHong Zhang DM_Network *network = (DM_Network*)dm->data; 17279e1d080bSHong Zhang PetscInt eStart,eEnd,vStart,vEnd,rstart,nrows,*rows,localSize; 17289e1d080bSHong Zhang PetscInt cstart,ncols,j,e,v; 17299e1d080bSHong Zhang PetscBool ghost,ghost_vc,ghost2,isNest; 17309e1d080bSHong Zhang Mat Juser; 17319e1d080bSHong Zhang PetscSection sectionGlobal; 17329e1d080bSHong Zhang PetscInt nedges,*vptr=NULL,vc,*rows_v; /* suppress maybe-uninitialized warning */ 17339e1d080bSHong Zhang const PetscInt *edges,*cone; 17349e1d080bSHong Zhang MPI_Comm comm; 17359e1d080bSHong Zhang MatType mtype; 17369e1d080bSHong Zhang Vec vd_nz,vo_nz; 17379e1d080bSHong Zhang PetscInt *dnnz,*onnz; 17389e1d080bSHong Zhang PetscScalar *vdnz,*vonz; 17399e1d080bSHong Zhang 17409e1d080bSHong Zhang PetscFunctionBegin; 17419e1d080bSHong Zhang mtype = dm->mattype; 17429e1d080bSHong Zhang ierr = PetscStrcmp(mtype,MATNEST,&isNest);CHKERRQ(ierr); 17439e1d080bSHong Zhang if (isNest) { 17449e1d080bSHong Zhang ierr = DMCreateMatrix_Network_Nest(dm,J);CHKERRQ(ierr); 17459e1d080bSHong Zhang PetscFunctionReturn(0); 17469e1d080bSHong Zhang } 17479e1d080bSHong Zhang 17489e1d080bSHong Zhang if (!network->userEdgeJacobian && !network->userVertexJacobian) { 1749a4e85ca8SHong Zhang /* user does not provide Jacobian blocks */ 17509e1d080bSHong Zhang ierr = DMCreateMatrix_Plex(network->plex,J);CHKERRQ(ierr); 1751bfbc38dcSHong Zhang ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 17521ad426b7SHong Zhang PetscFunctionReturn(0); 17531ad426b7SHong Zhang } 17541ad426b7SHong Zhang 1755bfbc38dcSHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr); 1756e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§ionGlobal);CHKERRQ(ierr); 1757bfbc38dcSHong Zhang ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr); 1758bfbc38dcSHong Zhang ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 17592a945128SHong Zhang 17602a945128SHong Zhang ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr); 17612a945128SHong Zhang ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 176289898e50SHong Zhang 176389898e50SHong Zhang /* (1) Set matrix preallocation */ 176489898e50SHong Zhang /*------------------------------*/ 1765840c2264SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1766840c2264SHong Zhang ierr = VecCreate(comm,&vd_nz);CHKERRQ(ierr); 1767840c2264SHong Zhang ierr = VecSetSizes(vd_nz,localSize,PETSC_DECIDE);CHKERRQ(ierr); 1768840c2264SHong Zhang ierr = VecSetFromOptions(vd_nz);CHKERRQ(ierr); 1769840c2264SHong Zhang ierr = VecSet(vd_nz,0.0);CHKERRQ(ierr); 1770840c2264SHong Zhang ierr = VecDuplicate(vd_nz,&vo_nz);CHKERRQ(ierr); 1771840c2264SHong Zhang 177289898e50SHong Zhang /* Set preallocation for edges */ 177389898e50SHong Zhang /*-----------------------------*/ 1774840c2264SHong Zhang ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr); 1775840c2264SHong Zhang 1776bdcb62a2SHong Zhang ierr = PetscMalloc1(localSize,&rows);CHKERRQ(ierr); 1777840c2264SHong Zhang for (e=eStart; e<eEnd; e++) { 1778840c2264SHong Zhang /* Get row indices */ 1779840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr); 1780840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr); 1781840c2264SHong Zhang if (nrows) { 1782840c2264SHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 1783840c2264SHong Zhang 17845cf7da58SHong Zhang /* Set preallocation for conntected vertices */ 1785d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 1786840c2264SHong Zhang for (v=0; v<2; v++) { 1787840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr); 1788840c2264SHong Zhang 17898675203cSHong Zhang if (network->Je) { 1790840c2264SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 17918675203cSHong Zhang } else Juser = NULL; 1792840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr); 17935cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 1794840c2264SHong Zhang } 1795840c2264SHong Zhang 179689898e50SHong Zhang /* Set preallocation for edge self */ 1797840c2264SHong Zhang cstart = rstart; 17988675203cSHong Zhang if (network->Je) { 1799840c2264SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 18008675203cSHong Zhang } else Juser = NULL; 18015cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 1802840c2264SHong Zhang } 1803840c2264SHong Zhang } 1804840c2264SHong Zhang 180589898e50SHong Zhang /* Set preallocation for vertices */ 180689898e50SHong Zhang /*--------------------------------*/ 1807840c2264SHong Zhang ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 18088675203cSHong Zhang if (vEnd - vStart) vptr = network->Jvptr; 1809840c2264SHong Zhang 1810840c2264SHong Zhang for (v=vStart; v<vEnd; v++) { 1811840c2264SHong Zhang /* Get row indices */ 1812840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr); 1813840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr); 1814840c2264SHong Zhang if (!nrows) continue; 1815840c2264SHong Zhang 1816bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 1817bdcb62a2SHong Zhang if (ghost) { 1818bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 1819bdcb62a2SHong Zhang } else { 1820bdcb62a2SHong Zhang rows_v = rows; 1821bdcb62a2SHong Zhang } 1822bdcb62a2SHong Zhang 1823bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 1824840c2264SHong Zhang 1825840c2264SHong Zhang /* Get supporting edges and connected vertices */ 1826840c2264SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 1827840c2264SHong Zhang 1828840c2264SHong Zhang for (e=0; e<nedges; e++) { 1829840c2264SHong Zhang /* Supporting edges */ 1830840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr); 1831840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr); 1832840c2264SHong Zhang 18338675203cSHong Zhang if (network->Jv) { 1834840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 18358675203cSHong Zhang } else Juser = NULL; 1836bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 1837840c2264SHong Zhang 1838840c2264SHong Zhang /* Connected vertices */ 1839d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 1840840c2264SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 1841840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,vc,&ghost_vc);CHKERRQ(ierr); 1842840c2264SHong Zhang 1843840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr); 1844840c2264SHong Zhang 18458675203cSHong Zhang if (network->Jv) { 1846840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 18478675203cSHong Zhang } else Juser = NULL; 1848e102a522SHong Zhang if (ghost_vc||ghost) { 1849e102a522SHong Zhang ghost2 = PETSC_TRUE; 1850e102a522SHong Zhang } else { 1851e102a522SHong Zhang ghost2 = PETSC_FALSE; 1852e102a522SHong Zhang } 1853e102a522SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost2,vd_nz,vo_nz);CHKERRQ(ierr); 1854840c2264SHong Zhang } 1855840c2264SHong Zhang 185689898e50SHong Zhang /* Set preallocation for vertex self */ 1857840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 1858840c2264SHong Zhang if (!ghost) { 1859840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr); 18608675203cSHong Zhang if (network->Jv) { 1861840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 18628675203cSHong Zhang } else Juser = NULL; 1863bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 1864840c2264SHong Zhang } 1865bdcb62a2SHong Zhang if (ghost) { 1866bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 1867bdcb62a2SHong Zhang } 1868840c2264SHong Zhang } 1869840c2264SHong Zhang 1870840c2264SHong Zhang ierr = VecAssemblyBegin(vd_nz);CHKERRQ(ierr); 1871840c2264SHong Zhang ierr = VecAssemblyBegin(vo_nz);CHKERRQ(ierr); 18725cf7da58SHong Zhang 18735cf7da58SHong Zhang ierr = PetscMalloc2(localSize,&dnnz,localSize,&onnz);CHKERRQ(ierr); 18745cf7da58SHong Zhang 18755cf7da58SHong Zhang ierr = VecAssemblyEnd(vd_nz);CHKERRQ(ierr); 1876840c2264SHong Zhang ierr = VecAssemblyEnd(vo_nz);CHKERRQ(ierr); 1877840c2264SHong Zhang 1878840c2264SHong Zhang ierr = VecGetArray(vd_nz,&vdnz);CHKERRQ(ierr); 1879840c2264SHong Zhang ierr = VecGetArray(vo_nz,&vonz);CHKERRQ(ierr); 1880840c2264SHong Zhang for (j=0; j<localSize; j++) { 1881e102a522SHong Zhang dnnz[j] = (PetscInt)PetscRealPart(vdnz[j]); 1882e102a522SHong Zhang onnz[j] = (PetscInt)PetscRealPart(vonz[j]); 1883840c2264SHong Zhang } 1884840c2264SHong Zhang ierr = VecRestoreArray(vd_nz,&vdnz);CHKERRQ(ierr); 1885840c2264SHong Zhang ierr = VecRestoreArray(vo_nz,&vonz);CHKERRQ(ierr); 1886840c2264SHong Zhang ierr = VecDestroy(&vd_nz);CHKERRQ(ierr); 1887840c2264SHong Zhang ierr = VecDestroy(&vo_nz);CHKERRQ(ierr); 1888840c2264SHong Zhang 18895cf7da58SHong Zhang ierr = MatSeqAIJSetPreallocation(*J,0,dnnz);CHKERRQ(ierr); 18905cf7da58SHong Zhang ierr = MatMPIAIJSetPreallocation(*J,0,dnnz,0,onnz);CHKERRQ(ierr); 18915cf7da58SHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 18925cf7da58SHong Zhang 18935cf7da58SHong Zhang ierr = PetscFree2(dnnz,onnz);CHKERRQ(ierr); 18945cf7da58SHong Zhang 189589898e50SHong Zhang /* (2) Set matrix entries for edges */ 189689898e50SHong Zhang /*----------------------------------*/ 18971ad426b7SHong Zhang for (e=eStart; e<eEnd; e++) { 1898bfbc38dcSHong Zhang /* Get row indices */ 18991ad426b7SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr); 190017df6e9eSHong Zhang ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr); 19014b976069SHong Zhang if (nrows) { 190217df6e9eSHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 19031ad426b7SHong Zhang 1904bfbc38dcSHong Zhang /* Set matrix entries for conntected vertices */ 1905d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 1906bfbc38dcSHong Zhang for (v=0; v<2; v++) { 1907bfbc38dcSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,cone[v],&cstart);CHKERRQ(ierr); 1908883e35e8SHong Zhang ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr); 19093e97b6e8SHong Zhang 19108675203cSHong Zhang if (network->Je) { 1911a4e85ca8SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 19128675203cSHong Zhang } else Juser = NULL; 1913a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 1914bfbc38dcSHong Zhang } 191517df6e9eSHong Zhang 1916bfbc38dcSHong Zhang /* Set matrix entries for edge self */ 19173e97b6e8SHong Zhang cstart = rstart; 19188675203cSHong Zhang if (network->Je) { 1919a4e85ca8SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 19208675203cSHong Zhang } else Juser = NULL; 1921a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr); 19221ad426b7SHong Zhang } 19234b976069SHong Zhang } 19241ad426b7SHong Zhang 1925bfbc38dcSHong Zhang /* Set matrix entries for vertices */ 192683b2e829SHong Zhang /*---------------------------------*/ 19271ad426b7SHong Zhang for (v=vStart; v<vEnd; v++) { 1928bfbc38dcSHong Zhang /* Get row indices */ 1929596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr); 1930596e729fSHong Zhang ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr); 19314b976069SHong Zhang if (!nrows) continue; 1932596e729fSHong Zhang 1933bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 1934bdcb62a2SHong Zhang if (ghost) { 1935bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 1936bdcb62a2SHong Zhang } else { 1937bdcb62a2SHong Zhang rows_v = rows; 1938bdcb62a2SHong Zhang } 1939bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 1940596e729fSHong Zhang 1941bfbc38dcSHong Zhang /* Get supporting edges and connected vertices */ 1942596e729fSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 1943596e729fSHong Zhang 1944596e729fSHong Zhang for (e=0; e<nedges; e++) { 1945bfbc38dcSHong Zhang /* Supporting edges */ 1946596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr); 1947596e729fSHong Zhang ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr); 1948596e729fSHong Zhang 19498675203cSHong Zhang if (network->Jv) { 1950a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 19518675203cSHong Zhang } else Juser = NULL; 1952bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 1953596e729fSHong Zhang 1954bfbc38dcSHong Zhang /* Connected vertices */ 1955d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 19562a945128SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 19572a945128SHong Zhang 195844aca652SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,vc,&cstart);CHKERRQ(ierr); 195944aca652SHong Zhang ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr); 1960a4e85ca8SHong Zhang 19618675203cSHong Zhang if (network->Jv) { 1962a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 19638675203cSHong Zhang } else Juser = NULL; 1964bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 1965596e729fSHong Zhang } 1966596e729fSHong Zhang 1967bfbc38dcSHong Zhang /* Set matrix entries for vertex self */ 19681ad426b7SHong Zhang if (!ghost) { 1969596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr); 19708675203cSHong Zhang if (network->Jv) { 1971a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 19728675203cSHong Zhang } else Juser = NULL; 1973bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,nrows,cstart,J);CHKERRQ(ierr); 1974bdcb62a2SHong Zhang } 1975bdcb62a2SHong Zhang if (ghost) { 1976bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 1977bdcb62a2SHong Zhang } 19781ad426b7SHong Zhang } 1979a4e85ca8SHong Zhang ierr = PetscFree(rows);CHKERRQ(ierr); 1980bdcb62a2SHong Zhang 19811ad426b7SHong Zhang ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19821ad426b7SHong Zhang ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1983dd6f46cdSHong Zhang 19845f2c45f1SShri Abhyankar ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 19855f2c45f1SShri Abhyankar PetscFunctionReturn(0); 19865f2c45f1SShri Abhyankar } 19875f2c45f1SShri Abhyankar 19885f2c45f1SShri Abhyankar PetscErrorCode DMDestroy_Network(DM dm) 19895f2c45f1SShri Abhyankar { 19905f2c45f1SShri Abhyankar PetscErrorCode ierr; 19915f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 19922727e31bSShri Abhyankar PetscInt j; 19935f2c45f1SShri Abhyankar 19945f2c45f1SShri Abhyankar PetscFunctionBegin; 19958415c774SShri Abhyankar if (--network->refct > 0) PetscFunctionReturn(0); 199683b2e829SHong Zhang if (network->Je) { 199783b2e829SHong Zhang ierr = PetscFree(network->Je);CHKERRQ(ierr); 199883b2e829SHong Zhang } 199983b2e829SHong Zhang if (network->Jv) { 2000883e35e8SHong Zhang ierr = PetscFree(network->Jvptr);CHKERRQ(ierr); 200183b2e829SHong Zhang ierr = PetscFree(network->Jv);CHKERRQ(ierr); 20021ad426b7SHong Zhang } 200313c2a604SAdrian Maldonado 200413c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->vertex.mapping);CHKERRQ(ierr); 200513c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.DofSection);CHKERRQ(ierr); 200613c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.GlobalDofSection);CHKERRQ(ierr); 2007f5427c60SHong Zhang if (network->vltog) { 2008f5427c60SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 2009f5427c60SHong Zhang } 201013c2a604SAdrian Maldonado if (network->vertex.sf) { 201113c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->vertex.sf);CHKERRQ(ierr); 201213c2a604SAdrian Maldonado } 201313c2a604SAdrian Maldonado /* edge */ 201413c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->edge.mapping);CHKERRQ(ierr); 201513c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.DofSection);CHKERRQ(ierr); 201613c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.GlobalDofSection);CHKERRQ(ierr); 201713c2a604SAdrian Maldonado if (network->edge.sf) { 201813c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->edge.sf);CHKERRQ(ierr); 201913c2a604SAdrian Maldonado } 20205f2c45f1SShri Abhyankar ierr = DMDestroy(&network->plex);CHKERRQ(ierr); 20215f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr); 20225f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr); 202383b2e829SHong Zhang 20242727e31bSShri Abhyankar for(j=0; j<network->nsubnet; j++) { 20252727e31bSShri Abhyankar ierr = PetscFree(network->subnet[j].edges);CHKERRQ(ierr); 20262727e31bSShri Abhyankar } 2027caf410d2SHong Zhang ierr = PetscFree(network->subnetvtx);CHKERRQ(ierr); 2028caf410d2SHong Zhang 2029e2aaf10cSShri Abhyankar ierr = PetscFree(network->subnet);CHKERRQ(ierr); 20305f2c45f1SShri Abhyankar ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr); 2031caf410d2SHong Zhang ierr = PetscFree2(network->header,network->cvalue);CHKERRQ(ierr); 20325f2c45f1SShri Abhyankar ierr = PetscFree(network);CHKERRQ(ierr); 20335f2c45f1SShri Abhyankar PetscFunctionReturn(0); 20345f2c45f1SShri Abhyankar } 20355f2c45f1SShri Abhyankar 20365f2c45f1SShri Abhyankar PetscErrorCode DMView_Network(DM dm,PetscViewer viewer) 20375f2c45f1SShri Abhyankar { 20385f2c45f1SShri Abhyankar PetscErrorCode ierr; 20395f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 2040caf410d2SHong Zhang PetscBool iascii; 2041caf410d2SHong Zhang PetscMPIInt rank; 2042caf410d2SHong Zhang PetscInt p,nsubnet; 20435f2c45f1SShri Abhyankar 20445f2c45f1SShri Abhyankar PetscFunctionBegin; 2045caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 2046caf410d2SHong Zhang ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 2047caf410d2SHong Zhang PetscValidHeaderSpecific(dm,DM_CLASSID, 1); 2048caf410d2SHong Zhang PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2049caf410d2SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 2050caf410d2SHong Zhang if (iascii) { 2051caf410d2SHong Zhang const PetscInt *cone,*vtx,*edges; 2052caf410d2SHong Zhang PetscInt vfrom,vto,i,j,nv,ne; 2053caf410d2SHong Zhang 2054caf410d2SHong Zhang nsubnet = network->nsubnet - network->ncsubnet; /* num of subnetworks */ 2055caf410d2SHong Zhang ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 2056caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " [%d] nsubnet: %D; nsubnetCouple: %D; nEdges: %D; nVertices: %D\n",rank,nsubnet,network->ncsubnet,network->nEdges,network->nVertices);CHKERRQ(ierr); 2057caf410d2SHong Zhang 2058caf410d2SHong Zhang for (i=0; i<nsubnet; i++) { 2059caf410d2SHong Zhang ierr = DMNetworkGetSubnetworkInfo(dm,i,&nv,&ne,&vtx,&edges);CHKERRQ(ierr); 2060caf410d2SHong Zhang if (ne) { 2061caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " Subnet %D: nEdges %D, nVertices %D\n",i,ne,nv);CHKERRQ(ierr); 2062caf410d2SHong Zhang for (j=0; j<ne; j++) { 2063caf410d2SHong Zhang p = edges[j]; 2064caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,p,&cone);CHKERRQ(ierr); 2065caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[0],&vfrom);CHKERRQ(ierr); 2066caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[1],&vto);CHKERRQ(ierr); 2067caf410d2SHong Zhang ierr = DMNetworkGetGlobalEdgeIndex(dm,edges[j],&p);CHKERRQ(ierr); 2068caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " edge %D: %D----> %D\n",p,vfrom,vto);CHKERRQ(ierr); 2069caf410d2SHong Zhang } 2070caf410d2SHong Zhang } 2071caf410d2SHong Zhang } 2072caf410d2SHong Zhang /* Coupling subnets */ 2073caf410d2SHong Zhang nsubnet = network->nsubnet; 2074caf410d2SHong Zhang for (; i<nsubnet; i++) { 2075caf410d2SHong Zhang ierr = DMNetworkGetSubnetworkInfo(dm,i,&nv,&ne,&vtx,&edges);CHKERRQ(ierr); 2076caf410d2SHong Zhang if (ne) { 2077caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " Subnet %D (couple): nEdges %D, nVertices %D\n",i,ne,nv);CHKERRQ(ierr); 2078caf410d2SHong Zhang for (j=0; j<ne; j++) { 2079caf410d2SHong Zhang p = edges[j]; 2080caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,p,&cone);CHKERRQ(ierr); 2081caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[0],&vfrom);CHKERRQ(ierr); 2082caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[1],&vto);CHKERRQ(ierr); 2083caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " edge %D: %D----> %D\n",p,vfrom,vto);CHKERRQ(ierr); 2084caf410d2SHong Zhang } 2085caf410d2SHong Zhang } 2086caf410d2SHong Zhang } 2087caf410d2SHong Zhang ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2088caf410d2SHong Zhang ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 2089caf410d2SHong Zhang } else SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMNetwork writing", ((PetscObject)viewer)->type_name); 20905f2c45f1SShri Abhyankar PetscFunctionReturn(0); 20915f2c45f1SShri Abhyankar } 20925f2c45f1SShri Abhyankar 20935f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l) 20945f2c45f1SShri Abhyankar { 20955f2c45f1SShri Abhyankar PetscErrorCode ierr; 20965f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 20975f2c45f1SShri Abhyankar 20985f2c45f1SShri Abhyankar PetscFunctionBegin; 20995f2c45f1SShri Abhyankar ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr); 21005f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21015f2c45f1SShri Abhyankar } 21025f2c45f1SShri Abhyankar 21035f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l) 21045f2c45f1SShri Abhyankar { 21055f2c45f1SShri Abhyankar PetscErrorCode ierr; 21065f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 21075f2c45f1SShri Abhyankar 21085f2c45f1SShri Abhyankar PetscFunctionBegin; 21095f2c45f1SShri Abhyankar ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr); 21105f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21115f2c45f1SShri Abhyankar } 21125f2c45f1SShri Abhyankar 21135f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g) 21145f2c45f1SShri Abhyankar { 21155f2c45f1SShri Abhyankar PetscErrorCode ierr; 21165f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 21175f2c45f1SShri Abhyankar 21185f2c45f1SShri Abhyankar PetscFunctionBegin; 21195f2c45f1SShri Abhyankar ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr); 21205f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21215f2c45f1SShri Abhyankar } 21225f2c45f1SShri Abhyankar 21235f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g) 21245f2c45f1SShri Abhyankar { 21255f2c45f1SShri Abhyankar PetscErrorCode ierr; 21265f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 21275f2c45f1SShri Abhyankar 21285f2c45f1SShri Abhyankar PetscFunctionBegin; 21295f2c45f1SShri Abhyankar ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr); 21305f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21315f2c45f1SShri Abhyankar } 213222bbedd7SHong Zhang 213322bbedd7SHong Zhang /*@ 2134b2aacc82SHong Zhang DMNetworkGetVertexLocalToGlobalOrdering - Get vertex globle index 213522bbedd7SHong Zhang 213622bbedd7SHong Zhang Not collective 213722bbedd7SHong Zhang 213822bbedd7SHong Zhang Input Parameters 213922bbedd7SHong Zhang + dm - the dm object 214022bbedd7SHong Zhang - vloc - local vertex ordering, start from 0 214122bbedd7SHong Zhang 214222bbedd7SHong Zhang Output Parameters 214322bbedd7SHong Zhang + vg - global vertex ordering, start from 0 214422bbedd7SHong Zhang 214522bbedd7SHong Zhang Level: Advanced 214622bbedd7SHong Zhang 214722bbedd7SHong Zhang .seealso: DMNetworkSetVertexLocalToGlobalOrdering() 214822bbedd7SHong Zhang @*/ 214922bbedd7SHong Zhang PetscErrorCode DMNetworkGetVertexLocalToGlobalOrdering(DM dm,PetscInt vloc,PetscInt *vg) 215022bbedd7SHong Zhang { 215122bbedd7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 215222bbedd7SHong Zhang PetscInt *vltog = network->vltog; 215322bbedd7SHong Zhang 215422bbedd7SHong Zhang PetscFunctionBegin; 215522bbedd7SHong Zhang if (!vltog) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkSetVertexLocalToGlobalOrdering() first"); 215622bbedd7SHong Zhang *vg = vltog[vloc]; 215722bbedd7SHong Zhang PetscFunctionReturn(0); 215822bbedd7SHong Zhang } 215922bbedd7SHong Zhang 216022bbedd7SHong Zhang /*@ 216122bbedd7SHong Zhang DMNetworkSetVertexLocalToGlobalOrdering - Create and setup vertex local to globle map 216222bbedd7SHong Zhang 216322bbedd7SHong Zhang Collective 216422bbedd7SHong Zhang 216522bbedd7SHong Zhang Input Parameters: 216622bbedd7SHong Zhang + dm - the dm object 216722bbedd7SHong Zhang 216822bbedd7SHong Zhang Level: Advanced 216922bbedd7SHong Zhang 217063029d29SHong Zhang .seealso: DMNetworkGetGlobalVertexIndex() 217122bbedd7SHong Zhang @*/ 217222bbedd7SHong Zhang PetscErrorCode DMNetworkSetVertexLocalToGlobalOrdering(DM dm) 217322bbedd7SHong Zhang { 217422bbedd7SHong Zhang PetscErrorCode ierr; 217522bbedd7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 217622bbedd7SHong Zhang MPI_Comm comm; 217763029d29SHong Zhang PetscMPIInt rank,size,*displs,*recvcounts,remoterank; 217822bbedd7SHong Zhang PetscBool ghost; 217963029d29SHong Zhang PetscInt *vltog,nroots,nleaves,i,*vrange,k,N,lidx; 218022bbedd7SHong Zhang const PetscSFNode *iremote; 218122bbedd7SHong Zhang PetscSF vsf; 218263029d29SHong Zhang Vec Vleaves,Vleaves_seq; 218363029d29SHong Zhang VecScatter ctx; 218463029d29SHong Zhang PetscScalar *varr,val; 218563029d29SHong Zhang const PetscScalar *varr_read; 218622bbedd7SHong Zhang 218722bbedd7SHong Zhang PetscFunctionBegin; 218822bbedd7SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 218922bbedd7SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 219063029d29SHong Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 219122bbedd7SHong Zhang 219222bbedd7SHong Zhang if (size == 1) { 219322bbedd7SHong Zhang nroots = network->vEnd - network->vStart; 219422bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 219522bbedd7SHong Zhang for (i=0; i<nroots; i++) vltog[i] = i; 219622bbedd7SHong Zhang network->vltog = vltog; 219722bbedd7SHong Zhang PetscFunctionReturn(0); 219822bbedd7SHong Zhang } 219922bbedd7SHong Zhang 220022bbedd7SHong Zhang if (!network->distributecalled) SETERRQ(comm, PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkDistribute() first"); 220122bbedd7SHong Zhang if (network->vltog) { 220222bbedd7SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 220322bbedd7SHong Zhang } 220422bbedd7SHong Zhang 220522bbedd7SHong Zhang ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 220622bbedd7SHong Zhang ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 220722bbedd7SHong Zhang vsf = network->vertex.sf; 220822bbedd7SHong Zhang 220922bbedd7SHong Zhang ierr = PetscMalloc3(size+1,&vrange,size+1,&displs,size,&recvcounts);CHKERRQ(ierr); 2210f5427c60SHong Zhang ierr = PetscSFGetGraph(vsf,&nroots,&nleaves,NULL,&iremote);CHKERRQ(ierr); 221122bbedd7SHong Zhang 221222bbedd7SHong Zhang for (i=0; i<size; i++) { displs[i] = i; recvcounts[i] = 1;} 221322bbedd7SHong Zhang 221422bbedd7SHong Zhang i = nroots - nleaves; /* local number of vertices, excluding ghosts */ 221522bbedd7SHong Zhang vrange[0] = 0; 221622bbedd7SHong Zhang ierr = MPI_Allgatherv(&i,1,MPIU_INT,vrange+1,recvcounts,displs,MPIU_INT,comm);CHKERRQ(ierr); 221767dd800bSHong Zhang for (i=2; i<size+1; i++) {vrange[i] += vrange[i-1];} 221822bbedd7SHong Zhang 221922bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 222022bbedd7SHong Zhang network->vltog = vltog; 222122bbedd7SHong Zhang 222263029d29SHong Zhang /* Set vltog for non-ghost vertices */ 222363029d29SHong Zhang k = 0; 222422bbedd7SHong Zhang for (i=0; i<nroots; i++) { 222522bbedd7SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 222663029d29SHong Zhang if (ghost) continue; 222763029d29SHong Zhang vltog[i] = vrange[rank] + k++; 222822bbedd7SHong Zhang } 2229f5427c60SHong Zhang ierr = PetscFree3(vrange,displs,recvcounts);CHKERRQ(ierr); 223063029d29SHong Zhang 223163029d29SHong Zhang /* Set vltog for ghost vertices */ 223263029d29SHong Zhang /* (a) create parallel Vleaves and sequential Vleaves_seq to convert local iremote[*].index to global index */ 223363029d29SHong Zhang ierr = VecCreate(comm,&Vleaves);CHKERRQ(ierr); 223463029d29SHong Zhang ierr = VecSetSizes(Vleaves,2*nleaves,PETSC_DETERMINE);CHKERRQ(ierr); 223563029d29SHong Zhang ierr = VecSetFromOptions(Vleaves);CHKERRQ(ierr); 223663029d29SHong Zhang ierr = VecGetArray(Vleaves,&varr);CHKERRQ(ierr); 223763029d29SHong Zhang for (i=0; i<nleaves; i++) { 223863029d29SHong Zhang varr[2*i] = (PetscScalar)(iremote[i].rank); /* rank of remote process */ 223963029d29SHong Zhang varr[2*i+1] = (PetscScalar)(iremote[i].index); /* local index in remote process */ 224063029d29SHong Zhang } 224163029d29SHong Zhang ierr = VecRestoreArray(Vleaves,&varr);CHKERRQ(ierr); 224263029d29SHong Zhang 224363029d29SHong Zhang /* (b) scatter local info to remote processes via VecScatter() */ 224463029d29SHong Zhang ierr = VecScatterCreateToAll(Vleaves,&ctx,&Vleaves_seq);CHKERRQ(ierr); 224563029d29SHong Zhang ierr = VecScatterBegin(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 224663029d29SHong Zhang ierr = VecScatterEnd(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 224763029d29SHong Zhang 224863029d29SHong Zhang /* (c) convert local indices to global indices in parallel vector Vleaves */ 224963029d29SHong Zhang ierr = VecGetSize(Vleaves_seq,&N);CHKERRQ(ierr); 225063029d29SHong Zhang ierr = VecGetArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 225163029d29SHong Zhang for (i=0; i<N; i+=2) { 22522e4cff2eSHong Zhang remoterank = (PetscMPIInt)PetscRealPart(varr_read[i]); 225363029d29SHong Zhang if (remoterank == rank) { 225463029d29SHong Zhang k = i+1; /* row number */ 22552e4cff2eSHong Zhang lidx = (PetscInt)PetscRealPart(varr_read[i+1]); 225663029d29SHong Zhang val = (PetscScalar)vltog[lidx]; /* global index for non-ghost vertex computed above */ 225763029d29SHong Zhang ierr = VecSetValues(Vleaves,1,&k,&val,INSERT_VALUES);CHKERRQ(ierr); 225863029d29SHong Zhang } 225963029d29SHong Zhang } 226063029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 226163029d29SHong Zhang ierr = VecAssemblyBegin(Vleaves);CHKERRQ(ierr); 226263029d29SHong Zhang ierr = VecAssemblyEnd(Vleaves);CHKERRQ(ierr); 226363029d29SHong Zhang 226463029d29SHong Zhang /* (d) Set vltog for ghost vertices by copying local values of Vleaves */ 226563029d29SHong Zhang ierr = VecGetArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 226663029d29SHong Zhang k = 0; 226763029d29SHong Zhang for (i=0; i<nroots; i++) { 226863029d29SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 226963029d29SHong Zhang if (!ghost) continue; 22702e4cff2eSHong Zhang vltog[i] = (PetscInt)PetscRealPart(varr_read[2*k+1]); k++; 227163029d29SHong Zhang } 227263029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 227363029d29SHong Zhang 227463029d29SHong Zhang ierr = VecDestroy(&Vleaves);CHKERRQ(ierr); 227563029d29SHong Zhang ierr = VecDestroy(&Vleaves_seq);CHKERRQ(ierr); 227663029d29SHong Zhang ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 227722bbedd7SHong Zhang PetscFunctionReturn(0); 227822bbedd7SHong Zhang } 2279